[Rose-commits] r189 - in branches/imperial: . config docs/Rose
docs/Rose/Tutorial projects/BinQ
projects/DistributedMemoryAnalysisCompass
projects/compass/src/compassSupport
projects/compass/src/compass_scripts/compass_template_generator
projects/compass/tools/compass
projects/compass/tools/compass/buildInterpreter
projects/compass/tools/compass/doc
projects/compass/tools/compass/gui projects/runtimeErrorCheck
src/ROSETTA src/ROSETTA/Grammar src/ROSETTA/src
src/backend/asmUnparser src/backend/unparser/CxxCodeGeneration
src/backend/unparser/FortranCodeGeneration
src/backend/unparser/languageIndependenceSupport
src/frontend/BinaryDisassembly src/frontend/CxxFrontend
src/frontend/Disassemblers src/frontend/ExecFormats
src/frontend/OpenFortranParser_SAGE_Connection
src/frontend/SageIII src/frontend/SageIII/astMerge
src/frontend/SageIII/astPostProcessing
src/frontend/SageIII/astVisualization
src/frontend/SageIII/sageInterface src/midend/astDiagnostics
src/midend/astProcessing tests/CompilerOptionsTests
tests/CompilerOptionsTests/testGnuOptions
tests/roseTests/astQueryTests
ckiddo74 at osp5.lbl.gov
ckiddo74 at osp5.lbl.gov
Wed Jan 14 07:08:16 PST 2009
Author: ckiddo74
Date: 2009-01-14 07:08:15 -0800 (Wed, 14 Jan 2009)
New Revision: 189
Added:
branches/imperial/docs/Rose/Tutorial/binaryConstruction.tex
branches/imperial/projects/BinQ/DwarfFileInfo.C
branches/imperial/projects/BinQ/DwarfFileInfo.h
branches/imperial/projects/BinQ/FunctionDiff.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/
branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc
branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h
branches/imperial/projects/compass/tools/compass/doc/usingCompassGui.tex
branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-apple-darwin-4e0991cce7811e46159c1b66bb26a0ce.tar.gz
branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz
branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-x86_64-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz
branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.C
branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.h
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h
Removed:
branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h
branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc
branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C
branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h
branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-apple-darwin-40d96a32f4107da10f3e9700d061aec6.tar.gz
branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-pc-linux-gnu-40d96a32f4107da10f3e9700d061aec6.tar.gz
branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-x86_64-pc-linux-gnu-40d96a32f4107da10f3e9700d061aec6.tar.gz
branches/imperial/src/frontend/SageIII/attach_all_info.C
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C
branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h
Modified:
branches/imperial/README.OSX
branches/imperial/config/EDG.m4
branches/imperial/config/Makefile.for.ROSE.includes.and.libs
branches/imperial/config/ax_boost_base.m4
branches/imperial/configure.in
branches/imperial/docs/Rose/Makefile.am
branches/imperial/docs/Rose/Tutorial/Makefile.am
branches/imperial/docs/Rose/Tutorial/tutorial.tex.in
branches/imperial/docs/Rose/developersAppendix.tex
branches/imperial/docs/Rose/installRose.tex
branches/imperial/projects/BinQ/BinAnalyses.h
branches/imperial/projects/BinQ/BinDataFlowAnalysis.C
branches/imperial/projects/BinQ/BinQAbstract.C
branches/imperial/projects/BinQ/BinQAbstract.h
branches/imperial/projects/BinQ/BinQGui.C
branches/imperial/projects/BinQ/BinQGui.h
branches/imperial/projects/BinQ/BinQMain.C
branches/imperial/projects/BinQ/BinQbatch.C
branches/imperial/projects/BinQ/BinQbatch.h
branches/imperial/projects/BinQ/BinQinteractive.C
branches/imperial/projects/BinQ/BufferOverflow.C
branches/imperial/projects/BinQ/ForbiddenFunctionCall.C
branches/imperial/projects/BinQ/ForbiddenFunctionCall.h
branches/imperial/projects/BinQ/Makefile.am
branches/imperial/projects/DistributedMemoryAnalysisCompass/parallel_compass.C
branches/imperial/projects/compass/src/compassSupport/compass.C
branches/imperial/projects/compass/src/compass_scripts/compass_template_generator/compass.C
branches/imperial/projects/compass/tools/compass/Makefile.am
branches/imperial/projects/compass/tools/compass/doc/Makefile.am
branches/imperial/projects/compass/tools/compass/doc/compass.tex.in
branches/imperial/projects/compass/tools/compass/doc/usingCompass.tex
branches/imperial/projects/compass/tools/compass/gui/compassGui.C
branches/imperial/projects/compass/tools/compass/gui/compassGui.h
branches/imperial/projects/runtimeErrorCheck/Makefile.am
branches/imperial/src/ROSETTA/Grammar/BinaryInstruction.code
branches/imperial/src/ROSETTA/Grammar/Expression.code
branches/imperial/src/ROSETTA/Grammar/Node.code
branches/imperial/src/ROSETTA/Grammar/Statement.code
branches/imperial/src/ROSETTA/Grammar/Support.code
branches/imperial/src/ROSETTA/Grammar/Type.code
branches/imperial/src/ROSETTA/astNodeList
branches/imperial/src/ROSETTA/src/binaryInstruction.C
branches/imperial/src/ROSETTA/src/buildStorageClasses.C
branches/imperial/src/ROSETTA/src/expression.C
branches/imperial/src/ROSETTA/src/statement.C
branches/imperial/src/ROSETTA/src/support.C
branches/imperial/src/backend/asmUnparser/unparseX86Asm.C
branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_expressions.C
branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_statements.C
branches/imperial/src/backend/unparser/FortranCodeGeneration/unparseFortran_statements.C
branches/imperial/src/backend/unparser/languageIndependenceSupport/name_qualification_support.C
branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.C
branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.h
branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnum.h
branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnumPrinter.C
branches/imperial/src/frontend/CxxFrontend/Makefile.am
branches/imperial/src/frontend/CxxFrontend/README
branches/imperial/src/frontend/Disassemblers/x86Disassembler.C
branches/imperial/src/frontend/ExecFormats/ROSE_ExecELF.C
branches/imperial/src/frontend/ExecFormats/ROSE_ExecGeneric.C
branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/FortranParserActionROSE.C
branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/fortran_support.C
branches/imperial/src/frontend/SageIII/Makefile.am
branches/imperial/src/frontend/SageIII/astMerge/collectAssociateNodes.C
branches/imperial/src/frontend/SageIII/astMerge/merge.C
branches/imperial/src/frontend/SageIII/astPostProcessing/astPostProcessing.C
branches/imperial/src/frontend/SageIII/astPostProcessing/resetParentPointers.C
branches/imperial/src/frontend/SageIII/astVisualization/wholeAST.C
branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.C
branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.h
branches/imperial/src/frontend/SageIII/attach_all_info.h
branches/imperial/src/frontend/SageIII/attributeListMap.h
branches/imperial/src/frontend/SageIII/dwarfSupport.C
branches/imperial/src/frontend/SageIII/rose_attributes_list.C
branches/imperial/src/frontend/SageIII/rose_attributes_list.h
branches/imperial/src/frontend/SageIII/sageInterface/abiStuff.h
branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.C
branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.h
branches/imperial/src/frontend/SageIII/sageInterface/sageInterface.C
branches/imperial/src/frontend/SageIII/sageSupport.C
branches/imperial/src/midend/astDiagnostics/AstConsistencyTests.C
branches/imperial/src/midend/astProcessing/AstDOTGeneration.C
branches/imperial/tests/CompilerOptionsTests/Makefile.am
branches/imperial/tests/roseTests/astQueryTests/Makefile.am
Log:
merged to revision 188
Modified: branches/imperial/README.OSX
===================================================================
--- branches/imperial/README.OSX 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/README.OSX 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,6 +1,55 @@
-As of the more recent Subversion versions of ROSE and Mac OS X 10.4 for Intel,
-ROSE runs out of the box on Mac. ROSE is not supported on any non-x86 platform.
+As of the more recent Subversion based versions of ROSE and Mac OS X 10.4 for Intel,
+ROSE runs out of the box on Mac. ROSE is however not supported on any non-x86
+platform (this will change in the future).
+Required (or helpful) external software (as per our own OSX test configuration):
+
+boost_1_35_0.tar.gz:
+ All installations of ROSE (any platform) require boost.
+
+doxygen-1.5.6.src.tar.gz:
+ Doxegen is required to build the documentation which is both distributed with ROSE
+ and make available via the ROSE web site.
+
+ghostscript-8.62.tar.gz:
+ Not clear that this is really required by ROSE.
+
+latex2html-2002-2-1.tar.gz:
+ Likely required by LaTeX (not required by ROSE as far as I know).
+
+texlive2007-live-20070212.iso.zip (LaTeX):
+ Reqired to build the latex documentation (ROSE Manual and ROSE Tutorial).
+
+fontconfig-2.6.0.tar.gz:
+ Not clear that this is really required by ROSE.
+
+graphviz-2.20.1.tar.gz:
+ Required to generate graphs for the LaTex documentation in ROSE.
+
+libtool-2.2.4.tar.bz2:
+ Required to build ROSE (used in ROSE configuration).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+********************************************************************************
The following notes are old, and might give hints about running ROSE on PowerPC:
ROSE is developed on Linux I86 architectures. We have not worked much on portablity
Modified: branches/imperial/config/EDG.m4
===================================================================
--- branches/imperial/config/EDG.m4 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/config/EDG.m4 2009-01-14 15:08:15 UTC (rev 189)
@@ -79,7 +79,7 @@
consistency_checking_define_value=0
AC_ARG_ENABLE(checking,
-[ --disable-checking don't do consistency checking in parser],
+[ --disable-checking don't do EDG specific consistency checking in parser],
[if test $enable_checking = yes; then
# AC_DEFINE([CHECKING],[1],[Internal consistency tests.])
consistency_checking_define_value=0
@@ -88,7 +88,8 @@
consistency_checking_define_value=1
])
-AC_DEFINE_UNQUOTED([CHECKING],[$consistency_checking_define_value],[Internal consistency tests.])
+# DQ (1/6/2009): Made the comment more clear that this is an EDG feature.
+AC_DEFINE_UNQUOTED([CHECKING],[$consistency_checking_define_value],[Internal EDG specific consistency tests.])
AC_ARG_ENABLE(stand-alone,
[ --enable-stand-alone compile standalone edgcpfe],
Modified: branches/imperial/config/Makefile.for.ROSE.includes.and.libs
===================================================================
--- branches/imperial/config/Makefile.for.ROSE.includes.and.libs 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/config/Makefile.for.ROSE.includes.and.libs 2009-01-14 15:08:15 UTC (rev 189)
@@ -45,9 +45,14 @@
ROSE_SIDEEFFECTS_LIBS = -l$(ROSE_SIDEEFFECTS_LIB_NAME)
# Location of boost should be set in configuration (not done yet)
-# BOOST_INCLUDE = -idirafter /home/thuerey1/local/include
+ # Note: -idirafter puts the path last on the compiler command line, this is not what we want.
+ # BOOST_INCLUDE = -idirafter /home/thuerey1/local/include
+ # BOOST_INCLUDE = -idirafter $(BOOST_CPPFLAGS)
+ # BOOST_INCLUDE = -isystem $(ROSE_BOOST_INCLUDE_PATH)
- ROSE_DATABASE_INCLUDE = -I$(top_srcdir)/src/roseExtensions/databaseConnection $(BOOST_INCLUDE)
+ # DQ (12/22/2008): Since I am setting BOOST_INCLUDE above, I don't what this to interfer
+ # ROSE_DATABASE_INCLUDE = -I$(top_srcdir)/src/roseExtensions/databaseConnection $(BOOST_INCLUDE)
+ ROSE_DATABASE_INCLUDE = -I$(top_srcdir)/src/roseExtensions/databaseConnection
ROSE_DATABASE_OBJS = $(top_builddir)/src/roseExtensions/databaseConnection/*.o
ROSE_DATABASE_LIB_NAME = rosedatabase
# ROSE_DATABASE_LIB_FILE = lib$(ROSE_DATABASE_LIB_NAME).so
@@ -59,6 +64,13 @@
MYSQL_DATABASE_INCLUDE = $(MYSQL_CFLAGS)
endif
+# DQ (12/22/2008): Specification of Boost path for use with "-isystem" option (may be GNU
+# specific). We use this option only if the configuration of ROSE has detected a
+# previously installed version of Boost (which we do not want to use).
+# Note that only one of these will be non-empty makefile variables.
+ROSE_BOOST_PREINCLUDE_PATH = @ROSE_BOOST_PREINCLUDE_PATH@
+ROSE_BOOST_NORMAL_INCLUDE_PATH = @ROSE_BOOST_NORMAL_INCLUDE_PATH@
+
# SQLite is a simpler database to use than MySQL
if ROSE_USE_SQLITE_DATABASE
ROSE_SQLITE_DATABASE_INCLUDE = $(SQLITE3_CFLAGS)
@@ -133,7 +145,14 @@
ROSE_PHP_LIBS_WITH_PATH = $(php_path)/lib/libphc.so $(php_path)/lib/libphp5.so $(LIBLTDL)
endif
+# Note use of "-isystem" option in ROSE_BOOST_PREINCLUDE_PATH to have the
+# boost specified on the configure
+# command-line be used instead of the OS version of boost that is sometimes
+# installed with Linux (it is always a version too old to be used with ROSE).
+# This is used only when the ROSE configuration detects a previously installed
+# version of Boost (e.g /usr/include/boost) that we don't want to use.
ROSE_INCLUDES = \
+ $(ROSE_BOOST_PREINCLUDE_PATH) \
-I$(top_srcdir)/src \
-I$(top_builddir)/src/frontend/SageIII \
-I$(top_srcdir)/src/frontend/SageIII \
@@ -209,7 +228,6 @@
-I$(top_srcdir)/src/midend/programTransformation/runtimeTransformation \
-I$(top_srcdir)/src/roseSupport \
-I$(top_srcdir)/src/3rdPartyLibraries/MSTL \
-\
-I$(top_srcdir)/src/3rdPartyLibraries/libharu-2.1.0/include \
-I$(top_builddir)/src/3rdPartyLibraries/libharu-2.1.0/include \
-I$(top_srcdir)/src/3rdPartyLibraries/qrose/Framework \
@@ -223,8 +241,14 @@
$(ROSE_DWARF_INCLUDES) \
$(ROSE_WINE_INCLUDES) \
$(VALGRIND_CFLAGS) \
- $(BOOST_CPPFLAGS) $(SQLITE3_CFLAGS) -DBOOST_REGEX_MATCH_EXTRA
+ $(SQLITE3_CFLAGS) \
+ $(ROSE_BOOST_NORMAL_INCLUDE_PATH) -DBOOST_REGEX_MATCH_EXTRA
+# DQ (12/22/2008): Move Boost directory to front and used "-isystem" option so
+# that a system with a previous (older) installation of boost does not interfer
+# with the use of ROSE (and the version of boost specified using "--with-boost").
+# $(BOOST_CPPFLAGS)
+
# DQ (10/28/2008): I think these should be included, I don't know why they
# were removed (used with Microsoft Windows tests, and Yices tests).
# DQ: Not used currently
Modified: branches/imperial/config/ax_boost_base.m4
===================================================================
--- branches/imperial/config/ax_boost_base.m4 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/config/ax_boost_base.m4 2009-01-14 15:08:15 UTC (rev 189)
@@ -84,16 +84,41 @@
if test "$ac_boost_path" != ""; then
BOOST_LDFLAGS=" -L$ac_boost_path/lib"
BOOST_CPPFLAGS="-I$ac_boost_path/include"
+ ROSE_BOOST_INCLUDE_PATH="$ac_boost_path/include"
else
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
+ ROSE_BOOST_INCLUDE_PATH="$ac_boost_path_tmp/include"
break;
fi
done
fi
+# echo "WANT_BOOST_VERSION = $WANT_BOOST_VERSION"
+# echo "boost_lib_version_req = $boost_lib_version_req"
+# echo "BOOST_LDFLAGS = $BOOST_LDFLAGS"
+# echo "BOOST_CPPFLAGS = $BOOST_CPPFLAGS"
+
+# DQ (1/1/2009): Set the default value based on BOOST_CPPFLAGS
+# Liao (1/12/2009): ac_boost_path_tmp is one of the if's branches.
+# Moved the assignment into the two branches above
+# ROSE_BOOST_INCLUDE_PATH="$ac_boost_path_tmp/include"
+
+ # DQ (1/1/2009): Added testing for previously installed Boost (always older version)
+ # so that we can trigger the use of "-isystem" option (to g++) only when required
+ # (it appears to be a problem for SWIG).
+ # Use this set of paths, and the set including "/home/dquinlan" for testing this macro.
+ # for ac_boost_path_tmp in /usr /usr/local /opt /opt/local /home/dquinlan; do
+ for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
+ if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
+ PREVIOUSLY_INSTALLED_BOOST="$ac_boost_path_tmp/include/boost"
+ # echo "Detected a previously installed version of boost library: PREVIOUSLY_INSTALLED_BOOST = $PREVIOUSLY_INSTALLED_BOOST"
+ break;
+ fi
+ done
+
dnl overwrite ld flags if we have required special directory with
dnl --with-boost-libdir parameter
if test "$ac_boost_lib_path" != ""; then
@@ -125,8 +150,6 @@
])
AC_LANG_POP([C++])
-
-
dnl if we found no boost with system layout we search for boost libraries
dnl built and installed without the --layout=system option or for a staged(not installed) version
if test "x$succeeded" != "xyes"; then
@@ -141,6 +164,8 @@
fi
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
+ # DQ (12/22/2008): Modified macro to save the boost path so that it could be used with "-isystem" option (gcc).
+ ROSE_BOOST_INCLUDE_PATH="$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
done
fi
else
@@ -179,6 +204,9 @@
fi
fi
+ # DQ (12/22/2008): Fixup Boost to not use the system (OS) installation of Boost
+ # BOOST_CPPFLAGS="$BOOST_CPPFLAGS/boost"
+
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
@@ -204,7 +232,9 @@
if test "$succeeded" != "yes" ; then
if test "$_version" = "0" ; then
- AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
+ # This was always a confusing error message so make it more explicit for users.
+ # AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
+ AC_MSG_ERROR([[Boost libraries (version $boost_lib_version_req_shorten or higher) must be specified on the configure line (using the --with-boost=<path> option) and the boost libraries must be in your LD_LIBRARY_PATH.]])
else
AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
fi
@@ -218,4 +248,33 @@
LDFLAGS="$LDFLAGS_SAVED"
fi
+# DQ (12/22/2008): Modified macro to save the boost path so that it could be used with "-isystem"
+# option to include the boost path specified on the configure command ahead of "/usr/local/include"
+# so that we can get the required version of Boost on systems that have it installed by default.
+# echo "Final Test: ROSE_BOOST_INCLUDE_PATH = $ROSE_BOOST_INCLUDE_PATH"
+# AC_SUBST(ROSE_BOOST_INCLUDE_PATH)
+
+# DQ (1/1/2009): This use of "-isystem" is not triggered only when there is
+# a previously installed version of ROSE detected (e.g. in /usr/liclude/boost).
+# Note that use of "-isystem" option with g++ will cause SWIG to fail.
+if test "$PREVIOUSLY_INSTALLED_BOOST" != ""; then
+ # echo "Using the -isystem option of g++ to force the use of the specified version of Boost ahead of a previously installed version of boost on your system at: $PREVIOUSLY_INSTALLED_BOOST"
+ AC_MSG_NOTICE(Using the -isystem option of g++ to force the use of the specified version of Boost ahead of a previously installed version of boost on your system at: $PREVIOUSLY_INSTALLED_BOOST)
+ AC_MSG_WARN([Note that the --with-javaport can NOT be used with the -isystem option])
+ ROSE_BOOST_PREINCLUDE_PATH="-isystem $ROSE_BOOST_INCLUDE_PATH"
+ ROSE_BOOST_NORMAL_INCLUDE_PATH=""
+ AC_MSG_WARN([[Detected previously installed version of boost (please remove older version of Boost before installing ROSE) (continuing but expect Boost to be a problem...)]])
+ # AC_MSG_ERROR([[Detected previously installed version of boost (please remove older version of Boost before installing ROSE) (continuing but expect Boost to be a problem...)]])
+ # Remove this exit (as a test) after detecting what I expect is a problem...
+ # exit 1
+else
+ AC_MSG_NOTICE(No previously installed version of boost detected: using boost include directories with normal -I option)
+ ROSE_BOOST_PREINCLUDE_PATH=""
+ ROSE_BOOST_NORMAL_INCLUDE_PATH="-I$ROSE_BOOST_INCLUDE_PATH"
+fi
+
+AC_SUBST(ROSE_BOOST_PREINCLUDE_PATH)
+AC_SUBST(ROSE_BOOST_NORMAL_INCLUDE_PATH)
+
+
])
Modified: branches/imperial/configure.in
===================================================================
--- branches/imperial/configure.in 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/configure.in 2009-01-14 15:08:15 UTC (rev 189)
@@ -75,9 +75,40 @@
AC_ARG_ENABLE(new-edg-interface, AS_HELP_STRING([--enable-new-edg-interface], [Enable new (experimental) translator from EDG ASTs to Sage ASTs]))
AM_CONDITIONAL(ROSE_USE_NEW_EDG_INTERFACE, [test "x$enable_new_edg_interface" = xyes])
if test "x$enable_new_edg_interface" = "xyes"; then
+ AC_MSG_WARN([Using newest version of interface to translate EDG to ROSE (experimental)!])
AC_DEFINE([ROSE_USE_NEW_EDG_INTERFACE], [], [Whether to use the new interface to EDG])
fi
+# DQ (12/29/2008): the default is new EDG interface is 3.10, this option permits the use
+# of the newer EDG 4.0 interface (which breaks some existing work).
+AC_ARG_ENABLE(edg-version4, AS_HELP_STRING([--enable-edg-version4], [Enable newest EDG version 4 (requires --enable-new-edg-interface option)]))
+AM_CONDITIONAL(ROSE_USE_EDG_VERSION_4, [test "x$enable_edg_version4" = xyes])
+if test "x$enable_edg_version4" = "xyes"; then
+ AC_MSG_WARN([Using newest EDG version 4.x (requires new interface) to translate EDG to ROSE (experimental)!])
+ AC_DEFINE([ROSE_USE_EDG_VERSION_4], [], [Whether to use the new EDG version 4.x])
+fi
+
+# DQ (1/4/2009) Added support for optional GNU language extensions in new EDG/ROSE interface.
+# This value will be substituted into EDG/4.0/src/rose_lang_feat.h in the future (not used at present!)
+AC_ARG_ENABLE(gnu-extensions, AS_HELP_STRING([--enable-gnu-extensions], [Enable internal support in ROSE for GNU language extensions]))
+if test "x$enable_gnu_extensions" = "xyes"; then
+ ROSE_SUPPORT_GNU_EXTENSIONS="TRUE"
+else
+ ROSE_SUPPORT_GNU_EXTENSIONS="FALSE"
+fi
+AC_SUBST(ROSE_SUPPORT_GNU_EXTENSIONS)
+
+# DQ (1/4/2009) Added support for optional Microsoft language extensions in new EDG/ROSE interface.
+# This value will be substituted into EDG/4.0/src/rose_lang_feat.h in the future (not used at present!)
+AC_ARG_ENABLE(microsoft-extensions, AS_HELP_STRING([--enable-microsoft-extensions], [Enable internal support in ROSE for Microsoft language extensions]))
+if test "x$enable_microsoft_extensions" = "xyes"; then
+ ROSE_SUPPORT_MICROSOFT_EXTENSIONS="TRUE"
+else
+ ROSE_SUPPORT_MICROSOFT_EXTENSIONS="FALSE"
+fi
+AC_SUBST(ROSE_SUPPORT_MICROSOFT_EXTENSIONS)
+
+
#AM_CONDITIONAL(ROSE_USE_QROSE,test "$with_qrose" = true)
# Set up for use of bison to build dot2gml tool in directory
@@ -123,6 +154,17 @@
AC_LANG(C++)
AX_BOOST_BASE([1.35.0], [], [echo "Boost 1.35.0 or above is required for ROSE" 1>&2; exit 1])
AC_SUBST(ac_boost_path) dnl Hack using an internal variable from AX_BOOST_BASE -- this path should only be used to set --with-boost in distcheck
+
+# DQ (12/22/2008): Fix boost configure to handle OS with older version of Boost that will
+# not work with ROSE, and use the newer version specified by the user on the configure line.
+echo "In ROSE/configure: ac_boost_path = $ac_boost_path"
+#AC_DEFINE([ROSE_BOOST_PATH],"$ac_boost_path",[Location of Boost specified on configure line.])
+AC_DEFINE_UNQUOTED([ROSE_BOOST_PATH],"$ac_boost_path",[Location (unquoted) of Boost specified on configure line.])
+#AC_DEFINE([ROSE_WAVE_PATH],"$ac_boost_path/wave",[Location of Wave specified on configure line.])
+AC_DEFINE_UNQUOTED([ROSE_WAVE_PATH],"$ac_boost_path/wave",[Location (unquoted) of Wave specified on configure line.])
+
+# exit 1
+
AX_BOOST_THREAD
AX_BOOST_DATE_TIME
AX_BOOST_REGEX
@@ -250,8 +292,6 @@
AC_PROG_YACC
AC_SUBST(YACC)
-
-
# echo "After test for LEX: CC (CC = $CC)"
# DQ (4/1/2001) Need to call this macro to avoid having "MAKE" set to "make" in the
@@ -756,7 +796,7 @@
AM_CONDITIONAL(BINARY_EDG_TARBALL_ENABLED, [test "x$binary_edg_tarball_enabled" = "xyes"])
-release_binary_compatibility_signature="40d96a32f4107da10f3e9700d061aec6" # This variable will be substituted in binary-EDG release copies of configure.in
+release_binary_compatibility_signature="4e0991cce7811e46159c1b66bb26a0ce" # This variable will be substituted in binary-EDG release copies of configure.in
build_triplet_without_redhat=`${srcdir}/config/cleanConfigGuessOutput "$build"`
expected_binary_edg_dirname="roseBinaryEDG-${build_triplet_without_redhat}-${release_binary_compatibility_signature}"
expected_binary_edg_tarball="${expected_binary_edg_dirname}.tar.gz"
@@ -1003,6 +1043,7 @@
projects/compass/tools/compass/Makefile
projects/compass/tools/compass/doc/compass.tex
projects/compass/tools/compass/gui/Makefile
+projects/compass/tools/compass/buildInterpreter/Makefile
projects/compass/tools/compass/doc/Makefile
projects/compass/tools/compass/tests/Makefile
projects/compass/tools/compass/tests/C_tests/Makefile
@@ -1066,6 +1107,7 @@
tests/CompilerOptionsTests/testForSpuriousOutput/Makefile
tests/CompilerOptionsTests/testHeaderFileOutput/Makefile
tests/CompilerOptionsTests/testOutputFileOption/Makefile
+tests/CompilerOptionsTests/testGnuOptions/Makefile
tests/CompilerOptionsTests/testFileNamesAndExtensions/Makefile
tests/CompilerOptionsTests/testFileNamesAndExtensions/fileNames/Makefile
tests/CompilerOptionsTests/testFileNamesAndExtensions/fileExtensions/Makefile
@@ -1170,6 +1212,13 @@
scripts/Makefile
])
+# DQ (12/31/2008): Skip these, since we don't have SPEC and NAS benchmarks setup yet.
+# developersScratchSpace/Dan/Fortran_tests/NPB3.2-SER/Makefile
+# developersScratchSpace/Dan/Fortran_tests/NPB3.2-SER/BT/Makefile
+# developersScratchSpace/Dan/SpecCPU2006/Makefile
+# developersScratchSpace/Dan/SpecCPU2006/config/Makefile
+# developersScratchSpace/Dan/SpecCPU2006/config/rose.cfg
+
# DQ (9/12/2008): Removed older version of QRose (now an external project)
# src/roseIndependentSupport/graphicalUserInterface/Makefile
# src/roseIndependentSupport/graphicalUserInterface/src/Makefile
Modified: branches/imperial/docs/Rose/Makefile.am
===================================================================
--- branches/imperial/docs/Rose/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/docs/Rose/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,8 +1,9 @@
include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs
include $(top_srcdir)/projects/compass/src/compassSupport/compass_dirs.inc
+# When debugging latex documentation skip using the --interaction=batchmode option
PDFLATEX = env TEXINPUTS=$(srcdir):$(top_srcdir)/tests:.: pdflatex --interaction=batchmode
-#PDFLATEX = env TEXINPUTS=$(srcdir):$(top_srcdir)/tests:.: pdflatex
+# PDFLATEX = env TEXINPUTS=$(srcdir):$(top_srcdir)/tests:.: pdflatex
# Later we will add ROSETTA documentation here ...
SUBDIRS = Tutorial
Modified: branches/imperial/docs/Rose/Tutorial/Makefile.am
===================================================================
--- branches/imperial/docs/Rose/Tutorial/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/docs/Rose/Tutorial/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,3 +1,4 @@
+# When debugging latex documentation skip using the --interaction=batchmode option
PDFLATEX = env TEXINPUTS=$(srcdir):$(srcdir)/..:$(top_srcdir)/tests:.: pdflatex --interaction=batchmode
#PDFLATEX = env TEXINPUTS=$(srcdir):$(srcdir)/..:$(top_srcdir)/tests:.: pdflatex
@@ -18,7 +19,7 @@
appendix.tex astFileIO.tex uniqueNames.tex wholeGraphAST.tex addingComments.tex \
partialRedundancyElimination.tex codeGenerationFormatControl.tex copyHelp.tex \
roseHPCT.tex sharedMemoryTraversals.tex distributedMemoryTraversals.tex bugSeeding.tex \
- modifiers.tex howToContribute.tex virtualCFG.tex
+ modifiers.tex howToContribute.tex virtualCFG.tex binaryConstruction.tex
# This is an evolving list, but these are a few of the required files
generatedCodeExamples = \
Copied: branches/imperial/docs/Rose/Tutorial/binaryConstruction.tex (from rev 188, trunk/docs/Rose/Tutorial/binaryConstruction.tex)
===================================================================
--- branches/imperial/docs/Rose/Tutorial/binaryConstruction.tex (rev 0)
+++ branches/imperial/docs/Rose/Tutorial/binaryConstruction.tex 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,416 @@
+\chapter{Binary Construction}
+
+ROSE is normally used in such a way that a file (source code or
+binary) is parsed to construct an AST, then operations are performed
+on the AST, and the modified AST is unparsed to create a new source or
+binary file. However, it is also possible to construct an AST
+explicitly without parsing and then use that AST to generate the
+output. The AST construction interface for binary files was designed
+so that working files could be created simply, while still providing
+methods to control the finer details of the resulting file.
+
+The example in this chapter shows how to construct a statically linked
+ELF executable containing a small ``.text'' section that simply causes
+the process to exit with a specific non-zero value.
+
+\section{Constructors}
+
+The AST node constructors are designed to construct the tree from the
+root down, and thus generally take the parent node as an
+argument. Nodes that refer to other nodes as prerequisites also take
+those prerequisites as arguments. For instance, an ELF Relocation
+Section is a child of the ELF File Header but also needs an ELF Symbol
+Table and therefore takes both objects as constructor arguments.
+
+\section{Read-Only Data Members}
+
+When two or more file formats have a similar notion then that notion
+is represented in a base class. However, part of the information may
+continue to survive in the specialized class. In these situations
+modifications to the specilized data will probably be overridden by
+the generic values from the base class. For instance, all formats
+have a notion of byte order which is represented in the base class
+SgAsmGenericHeader as little- or big-endian (an enumeration
+constant). The ELF specification provides an 8-bit unsigned field to
+store the byte order and therefore has potentially more than two
+possibilities. Any value assigned to the ELF-specific byte order will
+likely be overwritten by the generic byte order before the AST is
+unparsed.
+
+A similar situation arises with section offsets, sizes, memory
+mappings, permissions, etc. The SgAsmGenericSection class represents
+ELF Sections, ELF Segments, PE Objects, and other contiguous regions
+of a file and has methods for obtaining/setting these values. In
+addition, many of the formats have some sort of table that describes
+these sections and which also contains similar information (e.g., the
+ELF Segment Table, a.k.a., the ELF Program Header Table). As above,
+the generic representation of these notions (stored in
+SgAsmGenericSection) override the format-specific values (stored in
+SgAsmElfSegmentEntry).
+
+ROSETTA doesn't make a distinction between data members that can be
+user-modified and data members that should be modified only by the
+parser. Therefore it is up to the user to be aware that certain data
+members will have their values computed or copied from other locations
+in the AST during the unparsing phase.
+
+\section{Constructing the Executable File Container}
+
+All executable files are stored as children of an SgAsmGenericFile
+node. The children are file format headers (SgAsmGenericHeader) such
+as an ELF File Header (SgAsmElfFileHeader). This design allows a
+single executable file to potentially contain more than one executable
+and is used by formats like Windows-PE where the file contains a DOS
+File Header as well as a PE File Header.
+
+For the purposes of this example the SgAsmGenericFile node will serve
+as the root of the AST and therefore we do not need to specify a
+parent in the constructor argument list.
+
+\begin{verbatim}
+SgAsmGenericFile *ef = new SgAsmGenericFile;
+\end{verbatim}
+
+\section{Constructing the ELF File Header}
+
+The ELF File Header is the first thing in the file, always at offset
+zero. File headers are always children of an SgAsmGenericFile which is
+specified as the constructor argument.
+
+The section constructors (a file header is a kind of section) always
+create the new section so it begins at the current end-of-file and
+contains at least one byte. This ensures that each section has a
+unique starting address, which will be important when file memory is
+actually allocated and sections need to be moved around--the allocator
+needs to know the relative positions of the sections in order to
+correctly relocate them.
+
+If we were parsing an ELF file we would usually use ROSE's frontend()
+method. However, one can also parse the file by first constructing the
+SgAsmElfFileHeader and then invoking its parse() method, which parses
+the ELF File Header and everything that can be reached from that
+header.
+
+We use the typical 0x400000 as the virtual address of the main LOAD
+segment, which occupies the first part of the file up through the end
+of the ``.text'' section (see below). ELF File Headers don't actually
+store a base address, so instead of assigning one to the
+SgAsmElfFileHeader we'll leave the header's base address at the
+default zero and add base\_va explicitly whenever we need to.
+
+\begin{verbatim}
+SgAsmElfFileHeader *fhdr = new SgAsmElfFileHeader(ef);
+fhdr->get_exec_format()->set_word_size(8); /* default is 32-bit; we want 64-bit */
+fhdr->set_isa(SgAsmExecutableFileFormat::ISA_X8664_Family); /* instruction set architecture; default is ISA_IA32_386 */
+rose_addr_t base_va = 0x400000; /* base virtual address */
+\end{verbatim}
+
+\section{Constructing the ELF Segment Table}
+
+ELF executable files always have an ELF Segment Table (also called the
+ELF Program Header Table), which usually appears immediately after the
+ELF File Header. The ELF Segment Table describes contiguous regions of
+the file that should be memory mapped by the loader. ELF Segments
+don't have names--names are imparted to the segment by virtue of the
+segment also being described by the ELF Section Table, which we'll
+create later.
+
+Being a contiguous region of the file, an ELF Segment Table
+(SgAsmElfSegmentTable) is derived from SgAsmGenericSection. All
+non-header sections have a header as a parent, which we supply as an
+argument to the constructor. Since all ELF Segments will be children of
+the ELF File Header rather than children of the ELF Segment Table, we
+could define the ELF Segment Table at the end rather than here. But
+defining it now is an easy way to get it located in its usuall
+location immediately after the ELF File Header.
+
+\begin{verbatim}
+SgAsmElfSegmentTable *segtab = new SgAsmElfSegmentTable(fhdr);
+\end{verbatim}
+
+\section{Constructing the .text Section}
+
+ROSE doesn't treat a ``.text'' section as being anything particularly
+special--it's just a regular SgAsmElfSection, which derives from
+SgAsmGenericSection. However, in this example, we want to make sure
+that our ``.text'' section gets initialized with some
+instructions. The easiest way to do that is to specialize
+SgAsmElfSection and override or augment a few of the virtual
+functions.
+
+We need to override two functions. First, the calculate\_sizes()
+function should return the size we need to store the
+instructions. We'll treat the instructions as an array of entries each
+entry being one byte of the instruction stream. In other words, each
+``entry'' is one byte in length consisting of one required byte and no
+optional bytes.
+
+We need to also override the unparse() method since the base class
+will just fill the ``.text'' section with zeros. The
+SgAsmGenericSection::write method we use will write the instructions
+starting at the first byte of the section.
+
+Finally, we need to augment the reallocate() method. This method is
+reponsible for allocating space in the file for the section and
+performing any other necessary pre-unparsing actions. We don't need to
+allocate space since the base class's method will take care of that in
+conjuction with our version of calculate\_sizes(), but we do need to
+set a special ELF flag (SHF\_ALLOC) in the ELF Segment Table entry for
+this section. There's a few ways to accomplish this. We do it this way
+because the ELF Section Table Entry is not created until later and we
+want to demonstrate how to keep all .text-related code in close
+proximity.
+
+\begin{verbatim}
+class TextSection : public SgAsmElfSection {
+public:
+ TextSection(SgAsmElfFileHeader *fhdr, size_t ins_size, const unsigned char *ins_bytes)
+ : SgAsmElfSection(fhdr), ins_size(ins_size), ins_bytes(ins_bytes)
+ {}
+ virtual rose_addr_t calculate_sizes(size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const {
+ if (entsize) *entsize = 1; /* an "entry" is one byte of instruction */
+ if (required) *required = 1; /* each "entry" is also stored in one byte of the file */
+ if (optional) *optional = 0; /* there is no extra data per instruction byte */
+ if (entcount) *entcount = ins_size; /* number of "entries" is the total instruction bytes */
+ return ins_size; /* return value is section size required */
+ }
+ virtual bool reallocate() {
+ bool retval = SgAsmElfSection::reallocate(); /* returns true if size or position of any section changed */
+ SgAsmElfSectionTableEntry *ste = get_section_entry();
+ ste->set_sh_flags(ste->get_sh_flags() | 0x02); /* set the SHF_ALLOC bit */
+ return retval;
+ }
+ virtual void unparse(std::ostream &f) const {
+ write(f, 0, ins_size, ins_bytes); /* Write the instructions at offset zero in section */
+ }
+ size_t ins_size;
+ const unsigned char *ins_bytes;
+};
+\end{verbatim}
+
+The section constructors and reallocators don't worry about alignment
+issues--they always allocate from the next available byte. However,
+instructions typically need to satisfy some alignment constraints. We
+can easily adjust the file offset chosen by the constructor, but we
+also need to tell the reallocator about the alignment constraint. Even
+if we didn't ever resize the ``.text'' section the reallocator could
+be called for some other section in such a way that it needs to move
+the ``.text'' section to a new file offset.
+
+For the purpose of this tutorial we want to be very picky about the
+location of the ELF Segment Table. We want it to immediately follow
+the ELF File Header without any intervening bytes of padding. At the
+current time, the ELF File Header has a size of one byte and will
+eventually be reallocated. When we reallocate the header the
+subsequent sections will need to be shifted to higher file
+offsets. When this happens, the allocator shifts them all by the same
+amount taking care to satisfy all alignment constraints, which means
+that an alignment constraint of byte bytes on the ``.text'' section
+will induce a similar alignment on the ELF Segment Table. Since we
+don't want that, the best practice is to call reallocate() now, before
+we create the ``.text'' section.
+
+\begin{verbatim}
+ef->reallocate(); /* Give existing sections a chance to allocate file space */
+static const unsigned char instructions[] = {0xb8, 0x01, 0x00, 0x00, 0x00, 0xbb, 0x56, 0x00, 0x00, 0x00, 0xcd, 0x80};
+SgAsmElfSection *text = new TextSection(fhdr, NELMTS(instructions), instructions);
+text->set_purpose(SgAsmGenericSection::SP_PROGRAM); /* Program-supplied text/data/etc. */
+text->set_offset(ALIGN_UP(text->get_offset(), 4)); /* Align on an 8-byte boundary */
+text->set_file_alignment(4); /* Tell reallocator about alignment constraint */
+text->set_mapped_alignment(4); /* Alignment constraint for memory mapping */
+text->set_mapped_rva(base_va+text->get_offset()); /* Mapped address is based on file offset */
+text->set_mapped_size(text->get_size()); /* Mapped size is same as file size */
+text->set_mapped_rperm(true); /* Readable */
+text->set_mapped_wperm(false); /* Not writable */
+text->set_mapped_xperm(true); /* Executable */
+\end{verbatim}
+
+At this point the text section doesn't have a name. We want to name it
+``.text'' and we want those characters to eventually be stored in the
+ELF file in a string table which we'll provide later. In ELF, section
+names are represented by the section's entry in the ELF Section Table
+as an offset into an ELF String Table for a NUL-terminated ASCII
+string. ROSE manages strings using the SgAsmGenericString class, which
+has two subclasses: one for strings that aren't stored in the
+executable file (SgAsmBasicString) and one for strings that are stored
+in the file (SgAsmStoredString). Both are capable of string an
+std::string value and querying its byte offset (although
+SgAsmBasicString::get\_offset() will always return
+SgAsmGenericString::unallocated). Since we haven't added the
+``.text'' section to the ELF Section Table yet the new section has an
+SgAsmBasicString name. We can assign a string to the name now and the
+string will be allocated in the ELF file when we've provided further
+information.
+
+\begin{verbatim}
+text->get_name()->set_string(".text");
+\end{verbatim}
+
+The ELF File Header needs to know the virtual address at which to
+start running the program. In ROSE, virtual addresses can be attached
+to a specific section so that if the section is ever moved the address
+is automatically updated. Some formats allow more than one entry
+address which is why the method is called add\_entry\_rva() rather than
+set\_entry\_rva(). ELF, however, only allows one entry address.
+
+\begin{verbatim}
+rose_rva_t entry_rva(text->get_mapped_rva(), text);
+fhdr->add_entry_rva(entry_rva);
+\end{verbatim}
+
+\section{Constructing a LOAD Segment}
+
+ELF Segments define parts of an executable file that should be mapped
+into memory by the loader. A program will typically have a LOAD
+segment that begins at the first byte of the file and continues
+through the last instruction (in our case, the end of the ``.text''
+section) and which is mapped to virtual address 0x400000.
+
+We've already created the ELF Segment Table, so all we need to do now
+is create an ELF Segment and add it to the ELF Segment Table. ELF
+Segments, like ELF Sections, are represented by SgAsmElfSection. An
+SgAsmElfSection is an ELF Section if it has an entry in the ELF
+Section Table, and/or it's an ELF Segment if it has an entry in the
+ELF Segment Table. The methods get\_section\_entry() and
+get\_segment\_entry() retrieve the actual entries in those tables.
+
+Recall that the constructor creates new sections located at the
+current end-of-file and containing one byte. Our LOAD segment needs to
+have a different offset and size.
+
+\begin{verbatim}
+SgAsmElfSection *seg1 = new SgAsmElfSection(fhdr); /* ELF Segments are represented by SgAsmElfSection */
+seg1->get_name()->set_string("LOAD"); /* Segment names aren't saved (but useful for debugging) */
+seg1->set_offset(0); /* Starts at beginning of file */
+seg1->set_size(text->get_offset() + text->get_size()); /* Extends to end of .text section */
+seg1->set_mapped_rva(base_va); /* Typically mapped by loader to this memory address */
+seg1->set_mapped_size(seg1->get_size()); /* Make mapped size match size in the file */
+seg1->set_mapped_rperm(true); /* Readable */
+seg1->set_mapped_wperm(false); /* Not writable */
+seg1->set_mapped_xperm(true); /* Executable */
+segtab->add_section(seg1); /* Add definition to ELF Segment Table */
+\end{verbatim}
+
+\section{Constructing a PAX Segment}
+
+This documentation shows how to construct a generic ELF Segment,
+giving it a particular file offset and size. ELF Segments don't have
+names stored in the file, but we can assign a name to the AST node to
+aid in debugging--it just won't be written out. When parsing an ELF
+file, segment names are generated based on the type stored in the
+entry of the ELF Segment Table. For a PAX segment we want this type to
+be PT\_PAX\_FLAGS (the default is PT\_LOAD).
+
+\begin{verbatim}
+SgAsmElfSection *pax = new SgAsmElfSection(fhdr);
+pax->get_name()->set_string("PAX Flags"); /* Name just for debugging */
+pax->set_offset(0); /* Override address to be at zero rather than EOF */
+pax->set_size(0); /* Override size to be zero rather than one byte */
+segtab->add_section(pax); /* Add definition to ELF Segment Table */
+pax->get_segment_entry()->set_type(SgAsmElfSegmentTableEntry::PT_PAX_FLAGS);
+\end{verbatim}
+
+\section{Constructing a String Table}
+
+An ELF String Table always corresponds to a single ELF Section of
+class SgAsmElfStringSection and thus you'll often see the term ``ELF
+String Section'' used interchangeably with ``ELF String Table'' even
+though they're two unique but closely tied classes internally.
+
+When the ELF String Section is created a corresponding ELF String
+Table is also created under the covers. Since string tables manage
+their own memory in reponse to the strings they contain, one should
+never adjust the size of the ELF String Section (it's actually fine to
+enlarge the section and the new space will become free space in the
+string table).
+
+ELF files typically have multiple string tables so that section names
+are in a different section than symbol names, etc. In this tutorial
+we'll create the section names string table, typically called
+``.shstrtab'', but use it for all string storage.
+
+\begin{verbatim}
+SgAsmElfStringSection *shstrtab = new SgAsmElfStringSection(fhdr);
+shstrtab->get_name()->set_string(".shstrtab");
+\end{verbatim}
+
+\section{Constructing an ELF Section Table}
+
+We do this last because we want the ELF Section Table to appear at the
+end of the file and this is the easiest way to achieve that. There's
+really not much one needs to do to create the ELF Section Table other
+than provide the ELF File Header as a parent and supply a string
+table.
+
+The string table we created above isn't activated until we assign it
+to the ELF Section Table. The first SgAsmElfStringSection added to the
+SgAsmElfSectionTable becomes the string table for storing section
+names. It is permissible to add other sections to the table before
+adding the string table.
+
+\begin{verbatim}
+SgAsmElfSectionTable *sectab = new SgAsmElfSectionTable(fhdr);
+sectab->add_section(text); /* Add the .text section */
+sectab->add_section(shstrtab); /* Add the string table to store section names. */
+\end{verbatim}
+
+\section{Allocating Space}
+
+Prior to calling unparse(), we need to make sure that all sections
+have a chance to allocate space for themselves, and perform any other
+operations necessary. It's not always possible to determine sizes at
+an earlier time, and most constructors would have declared sizes of
+only one byte.
+
+The reallocate() method is defined in the SgAsmGenericFile class since
+it operates over the entire collection of sections simultaneously. In
+other words, if a section needs to grow then all the sections located
+after it in the file need to be shifted to higher file offsets.
+
+\begin{verbatim}
+ef->reallocate();
+\end{verbatim}
+
+The reallocate() method has a shortcoming (as of 2008-12-19) in that
+it might not correctly update memory mappings in the case when the
+mapping for a section is inferred from the mapping of a containing
+segment. This can happen in our example since the ``.text'' section's
+memory mapping is a function of the LOAD Segment mapping. The
+work-around is to adjust mappings for these situations and then call
+reallocate() one final time. This final reallocate() call won't move
+any sections, but should always be the last thing to call before
+unparsing() (it gives sections a chance to update data dependencies
+which is not possible during unparse() due to its const nature).
+
+\begin{verbatim}
+text->set_mapped_rva(seg1->get_mapped_rva()+(text->get_offset()-seg1->get_offset()));
+ef->reallocate(); /*won't resize or move things this time since we didn't modify much since the last call to reallocate()*/
+\end{verbatim}
+
+\section{Produce a Debugging Dump}
+
+A debugging dump can be made with the following code. This dump will
+not be identical to the one produced by parsing and dumping the
+resulting file since we never parsed a file (a dump contains some
+information that's parser-specific).
+
+\begin{verbatim}
+ef->dump(stdout);
+SgAsmGenericSectionPtrList all = ef->get_sections(true);
+for (size_t i=0; i<all.size(); i++) {
+ fprintf(stdout, "Section %zu:\n", i);
+ all[i]->dump(stdout, " ", -1);
+}
+\end{verbatim}
+
+\section{Produce the Executable File}
+
+The executable file is produced by unparsing the AST.
+
+\begin{verbatim}
+std::ofstream f("a.out");
+ef->unparse(f);
+\end{verbatim}
+
+Note that the resulting file will not be created with execute
+permission--that must be added manually.
Modified: branches/imperial/docs/Rose/Tutorial/tutorial.tex.in
===================================================================
--- branches/imperial/docs/Rose/Tutorial/tutorial.tex.in 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/docs/Rose/Tutorial/tutorial.tex.in 2009-01-14 15:08:15 UTC (rev 189)
@@ -370,6 +370,8 @@
\input{abstractHandle}
+\input{binaryConstruction}
+
\input{howToContribute}
\backmatter
Modified: branches/imperial/docs/Rose/developersAppendix.tex
===================================================================
--- branches/imperial/docs/Rose/developersAppendix.tex 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/docs/Rose/developersAppendix.tex 2009-01-14 15:08:15 UTC (rev 189)
@@ -827,7 +827,14 @@
More information can be found at: \\
www.ipnom.com/Legato-NetWorker-Commands/nsr.5.html
+or \\
+ https://computation-int.llnl.gov/casc/computing/tutorials/toolsmith/backups.htm
+Example used in ROSE: \\
+{\bf +skip: *.C *.h *.f *.F *.o *.a *.la *.lo *.so *.so.* Makefile rose\_test* *.dot}
+
+Note: There does not appear to be a way of avoiding the backup on executables.
+
Thanks for saving a number of people a lot of work.
Modified: branches/imperial/docs/Rose/installRose.tex
===================================================================
--- branches/imperial/docs/Rose/installRose.tex 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/docs/Rose/installRose.tex 2009-01-14 15:08:15 UTC (rev 189)
@@ -15,9 +15,13 @@
portability issues for their C++ frontend and it is available on nearly all
platforms (see {\tt www.EDG.com} for details). ROSE is currently developed on
Linux/Intel platforms and works with all modern versions of the GNU compilers
-(3.4.x, and later). ROSE also works on both 32-bit and 64-bit architectures, as well as
-with the Intel C and C++ compiler.
+(3.4.x, and later). ROSE also works on both 32-bit and 64-bit architectures,
+as well as with the Intel C and C++ compilers. Recent work has ported ROSE
+to both Mac OSX and Cygwin (under Microsoft Windows).
+
Future work will focus on portability to other platforms important to users.
+If you have a specific requirement for ROSE to be ported to a target platform
+please let us know.
% At a later point we will address portability of ROSE onto other platforms:
% mostly likely IBM AIX will be next (at some point).
@@ -47,67 +51,103 @@
and limitations on how their software may be used.
}
-{\bf Use of Required Software:} \\
+{\bf Required Software:} \\
The following software is required in order to build and use ROSE:
\begin{itemize}
- \item {\bf ROSE} : \\
- There are three versions of ROSE supported: the
- {\it Distribution Version} for users (typical), the {\it External
- Development Version} for advanced users and collaborators,
- and the {\it Internal Development Version}
- (intended only for ROSE development team). The development versions
- are what are found in the ROSE software
- repositories and have additional software requirements (subversion,
- JDK, autoconf, automake, Doxygen, LaTeX, etc.).
-% The exact requirements are listed in the {\tt ROSE/ChangeLog} (including version numbers for each release of ROSE).
+ \item {\bf ROSE}: \\
+ There are three versions of ROSE supported: the {\it Distribution Version} for users
+ (typical), the {\it External Development Version} for advanced users and collaborators,
+ and the {\it Internal Development Version} (intended only for ROSE development team
+ and external developers with access to our internal SVN repository which includes the
+ EDG source code). The development versions are what are found in the ROSE software
+ repositories and have additional software requirements (subversion, JDK, autoconf,
+ automake, Doxygen, LaTeX, etc.).
+ % The exact requirements are listed in the {\tt ROSE/ChangeLog} (including version numbers for each release of ROSE).
\begin{itemize}
- \item {\bf Distribution Version} \\
- Provided as a tared and compressed file in the form,
- ROSE-\VersionNumber.tar.gz. It can be obtained from
- \htmladdnormallink{outreach.scidac.gov/projects/rose}{https://outreach.scidac.gov/projects/rose/}.
- This is the most typical way that users will
- see and work with ROSE. But it is less up-to-date compared to
- development versions.
+ \item {\bf Distribution Version} \\
+ Provided as a tared and compressed file in the form, ROSE-\VersionNumber.tar.gz.
+ It can be obtained from \htmladdnormallink{outreach.scidac.gov/projects/rose}{https://outreach.scidac.gov/projects/rose/}.
+ This is the most typical way that users will see and work with ROSE. But it is less
+ up-to-date compared to development versions.
\item {\bf External Development Version } \\
- It is available from the SciDAC Outreach Center's subversion
- repository:
+ It is available from the SciDAC Outreach Center's subversion repository:
\htmladdnormallink{outreach.scidac.gov/projects/rose}{https://outreach.scidac.gov/projects/rose/}.
We put a subset (excluding the EDG part essentially) of the internal developer version of
- ROSE into the external repository to enable people to
- have quick access to the most recent new features in ROSE.
- The external repository is synchronized with the internal repository
- once a day in ideal conditions. Several branches also exist to accept
- contributions from external collaborators.
+ ROSE into the external repository to enable people to have quick access to the most
+ recent new features in ROSE. The external repository is synchronized with the
+ internal repository once a day in ideal conditions. Several branches also exist to
+ accept contributions from external collaborators.
- \item {\bf Internal Development Version} \\
+ \item {\bf Internal Development Version} \\
Only available directly from the LLNL's internal Subversion (SVN) repository.
- The details of building this
- version are located in the Appendix of the Manual. %\ref{gettingStarted:DeveloperInstructions}.
- \end{itemize}
-% ROSE is delivered as either a development version (svn) or
-% as a distribution for users. The (typical) user version comes either with EDG source or binary distribution.
+ The details of building this version are located in the Appendix of the Manual. %\ref{gettingStarted:DeveloperInstructions}.
+ \end{itemize}
+ % ROSE is delivered as either a development version (svn) or as a distribution for
+ % users. The (typical) user version comes either with EDG source or binary distribution.
+
\item {\bf g++} : version $>=$ 3.4.x \\
In order to use OpenMP or gFortran g++ $>=$ 4.2.x is required.
+
\item {\bf BOOST} : version $>=$ 1.35.0 \\
Visit \htmladdnormallink{www.boost.org}{http://www.boost.org/}
for more details about BOOST and \htmladdnormallink{www.boost.org/users/download}{http://www.boost.org/users/download/}
for download and installation instructions.
+
\item {\bf JAVA} : version $>$1.5.0\_11 \\
- A SUN Java virtual machine (JVM) is needed. A Java compiler
- (JDK)
- is also required for development versions.
- \item {\bf Autoconf} : version $>=$ 2.59. Needed \emph{ONLY} for
- development versions. \\
+ A SUN Java virtual machine (JVM) is needed. A Java compiler (JDK) is also
+ required for development versions.
+
+ \item {\bf Autoconf} : version $>=$ 2.59. Needed \emph{ONLY} for development versions. \\
Autoconf is an extensible package of M4 macros that produce shell scripts to automatically configure software source code packages.
- \item {\bf Automake} : version $>=$ 1.96. Needed \emph{ONLY} for
- development versions. \\
- Automake is a tool for automatically generating `Makefile.in' files
- compliant with the GNU Coding Standards.
- \item {\bf Libtool}: version $>=$1.5.6. Needed \emph{ONLY} for
- development versions.
+
+ \item {\bf Automake} : version $>=$ 1.96. Needed \emph{ONLY} for development versions. \\
+ Automake is a tool for automatically generating `Makefile.in' files compliant with
+ the GNU Coding Standards.
+
+ \item {\bf Libtool}: version $>=$1.5.6. Needed \emph{ONLY} for development versions.
\end{itemize}
+Note that on Mac OSX (version 10.5.6), all of our testing of ROSE uses the following packages:
+\begin{itemize}
+ \item {\bf boost\_1\_35\_0.tar.gz}:
+ All installations of ROSE (any platform) require boost.
+
+ \item {\bf doxygen-1.5.6.src.tar.gz}:
+ Doxegen is required to build the documentation which is both distributed with ROSE
+ and make available via the ROSE web site.
+
+ \item {\bf ghostscript-8.62.tar.gz}:
+ Not clear that this is really required by ROSE.
+
+ \item {\bf latex2html-2002-2-1.tar.gz}:
+ Likely required by LaTeX (not required by ROSE as far as I know).
+
+ \item {\bf texlive2007-live-20070212.iso.zip (LaTeX)}:
+ Reqired to build the latex documentation (ROSE Manual and ROSE Tutorial).
+
+ \item {\bf fontconfig-2.6.0.tar.gz}:
+ Not clear that this is really required by ROSE.
+
+ \item {\bf graphviz-2.20.1.tar.gz}:
+ Required to generate graphs for the LaTex documentation in ROSE.
+
+ \item {\bf libtool-2.2.4.tar.bz2}:
+ Required to build ROSE (used in ROSE configuration).
+\end{itemize}
+
+The .bashrc file for Mac OSX is:
+\begin{verbatim}
+export DYLD_LIBRARY_PATH="/Users/dquinlan/local/boost_1_35_0_installTree-gxx-4.0.1/lib"
+export PATH="/Users/dquinlan/local/doxygen-install/bin:$PATH"
+export PATH="/Users/dquinlan/local/graphviz-install/bin:$PATH"
+export PATH="/Users/dquinlan/local/texlive-install/2007/bin/i386-darwin/:$PATH"
+export PATH="/Users/dquinlan/local/latex2html-install/bin/:$PATH"
+export PATH="/Users/dquinlan/local/ghostscript-install/bin/:$PATH"
+export PATH="/Users/dquinlan/local/fontconfig-install/bin/:$PATH"
+\end{verbatim}
+
+
To simplify the descriptions of the build process, we define:
\begin{itemize}
\item {\bf Source Tree} \\
@@ -390,6 +430,21 @@
configure: error: Unable to find path to JVM library
\end{verbatim}
+ \item Previously installed version of Boost library. \\
+ Some machines have a default version of Boost already installed (for example in
+{\tt /usr/include/boost}). This always the wrong version since the OS installation
+of Boost lags by several years. ROSE now attempts to detect this and use the
+\quote{-isystem} g++ option to have the explicitly specified version of boost from
+the configure command-line be search before the system include directories. This works
+well where a machine has a previously installed version of Boost, but it will fail when
+used with SWIG (so don't use {\tt --with-javaport} where a previous system installation
+of Boost is detected). The ROSE configure scripts will detect the presence of a
+previously installed version of Boost and issue a warning message to not use
+{\tt --with-javaport}. Also if no previously installed version of Boost is detected
+the configuration will report this as well and make clear that it will use the Boost
+include directory with a {\tt -I} option.
+
+
\end{enumerate}
Modified: branches/imperial/projects/BinQ/BinAnalyses.h
===================================================================
--- branches/imperial/projects/BinQ/BinAnalyses.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinAnalyses.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -7,8 +7,9 @@
class BinAnalyses {
public:
-
- BinAnalyses(){};
+ static RoseBin_DataFlowAnalysis* dfanalysis;
+ static RoseBin_Graph* graph;
+ BinAnalyses(){dfanalysis=NULL; graph=NULL;};
virtual ~BinAnalyses(){};
virtual void run(SgNode* f1, SgNode* f2)=0;
virtual void test(SgNode* fileA, SgNode* fileB)=0;
Modified: branches/imperial/projects/BinQ/BinDataFlowAnalysis.C
===================================================================
--- branches/imperial/projects/BinQ/BinDataFlowAnalysis.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinDataFlowAnalysis.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -13,6 +13,9 @@
using namespace std;
using namespace __gnu_cxx;
+RoseBin_DataFlowAnalysis* BinAnalyses::dfanalysis=NULL;
+RoseBin_Graph* BinAnalyses::graph=NULL;
+
std::string BinDataFlowAnalysis::name() {
return "Data Flow Graph";
}
@@ -32,7 +35,7 @@
return;
}
- RoseBin_Graph* graph=NULL;
+ graph=NULL;
ROSE_ASSERT(isSgProject(fileA));
SgBinaryFile* binaryFile = isSgBinaryFile(isSgProject(fileA)->get_fileList()[0]);
SgAsmFile* file = binaryFile != NULL ? binaryFile->get_binaryFile() : NULL;
@@ -60,7 +63,7 @@
}
SgAsmInterpretation* interp = SageInterface::getMainInterpretation(file);
- RoseBin_DataFlowAnalysis* dfanalysis =
+ dfanalysis =
new RoseBin_DataFlowAnalysis(interp->get_global_block(), forward, new RoseObj(), info);
ROSE_ASSERT(dfanalysis);
dfanalysis->init(interprocedural, edges);
@@ -79,7 +82,7 @@
BinDataFlowAnalysis::test(SgNode* fileA, SgNode* fileB) {
- RoseBin_Graph* graph=NULL;
+ graph=NULL;
ROSE_ASSERT(isSgProject(fileA));
SgBinaryFile* binaryFile = isSgBinaryFile(isSgProject(fileA)->get_fileList()[0]);
SgAsmFile* file = binaryFile != NULL ? binaryFile->get_binaryFile() : NULL;
@@ -102,7 +105,7 @@
}
SgAsmInterpretation* interp = SageInterface::getMainInterpretation(file);
- RoseBin_DataFlowAnalysis* dfanalysis =
+ dfanalysis =
new RoseBin_DataFlowAnalysis(interp->get_global_block(), forward, new RoseObj(), info);
ROSE_ASSERT(dfanalysis);
dfanalysis->init(interprocedural, edges);
Modified: branches/imperial/projects/BinQ/BinQAbstract.C
===================================================================
--- branches/imperial/projects/BinQ/BinQAbstract.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQAbstract.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -63,20 +63,6 @@
// generateDOTforMultipleFile ( *isSgProject(fileA) );
// ------------------------------------------------------------
- // this part writes the file out to an assembly file -----------------------------------
- SgBinaryFile* binaryFileA = isSgBinaryFile(isSgProject(fileA)->get_fileList()[0]);
- SgAsmFile* file1 = binaryFileA != NULL ? binaryFileA->get_binaryFile() : NULL;
- SgAsmInterpretation* interpA = SageInterface::getMainInterpretation(file1);
-
- unparseAsmStatementToFile("unparsedA.s", interpA->get_global_block());
-
- if (fileNameB!="")
- if(is_directory( fileNameB ) == false && sourceFile==false) {
- SgBinaryFile* binaryFileB = isSgBinaryFile(isSgProject(fileB)->get_fileList()[0]);
- SgAsmFile* file2 = binaryFileB != NULL ? binaryFileB->get_binaryFile() : NULL;
- SgAsmInterpretation* interpB = SageInterface::getMainInterpretation(file2);
- unparseAsmStatementToFile("unparsedB.s", interpB->get_global_block());
- }
// -------------------------------------------------------------------------------------
if (fileA)
itemsFileA.clear();
Modified: branches/imperial/projects/BinQ/BinQAbstract.h
===================================================================
--- branches/imperial/projects/BinQ/BinQAbstract.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQAbstract.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -22,6 +22,7 @@
#include "MallocAndFree.h"
#include "InitPointerToNull.h"
#include "ComplexityMetric.h"
+#include "DwarfFileInfo.h"
//class Slide;
class BinQSupport;
@@ -30,6 +31,7 @@
class BinQAbstract //: public QWidget
{
public:
+
BinQAbstract() {};
virtual ~BinQAbstract(){};
@@ -54,12 +56,14 @@
int screenWidth;
+
std::vector<BinAnalyses*> analyses;
+ std::vector<BinAnalyses*> preanalyses;
BinAnalyses* currentAnalysis;
// filenames for both files
std::string fileNameA,fileNameB;
-
+ bool sourceFile;
protected:
// used for testing
bool test;
@@ -71,7 +75,7 @@
BinQSupport* binqsupport;
void init();
- bool sourceFile;
+
int screenHeight;
std::vector<std::string> dllA;
std::vector<std::string> dllB;
Modified: branches/imperial/projects/BinQ/BinQGui.C
===================================================================
--- branches/imperial/projects/BinQ/BinQGui.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQGui.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -739,27 +739,31 @@
// This is for testing purposes only
void
-BinQGUI::testAnalyses() {
+BinQGUI::testAnalyses(std::vector<BinAnalyses*>& analysesVec) {
+ int problems=0;
double startTotal = RoseBin_support::getTime();
- for (unsigned int i=0;i<analyses.size();++i) {
- cerr << " testing analysis : " << analyses[i]->getDescription() << endl;
- bool twoFiles = analyses[i]->twoFiles();
+ for (unsigned int i=0;i<analysesVec.size();++i) {
+ cerr << " testing analysis : " << analysesVec[i]->getDescription() << endl;
+ bool twoFiles = analysesVec[i]->twoFiles();
if (twoFiles && fileB!=NULL || twoFiles==false) {
- currentAnalysis=analyses[i];
+ currentAnalysis=analysesVec[i];
if (currentAnalysis) {
double start = RoseBin_support::getTime();
currentAnalysis->test(fileA,fileB);
double end = RoseBin_support::getTime();
double time = (double) (end - start);
+ map<SgNode*,string> resu = currentAnalysis->getResult();
+ problems+=resu.size();
cerr << "Running analysis : " << currentAnalysis->name() <<
- " time : " << time << endl;
+ " time : " << time << " Problems : " << RoseBin_support::ToString(resu.size()) << endl;
+
}
}
}
double endTotal = RoseBin_support::getTime();
double timeTotal = (double) (endTotal - startTotal);
- cerr << "\nTotal time : " << timeTotal << endl;
+ cerr << "\nTotal time : " << timeTotal << " problems : " << problems << endl;
}
// this is the implementation of the run function in the GUI
Modified: branches/imperial/projects/BinQ/BinQGui.h
===================================================================
--- branches/imperial/projects/BinQ/BinQGui.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQGui.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -92,7 +92,7 @@
void insertFileInformation();
protected:
// used for testing
- void testAnalyses();
+ void testAnalyses(std::vector<BinAnalyses*>& analysesVec);
// support functions
void showFileTab();
void createGUI();
Modified: branches/imperial/projects/BinQ/BinQMain.C
===================================================================
--- branches/imperial/projects/BinQ/BinQMain.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQMain.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -10,12 +10,32 @@
#include "BinQinteractive.h"
#include <boost/program_options.hpp>
#include <iostream>
+#include "boost/filesystem/operations.hpp" // includes boost/filesystem/path.hpp
+
using namespace qrs;
using namespace boost::program_options;
using namespace boost;
using namespace std;
+using namespace boost::filesystem;
+void printAssembly(string fileNameA, string fileNameB, SgNode* fileA, SgNode* fileB,
+ bool sourceFile) {
+ // this part writes the file out to an assembly file -----------------------------------
+ SgBinaryFile* binaryFileA = isSgBinaryFile(isSgProject(fileA)->get_fileList()[0]);
+ SgAsmFile* file1 = binaryFileA != NULL ? binaryFileA->get_binaryFile() : NULL;
+ SgAsmInterpretation* interpA = SageInterface::getMainInterpretation(file1);
+
+ unparseAsmStatementToFile(fileNameA+".dump2", interpA->get_global_block());
+
+ if (fileNameB!="")
+ if(is_directory( fileNameB ) == false && sourceFile==false) {
+ SgBinaryFile* binaryFileB = isSgBinaryFile(isSgProject(fileB)->get_fileList()[0]);
+ SgAsmFile* file2 = binaryFileB != NULL ? binaryFileB->get_binaryFile() : NULL;
+ SgAsmInterpretation* interpB = SageInterface::getMainInterpretation(file2);
+ unparseAsmStatementToFile(fileNameB+".dump2", interpB->get_global_block());
+ }
+}
int main( int argc, char **argv )
@@ -99,19 +119,24 @@
if (test && !batch) {
BinQinteractive binGui(fileA,fileB,dllA,dllB,test);
+ printAssembly(fileA,fileB, binGui.fileA, binGui.fileB, binGui.sourceFile);
} else if (!test && !batch) {
QROSE::init(argc,argv);
BinQinteractive binGui(fileA,fileB,dllA,dllB,test);
+ printAssembly(fileA,fileB, binGui.fileA, binGui.fileB, binGui.sourceFile);
//binGui.run();
return QROSE::exec();
} else if (batch && !test) {
QROSE::init(argc,argv);
BinQbatch binGui(fileA,fileB,dllA,dllB,test);
- //binGui.run();
- binGui.runAnalyses();
+ binGui.runAnalyses(binGui.preanalyses,true);
+ binGui.runAnalyses(binGui.analyses,false);
+ printAssembly(fileA,fileB, binGui.fileA, binGui.fileB, binGui.sourceFile);
+
return QROSE::exec();
} else {
BinQbatch binGui(fileA,fileB,dllA,dllB,test);
+ printAssembly(fileA,fileB, binGui.fileA, binGui.fileB, binGui.sourceFile);
}
return 0;
}
Modified: branches/imperial/projects/BinQ/BinQbatch.C
===================================================================
--- branches/imperial/projects/BinQ/BinQbatch.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQbatch.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -42,15 +42,19 @@
if (test==false)
createGUI();
cerr << "Initialization done." <<endl;
- if (test)
- testAnalyses();
+ if (test) {
+ testAnalyses(preanalyses);
+ testAnalyses(analyses);
+ }
}
void BinQbatch::initAnalyses() {
cerr << "Checking for analyses ... " << endl;
analyses.clear();
- analyses.push_back(new BinCallGraph());
- analyses.push_back(new DynamicInfo());
+ preanalyses.clear();
+ preanalyses.push_back(new DynamicInfo());
+ preanalyses.push_back(new BinDataFlowAnalysis());
+
analyses.push_back(new ForbiddenFunctionCall());
analyses.push_back(new MallocAndFree());
analyses.push_back(new NullAfterFree());
@@ -62,39 +66,45 @@
int BinQbatch::addRemainingAnalyses() {
int before = analyses.size();
+ std::vector<BinAnalyses*>::const_iterator it =preanalyses.begin();
+ for (;it!=preanalyses.end();++it) {
+ analyses.push_back(*it);
+ }
+
+ analyses.push_back(new DwarfFileInfo());
+ analyses.push_back(new BinCallGraph());
analyses.push_back(new DiffAlgo());
analyses.push_back(new FunctionDiffAlgo());
analyses.push_back(new AlignFunction());
analyses.push_back(new BinControlFlowAnalysis());
- analyses.push_back(new BinDataFlowAnalysis());
analyses.push_back(new InterruptAnalysis());
return before;
}
// This is for testing purposes only
void
-BinQbatch::runAnalyses() {
+BinQbatch::runAnalyses( std::vector<BinAnalyses*>& analysesVec, bool init) {
string fileName = "analysisResult.txt";
double startTotal = RoseBin_support::getTime();
std::ofstream myfile;
myfile.open(fileName.c_str());
int problems=0;
- for (unsigned int i=0;i<analyses.size();++i) {
- bool twoFiles = analyses[i]->twoFiles();
+ for (unsigned int i=0;i<analysesVec.size();++i) {
+ bool twoFiles = analysesVec[i]->twoFiles();
if (twoFiles && fileB!=NULL || twoFiles==false) {
- currentAnalysis=analyses[i];
+ currentAnalysis=analysesVec[i];
if (currentAnalysis) {
- cerr << "Running analysis : " << analyses[i]->name().c_str() << endl;
+ cerr << "Running analysis : " << analysesVec[i]->name().c_str() << endl;
double start = RoseBin_support::getTime();
currentAnalysis->test(fileA,fileB);
double end = RoseBin_support::getTime();
double time = (double) (end - start);
map<SgNode*,string> resu = currentAnalysis->getResult();
problems+=resu.size();
- myfile << "Running analysis : " << analyses[i]->name().c_str() <<
+ myfile << "Running analysis : " << analysesVec[i]->name().c_str() <<
" time : " << time << " Problems : " << RoseBin_support::ToString(resu.size()) << endl;
- cerr << "Running analysis : " << analyses[i]->name().c_str() <<
+ cerr << "Running analysis : " << analysesVec[i]->name().c_str() <<
" time : " << time << " Problems : " << RoseBin_support::ToString(resu.size()) << endl;
QString res = QString("Running ... %1 time : %2 Problems: %3")
.arg(currentAnalysis->name().c_str())
@@ -106,6 +116,7 @@
string str = " "+it->second;
analysisResult->append(QString(str.c_str()));
myfile << " " << str << endl;
+ std::cout << str << endl;
}
analysisTab->setCurrentIndex(1);
analysisResult->moveCursor(QTextCursor::Start);
@@ -115,21 +126,24 @@
double endTotal = RoseBin_support::getTime();
double timeTotal = (double) (endTotal - startTotal);
- myfile << "\nTotal time : " << timeTotal << " total problems: " << problems << endl;
+ myfile << "\nTotal time : " << timeTotal << " total problems: " << RoseBin_support::ToString(problems) << endl;
myfile.close();
QString res = QString("Total time ... %1 Total problems %2")
.arg(timeTotal)
- .arg(problems);
+ .arg( RoseBin_support::ToString(problems).c_str());
analysisResult->append(res);
-
- int start = addRemainingAnalyses();
- for (unsigned int i=start; i < analyses.size(); ++i){
- new QListWidgetItem((analyses[i]->name().c_str()), listWidget);
+ if (init) {}
+ else {
+ int start = addRemainingAnalyses();
+
+ for (unsigned int i=start; i < analysesVec.size(); ++i){
+ new QListWidgetItem((analysesVec[i]->name().c_str()), listWidget);
+ }
+
+ updateByteItemList();
}
-
- updateByteItemList();
}
Modified: branches/imperial/projects/BinQ/BinQbatch.h
===================================================================
--- branches/imperial/projects/BinQ/BinQbatch.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQbatch.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -11,7 +11,7 @@
std::vector<std::string> dllB, bool test);
~BinQbatch();
- void runAnalyses();
+ void runAnalyses(std::vector<BinAnalyses*>& analysesVec, bool init);
void initAnalyses();
int addRemainingAnalyses();
}; //class BinQGUI
Modified: branches/imperial/projects/BinQ/BinQinteractive.C
===================================================================
--- branches/imperial/projects/BinQ/BinQinteractive.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BinQinteractive.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -44,12 +44,13 @@
}
cerr << "Initialization done." <<endl;
if (test)
- testAnalyses();
+ testAnalyses(analyses);
}
void BinQinteractive::initAnalyses() {
cerr << "Checking for analyses ... " << endl;
analyses.clear();
+ analyses.push_back(new DwarfFileInfo());
analyses.push_back(new DynamicInfo());
analyses.push_back(new ForbiddenFunctionCall());
analyses.push_back(new NullAfterFree());
Modified: branches/imperial/projects/BinQ/BufferOverflow.C
===================================================================
--- branches/imperial/projects/BinQ/BufferOverflow.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/BufferOverflow.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -15,6 +15,7 @@
using namespace __gnu_cxx;
using namespace RoseBin_DataTypes;
+
std::string BufferOverflow::name() {
return "Buffer Overflow Analysis";
}
@@ -230,7 +231,7 @@
return;
}
- RoseBin_Graph* graph=NULL;
+
ROSE_ASSERT(isSgProject(fileA));
SgBinaryFile* binaryFile = isSgBinaryFile(isSgProject(fileA)->get_fileList()[0]);
SgAsmFile* file = binaryFile != NULL ? binaryFile->get_binaryFile() : NULL;
@@ -253,19 +254,27 @@
bool mergedEdges=true;
bool interprocedural=false;
string dfgFileName = "dfg.dot";
- graph= new RoseBin_DotGraph(info);
- if (dot==false) {
- dfgFileName = "dfg.gml";
- graph= new RoseBin_GMLGraph(info);
- }
+ if (graph==NULL) {
+ cerr << "No graph found yet .. creating graph " << endl;
+ graph= new RoseBin_DotGraph(info);
+ if (dot==false) {
+ dfgFileName = "dfg.gml";
+ graph= new RoseBin_GMLGraph(info);
+ }
+ }
SgAsmInterpretation* interp = SageInterface::getMainInterpretation(file);
- RoseBin_DataFlowAnalysis* dfanalysis =
- new RoseBin_DataFlowAnalysis(interp->get_global_block(), forward, new RoseObj(), info);
- ROSE_ASSERT(dfanalysis);
- dfanalysis->writeToFile(false);
- dfanalysis->init(interprocedural, edges);
- dfanalysis->run(graph, dfgFileName, mergedEdges);
+ if (dfanalysis==NULL) {
+ cerr << "No dataflow analysis run yet ... running ... " << endl;
+ dfanalysis =
+ new RoseBin_DataFlowAnalysis(interp->get_global_block(), forward, new RoseObj(), info);
+ ROSE_ASSERT(dfanalysis);
+ dfanalysis->writeToFile(false);
+ dfanalysis->init(interprocedural, edges);
+ dfanalysis->run(graph, dfgFileName, mergedEdges);
+ } else {
+ cerr << "Dataflow analysis run before ... " << endl;
+ }
if (instance) {
res = QString("nr of nodes visited %1. nr of edges visited %2. ")
Copied: branches/imperial/projects/BinQ/DwarfFileInfo.C (from rev 188, trunk/projects/BinQ/DwarfFileInfo.C)
===================================================================
--- branches/imperial/projects/BinQ/DwarfFileInfo.C (rev 0)
+++ branches/imperial/projects/BinQ/DwarfFileInfo.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,101 @@
+#include "BinQGui.h"
+#include "DwarfFileInfo.h"
+
+#include <iostream>
+#include "BinQSupport.h"
+#include "slide.h"
+#include <qtabwidget.h>
+
+
+using namespace qrs;
+using namespace std;
+using namespace __gnu_cxx;
+
+
+std::string DwarfFileInfo::name() {
+ return "Dwarf File Info";
+}
+
+std::string DwarfFileInfo::getDescription() {
+ return "Detects the Files compiled for this binary";
+}
+
+
+
+void
+DwarfFileInfo::run(SgNode* fileA, SgNode* fileB) {
+ instance=NULL;
+ if (!testFlag)
+ instance = QROSE::cbData<BinQGUI *>();
+
+ if (isSgProject(fileA)==NULL) {
+ cerr << "This is not a valid file for this analysis!" << endl;
+ QString res = QString("This is not a valid file for this analysis");
+ instance->analysisResult->append(res);
+ return;
+ }
+
+ SgBinaryFile* binaryFile = isSgBinaryFile(isSgProject(fileA)->get_fileList()[0]);
+ SgAsmFile* file = binaryFile != NULL ? binaryFile->get_binaryFile() : NULL;
+ ROSE_ASSERT(file);
+ info = new VirtualBinCFG::AuxiliaryInformation(file);
+
+ if (!testFlag) {
+ ROSE_ASSERT(instance);
+ ROSE_ASSERT(instance->analysisTab);
+ instance->analysisTab->setCurrentIndex(1);
+ QString res = QString("Start : %1").arg(file->get_name().c_str());
+ instance->analysisResult->append(res);
+ }
+ genericF = file->get_genericFile() ;
+
+#if 0
+ std::set <std::string> files;
+#if USE_ROSE_DWARF_SUPPORT
+ // The input file is the binary file...
+ int binary_file_id = isSgProject(fileA)->get_fileList()[0]->get_file_info()->get_file_id();
+
+ std::string binaryFilename = Sg_File_Info::getFilenameFromID(binary_file_id);
+ printf ("file_id = %d binaryFilename = %s \n",binary_file_id,binaryFilename.c_str());
+ // Compute the binary executable instruction address range
+ std::pair<uint64_t,uint64_t> addressRange = SgAsmDwarfLineList::instructionRange();
+ printf ("\nBinary instruction address range = (0x%lx, 0x%lx) \n",addressRange.first,addressRange.second);
+
+ uint64_t minInstructionAddress = addressRange.first;
+ // Iterate over the addresses of the binary and compute the source code line numbers (limit the range so the output will be short).
+ //printf ("\nSource lines computed from address range (truncated to keep output short): \n");
+ for (uint64_t address = minInstructionAddress - 1; address < addressRange.second; address++)
+ {
+ FileIdLineColumnFilePosition s_map = SgAsmDwarfLineList::addressToSourceCode(address);
+ //printf (" addressToSourceCode: address 0x%lx = (%d,%d,%d) \n",address,s_map.first,s_map.second.first,s_map.second.second);
+ if (s_map.first>=0) {
+ std::string filename = Sg_File_Info::getFilenameFromID(s_map.first);
+ files.insert(filename);
+ }
+ }
+#else
+ printf ("\n\nROSE must be configured with --with-dwarf=<path to libdwarf> to use Dwarf support. \n\n");
+#endif
+
+ set<string>::const_iterator it= files.begin();
+ for (;it!=files.end();++it) {
+ string filename = *it;
+ cerr << " >>> Filename " << filename << endl;
+ }
+ // runTraversal(isSgProject(fileA));
+
+#endif
+ if (instance) {
+ QString res = QString("\n>>>>>>>>>>>>>>>> Resolving call addresses to names ...");
+ instance->analysisResult->append(res);
+ }
+}
+
+
+
+void
+DwarfFileInfo::test(SgNode* fileA, SgNode* fileB) {
+ testFlag=true;
+ run(fileA,fileB);
+ testFlag=false;
+}
Copied: branches/imperial/projects/BinQ/DwarfFileInfo.h (from rev 188, trunk/projects/BinQ/DwarfFileInfo.h)
===================================================================
--- branches/imperial/projects/BinQ/DwarfFileInfo.h (rev 0)
+++ branches/imperial/projects/BinQ/DwarfFileInfo.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,32 @@
+#ifndef DWARFFILEI_R_H
+#define DWARFFILEI_R_H
+#include "rose.h"
+
+#include <iostream>
+#include <list>
+#include "BinAnalyses.h"
+
+class DwarfFileInfo : public BinAnalyses {
+ public:
+ DwarfFileInfo(){testFlag=false; debug=false;};
+ virtual ~DwarfFileInfo(){};
+ bool testFlag;
+ void run(SgNode* f1, SgNode* f2);
+ void test(SgNode* f1, SgNode* f2);
+ std::string name();
+ std::string getDescription();
+ bool twoFiles() {return false;}
+ std::map<SgNode*,std::string> getResult(){return result;}
+
+ private:
+ SgAsmGenericFile *genericF;
+ VirtualBinCFG::AuxiliaryInformation* info;
+ bool debug;
+ BinQGUI *instance;
+ std::map<SgNode*,std::string> result;
+
+};
+
+
+
+#endif
Modified: branches/imperial/projects/BinQ/ForbiddenFunctionCall.C
===================================================================
--- branches/imperial/projects/BinQ/ForbiddenFunctionCall.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/ForbiddenFunctionCall.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -45,9 +45,14 @@
}
}
if (isSgAsmFunctionDeclaration(node)) {
- foundFunction++;
- std::cout << " name ==== " << isSgAsmFunctionDeclaration(node)->get_name() << std::endl;
+ string fname = isSgAsmFunctionDeclaration(node)->get_name();
+ //cerr << " name === " << fname << endl;
+ std::set<std::string>::const_iterator it = foundFunction.find(fname);
+ if (it==foundFunction.end())
+ foundFunction.insert(fname);
}
+ if (isSgAsmInstruction(node))
+ foundInstruction.insert(node);
}
void
@@ -73,6 +78,8 @@
blackList.push_back("unparse");
blackList.push_back("unparseToString");
+ foundFunction.clear();
+ foundInstruction.clear();
this->traverse(project,preorder);
}
@@ -104,18 +111,27 @@
instance->analysisResult->append(res);
}
- foundFunction=0;
genericF = file->get_genericFile() ;
runTraversal(isSgProject(fileA));
+ if (debug) {
+ std::set<std::string>::const_iterator it = foundFunction.begin();
+ for (;it!=foundFunction.end();++it) {
+ string fname = *it;
+ std::cout << " function name ==== " << fname << std::endl;
+ }
+ }
if (instance) {
QString res = QString("\n>>>>>>>>>>>>>>>> Resolving call addresses to names ... total # functions: %1")
- .arg(foundFunction);
+ .arg(RoseBin_support::ToString(foundFunction.size()).c_str());
instance->analysisResult->append(res);
}
- std::cerr << " ForbiddenFunctionCall : Total # functions: " <<
- RoseBin_support::ToString(foundFunction) << std::endl;
+ std::cerr << " ForbiddenFunctionCall : Fobidden Functions : " <<
+ RoseBin_support::ToString(result.size()) << " Total # functions: " <<
+ RoseBin_support::ToString(foundFunction.size())
+ << " # instructions: " <<
+ RoseBin_support::ToString(foundInstruction.size()) << std::endl;
}
Modified: branches/imperial/projects/BinQ/ForbiddenFunctionCall.h
===================================================================
--- branches/imperial/projects/BinQ/ForbiddenFunctionCall.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/ForbiddenFunctionCall.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -27,7 +27,8 @@
BinQGUI *instance;
std::vector<std::string> blackList;
std::map<SgNode*,std::string> result;
- int foundFunction;
+ std::set<std::string> foundFunction;
+ std::set<SgNode*> foundInstruction;
};
Copied: branches/imperial/projects/BinQ/FunctionDiff.h (from rev 188, trunk/projects/BinQ/FunctionDiff.h)
===================================================================
--- branches/imperial/projects/BinQ/FunctionDiff.h (rev 0)
+++ branches/imperial/projects/BinQ/FunctionDiff.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,27 @@
+#ifndef DIFFCLONE_R_H
+#define DIFFCLONE_R_H
+#include "rose.h"
+
+#include <iostream>
+#include <list>
+#include "BinAnalyses.h"
+
+
+class FunctionDiffAlgo : public BinAnalyses {
+ public:
+ FunctionDiffAlgo(){testFlag=false;};
+ virtual ~FunctionDiffAlgo(){};
+ bool testFlag;
+ void run(SgNode* f1, SgNode* f2);
+ void test(SgNode* f1, SgNode* f2);
+ std::string name();
+ std::string getDescription();
+ bool twoFiles() {return true;}
+ std::map<SgNode*,std::string> getResult(){return result;}
+ private:
+ std::map<SgNode*,std::string> result;
+
+};
+
+
+#endif
Modified: branches/imperial/projects/BinQ/Makefile.am
===================================================================
--- branches/imperial/projects/BinQ/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/BinQ/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -31,7 +31,8 @@
NullAfterFree.C \
MallocAndFree.C \
InitPointerToNull.C \
- ComplexityMetric.C
+ ComplexityMetric.C \
+ DwarfFileInfo.C
@@ -89,6 +90,7 @@
icons.h \
Item.h \
Clone.h \
+ FunctionDiff.h \
LCS.h \
BinCallGraph.h \
BinControlFlowAnalysis.h \
@@ -104,5 +106,6 @@
NullAfterFree.h \
MallocAndFree.h \
InitPointerToNull.h \
- ComplexityMetric.h
+ ComplexityMetric.h \
+ DwarfFileInfo.h
Modified: branches/imperial/projects/DistributedMemoryAnalysisCompass/parallel_compass.C
===================================================================
--- branches/imperial/projects/DistributedMemoryAnalysisCompass/parallel_compass.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/DistributedMemoryAnalysisCompass/parallel_compass.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -513,10 +513,11 @@
if (DEBUG_OUTPUT_PC_MORE)
cout << "bounds size = " << bounds.size() << endl;
int i=-1;
- int foundFunction=0;
+ std::set<std::string> foundFunction;
+ std::set<std::string> foundFiles;
gettime(begin_time_defuse);
#if ROSE_GCC_OMP
-#pragma omp parallel for private(i,b_itr) shared(bounds,my_rank,bases,nullderefCounter, foundFunction)
+#pragma omp parallel for private(i,b_itr) shared(bounds,my_rank,bases,nullderefCounter, foundFunction, foundFiles)
#endif
for (i = 0; i<(int)bounds.size();i++) {
if (DEBUG_OUTPUT_PC_MORE)
@@ -526,7 +527,7 @@
if (bounds[i]== my_rank)
for (t_itr = traversals.begin(); t_itr != traversals.end(); ++t_itr, ++b_itr) {
SgNode* mynode = isSgNode(nullderefCounter.nodes[i]);
- if (t_itr==traversals.begin())
+ if (t_itr==traversals.begin()) {
if (isSgFunctionDeclaration(mynode)) {
SgFunctionDeclaration* def = isSgFunctionDeclaration(mynode);
if (def->get_definition())
@@ -535,14 +536,26 @@
Sg_File_Info* fileI = def->get_startOfConstruct();
std::string fileName = fileI->get_filenameString();
if (fileName.find("/usr/include")==string::npos) {
- //std::cerr << " name === " << name << " " << fileName << std::endl;
- std::cout << " name === " << name << std::endl;
- foundFunction++;
+ std::cerr << " fname === " << name << " " << fileName << std::endl;
+ //std::cout << " name === " << name << std::endl;
+ foundFunction.insert(name);
} else {
//std::cerr << " >> non local function: name === " << name << " " << fileName << std::endl;
}
}
}
+ if (isSgFile(mynode)){
+ SgFile* file = isSgFile(mynode);
+ Sg_File_Info* fileI = file->get_file_info();
+ std::string fileName = fileI->get_filenameString();
+ if (fileName.find("/usr/include")==string::npos) {
+ // std::cout << " filename === " << fileName << std::endl;
+ foundFiles.insert(fileName);
+ } else {
+ //std::cerr << " >> non local function: name === " << name << " " << fileName << std::endl;
+ }
+ }
+ }
ROSE_ASSERT(mynode);
gettime(begin_time_checker);
(*t_itr)->visit(mynode);
@@ -554,8 +567,22 @@
}
}
gettime(end_time_defuse);
+
+ set<string>::const_iterator itF = foundFunction.begin();
+ for (;itF!=foundFunction.end();++itF) {
+ string function = *itF;
+ std::cout << " functionname === " << function << std::endl;
+ }
+ itF = foundFiles.begin();
+ for (;itF!=foundFiles.end();++itF) {
+ string function = *itF;
+ std::cout << " filename === " << function << std::endl;
+ }
+
+
std::cerr << " parallel_compass : functions traversed = " <<
- RoseBin_support::ToString(foundFunction) << std::endl;
+ RoseBin_support::ToString(foundFunction.size()) << " " <<
+ " files traversed : " << RoseBin_support::ToString(foundFiles.size()) << std::endl;
calc_time_processor = timeDifference(end_time_defuse, begin_time_defuse);
} else {
Modified: branches/imperial/projects/compass/src/compassSupport/compass.C
===================================================================
--- branches/imperial/projects/compass/src/compassSupport/compass.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/src/compassSupport/compass.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -829,7 +829,7 @@
//con.executenonquery("create table IF NOT EXISTS clusters(row_number INTEGER PRIMARY KEY, cluster INTEGER, function_id INTEGER, index_within_function INTEGER, vectors_row INTEGER, dist INTEGER)")
try {
- con.executenonquery("create table IF NOT EXISTS violations( row_number PRIMARY KEY, checker_name TEXT, error_body TEXT, filename TEXT, line INTEGER, short_description TEXT )");
+ con.executenonquery("create table IF NOT EXISTS violations( row_number INTEGER PRIMARY KEY, checker_name TEXT, error_body TEXT, filename TEXT, line INTEGER, short_description TEXT )");
}
catch(std::exception &ex) {
Modified: branches/imperial/projects/compass/src/compass_scripts/compass_template_generator/compass.C
===================================================================
--- branches/imperial/projects/compass/src/compass_scripts/compass_template_generator/compass.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/src/compass_scripts/compass_template_generator/compass.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -829,7 +829,7 @@
//con.executenonquery("create table IF NOT EXISTS clusters(row_number INTEGER PRIMARY KEY, cluster INTEGER, function_id INTEGER, index_within_function INTEGER, vectors_row INTEGER, dist INTEGER)")
try {
- con.executenonquery("create table IF NOT EXISTS violations( row_number PRIMARY KEY, checker_name TEXT, error_body TEXT, filename TEXT, line INTEGER, short_description TEXT )");
+ con.executenonquery("create table IF NOT EXISTS violations( row_number INTEGER PRIMARY KEY, checker_name TEXT, error_body TEXT, filename TEXT, line INTEGER, short_description TEXT )");
}
catch(std::exception &ex) {
Modified: branches/imperial/projects/compass/tools/compass/Makefile.am
===================================================================
--- branches/imperial/projects/compass/tools/compass/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,6 +1,6 @@
include $(top_srcdir)/projects/compass/src/compassSupport/compass.inc
-SUBDIRS = doc tests gui
+SUBDIRS = doc tests gui buildInterpreter
BUILT_SOURCES = buildCheckers.C checkers.h
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter)
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,51 +0,0 @@
-include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs
-include $(top_srcdir)/projects/compass/src/compassSupport/compass_dirs.inc
-
-if ROSE_USE_SQLITE_DATABASE
-
-$(compass_build_tooldir)/compass/libCompassCheckers.la:
- cd .. && $(MAKE) libCompassCheckers.la
-
-bin_PROGRAMS = buildInterpreter
-
-buildInterpreter_SOURCES = \
- roseQMGen.C \
- stringManipulations.C \
- commandLinePreProcessing.C \
- commandLineProcessing.C \
- qmgen.C
-
-# DQ (1/12/2009): Removed -lrt since it fails on Mac OSX
-# buildInterpreter_LDADD = $(ROSE_LIBS) -lrt
-buildInterpreter_LDADD = $(ROSE_LIBS)
-
-AM_CXXFLAGS = $(ROSE_CPPFLAGS) $(BOOST_CPPFLAGS) -DBOOST_REGEX_MATCH_EXTRA -DRCFILE=\""$(top_builddir)/projects/compass/tools/compass/buildInterpreter/rqmgc"\"
-
-INCLUDES = $(ROSE_INCLUDES) $(BOOST_CPPFLAGS) -I.
-
-buildInterpreter_DEPENDENCIES = ${builddir}/rqmgc
-
-${builddir}/rqmgc:
- cp -f ${srcdir}/rqmgc .
-
-compass_parameters:
- cd .. && $(MAKE) compass_parameters
- cp -f ../compass_parameters .
-
-#test: compass_parameters compassMainGui $(compass_test_dir)/exampleTest_1.C
-# env COMPASS_PARAMETERS=./compass_parameters ./compassMainGui $(compass_test_dir)/exampleTest_1.C
-
-check-local:
- @echo "************************************************************************************"
- @echo "*** ROSE/projects/compass/tools/compass/buildInterpreter: make check rule complete (terminated normally) ***"
- @echo "************************************************************************************"
-
-CLEANFILES = compass_parameters rqmgc
-
-endif
-
-
-# DQ (1/11/2009): Modified this, since it was not checked into SVN and does not appear to be required.
-# EXTRA_DIST = compassChecker.h compassGui.h compassInterface.h compassResult.h compassViolation.h icons.h timer.h disks.xpm
-EXTRA_DIST = commandLinePreProcessing.h commandLineProcessing.h defs.h extern.h qmgen.h stringManipulations.h rqmgc
-
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/Makefile.am)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,51 @@
+include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs
+include $(top_srcdir)/projects/compass/src/compassSupport/compass_dirs.inc
+
+if ROSE_USE_SQLITE_DATABASE
+
+$(compass_build_tooldir)/compass/libCompassCheckers.la:
+ cd .. && $(MAKE) libCompassCheckers.la
+
+bin_PROGRAMS = buildInterpreter
+
+buildInterpreter_SOURCES = \
+ roseQMGen.C \
+ stringManipulations.C \
+ commandLinePreProcessing.C \
+ commandLineProcessing.C \
+ qmgen.C
+
+# DQ (1/12/2009): Removed -lrt since it fails on Mac OSX
+# buildInterpreter_LDADD = $(ROSE_LIBS) -lrt
+buildInterpreter_LDADD = $(ROSE_LIBS)
+
+AM_CXXFLAGS = $(ROSE_CPPFLAGS) $(BOOST_CPPFLAGS) -DBOOST_REGEX_MATCH_EXTRA -DRCFILE=\""$(top_builddir)/projects/compass/tools/compass/buildInterpreter/rqmgc"\"
+
+INCLUDES = $(ROSE_INCLUDES) $(BOOST_CPPFLAGS) -I.
+
+buildInterpreter_DEPENDENCIES = ${builddir}/rqmgc
+
+${builddir}/rqmgc:
+ cp -f ${srcdir}/rqmgc .
+
+compass_parameters:
+ cd .. && $(MAKE) compass_parameters
+ cp -f ../compass_parameters .
+
+#test: compass_parameters compassMainGui $(compass_test_dir)/exampleTest_1.C
+# env COMPASS_PARAMETERS=./compass_parameters ./compassMainGui $(compass_test_dir)/exampleTest_1.C
+
+check-local:
+ @echo "************************************************************************************"
+ @echo "*** ROSE/projects/compass/tools/compass/buildInterpreter: make check rule complete (terminated normally) ***"
+ @echo "************************************************************************************"
+
+CLEANFILES = compass_parameters rqmgc
+
+endif
+
+
+# DQ (1/11/2009): Modified this, since it was not checked into SVN and does not appear to be required.
+# EXTRA_DIST = compassChecker.h compassGui.h compassInterface.h compassResult.h compassViolation.h icons.h timer.h disks.xpm
+EXTRA_DIST = commandLinePreProcessing.h commandLineProcessing.h defs.h extern.h qmgen.h stringManipulations.h rqmgc
+
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,101 +0,0 @@
-/*
- * Author: Gary yuan
- * Date: July 2008
- * File: roseQMGen/src/commandLinePreProcessing.h
- */
-
-#include "commandLinePreProcessing.h"
-
-#include <iostream>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <boost/algorithm/string.hpp>
-
-#include "extern.h"
-#include "commandLineProcessing.h"
-
-using namespace boost::algorithm;
-
-/*
- * Function: commandLinePreprocessor
- * Arguments:
- * const std::string &s -- an original command line argument passed by boost
- * Returns:
- * std::pair< std::string, std::string > -- a pair representing the option
- * classification in boost and the stripped option itself
- * Purpose:
- * This is a special function that is run by boost program_options prior
- * to parsing the command line arguments. Here the user may specify special
- * behavior for arguments that match certain patterns
- */
-std::pair< std::string, std::string >
-commandLinePreprocessor( const std::string &s )
-{
- if( s.find("-Wl") == 0 || s.find("-Wp") == 0 )
- return std::make_pair( "passing_option", s );
-
- if( s.find("-c") != std::string::npos )
- isCompileOnly = true;
-
- if( s.find("-") != 0 )
- {
- if( s.find(".o") != std::string::npos )
- return std::make_pair( "object", s );
-
- if( s.find(".h") != std::string::npos )
- return std::make_pair( "header", s );
-
- if( s.find(".c") != std::string::npos ||
- s.find(".C") != std::string::npos ||
- s.find(".f") != std::string::npos ||
- s.find(".F") != std::string::npos )
- {
- return std::make_pair( "source", s );
- } //if, is source file
-
- if( s.find(".so") != std::string::npos ||
- s.find(".lo") != std::string::npos ||
- s.find(".a") != std::string::npos ||
- s.find(".s") != std::string::npos ||
- s.find(".S") != std::string::npos ||
- s.find(".pp") != std::string::npos ||
- s.find(".gz") != std::string::npos )
- {
- return std::make_pair( "library", s );
- } //if, is positional library
-
- if( s.find(".") == 0 )
- return std::make_pair( "relative_path", s );
- } //if( s.find("-") != 0 ), is not an option
-
- return std::make_pair( std::string(), std::string() );
-} //commandLinePreprocessor( const std::string &s )
-
-/*
- * Function: commandLinePreprocessing
- * Purpose:
- * This function performs tasks on the command line arguments and data
- * structures that are necessary before going onto commandLineProcessing.
- * Currently, this function performs the split of option passing arguments
- * such as -Wl, -Wp, etc. and fills the data structure
- * option_passing_arguments
- */
-void commandLinePreprocessing()
-{
- std::vector< std::string > &original_options = option_passing_arguments.first;
- std::vector< std::vector< std::string > > &split_options = option_passing_arguments.second;
-
- for( std::vector< std::string >::iterator itr = original_options.begin();
- itr != original_options.end(); itr++ )
- {
- split_options.push_back( std::vector< std::string >() );
- split( *split_options.rbegin(), *itr, is_any_of(",") );
- } //for, itr
-
- assert( original_options.size() == split_options.size() );
-
- return;
-} //commandLinePreprocessing()
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,101 @@
+/*
+ * Author: Gary yuan
+ * Date: July 2008
+ * File: roseQMGen/src/commandLinePreProcessing.h
+ */
+
+#include "commandLinePreProcessing.h"
+
+#include <iostream>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <boost/algorithm/string.hpp>
+
+#include "extern.h"
+#include "commandLineProcessing.h"
+
+using namespace boost::algorithm;
+
+/*
+ * Function: commandLinePreprocessor
+ * Arguments:
+ * const std::string &s -- an original command line argument passed by boost
+ * Returns:
+ * std::pair< std::string, std::string > -- a pair representing the option
+ * classification in boost and the stripped option itself
+ * Purpose:
+ * This is a special function that is run by boost program_options prior
+ * to parsing the command line arguments. Here the user may specify special
+ * behavior for arguments that match certain patterns
+ */
+std::pair< std::string, std::string >
+commandLinePreprocessor( const std::string &s )
+{
+ if( s.find("-Wl") == 0 || s.find("-Wp") == 0 )
+ return std::make_pair( "passing_option", s );
+
+ if( s.find("-c") != std::string::npos )
+ isCompileOnly = true;
+
+ if( s.find("-") != 0 )
+ {
+ if( s.find(".o") != std::string::npos )
+ return std::make_pair( "object", s );
+
+ if( s.find(".h") != std::string::npos )
+ return std::make_pair( "header", s );
+
+ if( s.find(".c") != std::string::npos ||
+ s.find(".C") != std::string::npos ||
+ s.find(".f") != std::string::npos ||
+ s.find(".F") != std::string::npos )
+ {
+ return std::make_pair( "source", s );
+ } //if, is source file
+
+ if( s.find(".so") != std::string::npos ||
+ s.find(".lo") != std::string::npos ||
+ s.find(".a") != std::string::npos ||
+ s.find(".s") != std::string::npos ||
+ s.find(".S") != std::string::npos ||
+ s.find(".pp") != std::string::npos ||
+ s.find(".gz") != std::string::npos )
+ {
+ return std::make_pair( "library", s );
+ } //if, is positional library
+
+ if( s.find(".") == 0 )
+ return std::make_pair( "relative_path", s );
+ } //if( s.find("-") != 0 ), is not an option
+
+ return std::make_pair( std::string(), std::string() );
+} //commandLinePreprocessor( const std::string &s )
+
+/*
+ * Function: commandLinePreprocessing
+ * Purpose:
+ * This function performs tasks on the command line arguments and data
+ * structures that are necessary before going onto commandLineProcessing.
+ * Currently, this function performs the split of option passing arguments
+ * such as -Wl, -Wp, etc. and fills the data structure
+ * option_passing_arguments
+ */
+void commandLinePreprocessing()
+{
+ std::vector< std::string > &original_options = option_passing_arguments.first;
+ std::vector< std::vector< std::string > > &split_options = option_passing_arguments.second;
+
+ for( std::vector< std::string >::iterator itr = original_options.begin();
+ itr != original_options.end(); itr++ )
+ {
+ split_options.push_back( std::vector< std::string >() );
+ split( *split_options.rbegin(), *itr, is_any_of(",") );
+ } //for, itr
+
+ assert( original_options.size() == split_options.size() );
+
+ return;
+} //commandLinePreprocessing()
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,10 +0,0 @@
-#ifndef ROSE_QM_GEN_COMMAND_LINE_PREPROCESSING_H
-#define ROSE_QM_GEN_COMMAND_LINE_PREPROCESSING_H
-
-#include <string>
-
-std::pair< std::string, std::string >
-commandLinePreprocessor( const std::string &s );
-void commandLinePreprocessing();
-
-#endif
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLinePreProcessing.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,10 @@
+#ifndef ROSE_QM_GEN_COMMAND_LINE_PREPROCESSING_H
+#define ROSE_QM_GEN_COMMAND_LINE_PREPROCESSING_H
+
+#include <string>
+
+std::pair< std::string, std::string >
+commandLinePreprocessor( const std::string &s );
+void commandLinePreprocessing();
+
+#endif
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,55 +0,0 @@
-/*
- * Author: Gary Yuan
- * Date: July 2008
- * File: roseQMGen/src/commandLineProcessing.C
- */
-
-#include "defs.h"
-#include "extern.h"
-#include "stringManipulations.h"
-#include "commandLineProcessing.h"
-
-//using namespace boost::algorithm;
-
-/*
- * Function: commandLineProcessing
- * Purpose:
- * This function calls subroutines to perform string manipulations on
- * the command line arguments such that they work with regression testing
- * using QMTest. Such manipulations are:
- * 1. escaping quotations, i.e. on -DSOMETHING="lots of white space"
- * 2. inserting quotations, where needed some may be lost from cmd line
- * 3. setting the relative path to the regression root, i.e. replace
- * regression_root with uplevel of the string given by the realpath
- * 4. setting the real relative path, i.e. replacing regression_root with
- * "./" relative path to the current working directory
- *
- * These string manipulation sub routines are called via overloaded wrappers
- */
-void commandLineProcessing()
-{
- escapeQuotations( includes );
- escapeQuotations( libincludes );
- escapeQuotations( defines );
- escapeQuotations( objects );
- escapeQuotations( sources );
- escapeQuotations( unrecognized_arguments );
-
- insertQuotations( defines );
-
- setRelativePathToRegressionRoot( includes );
- setRelativePathToRegressionRoot( libincludes );
- setRelativePathToRegressionRoot( defines );
- setRelativePathToRegressionRoot( option_passing_arguments );
- setRelativePathToRegressionRoot( unrecognized_arguments );
-
- setRealRelativePath( output );
- setRealRelativePath( objects );
-
- setRealRelativePathToRegressionRoot( libraries );
- setRealRelativePathToRegressionRoot( headers );
- setRealRelativePathToRegressionRoot( sources );
- setRealRelativePathToRegressionRoot( relative_paths );
-
- return;
-} //commandLineProcessing()
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,55 @@
+/*
+ * Author: Gary Yuan
+ * Date: July 2008
+ * File: roseQMGen/src/commandLineProcessing.C
+ */
+
+#include "defs.h"
+#include "extern.h"
+#include "stringManipulations.h"
+#include "commandLineProcessing.h"
+
+//using namespace boost::algorithm;
+
+/*
+ * Function: commandLineProcessing
+ * Purpose:
+ * This function calls subroutines to perform string manipulations on
+ * the command line arguments such that they work with regression testing
+ * using QMTest. Such manipulations are:
+ * 1. escaping quotations, i.e. on -DSOMETHING="lots of white space"
+ * 2. inserting quotations, where needed some may be lost from cmd line
+ * 3. setting the relative path to the regression root, i.e. replace
+ * regression_root with uplevel of the string given by the realpath
+ * 4. setting the real relative path, i.e. replacing regression_root with
+ * "./" relative path to the current working directory
+ *
+ * These string manipulation sub routines are called via overloaded wrappers
+ */
+void commandLineProcessing()
+{
+ escapeQuotations( includes );
+ escapeQuotations( libincludes );
+ escapeQuotations( defines );
+ escapeQuotations( objects );
+ escapeQuotations( sources );
+ escapeQuotations( unrecognized_arguments );
+
+ insertQuotations( defines );
+
+ setRelativePathToRegressionRoot( includes );
+ setRelativePathToRegressionRoot( libincludes );
+ setRelativePathToRegressionRoot( defines );
+ setRelativePathToRegressionRoot( option_passing_arguments );
+ setRelativePathToRegressionRoot( unrecognized_arguments );
+
+ setRealRelativePath( output );
+ setRealRelativePath( objects );
+
+ setRealRelativePathToRegressionRoot( libraries );
+ setRealRelativePathToRegressionRoot( headers );
+ setRealRelativePathToRegressionRoot( sources );
+ setRealRelativePathToRegressionRoot( relative_paths );
+
+ return;
+} //commandLineProcessing()
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,6 +0,0 @@
-#ifndef ROSE_QM_GEN_COMMAND_LINE_PROCESSING_H
-#define ROSE_QM_GEN_COMMAND_LINE_PROCESSING_H
-
-void commandLineProcessing();
-
-#endif
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/commandLineProcessing.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,6 @@
+#ifndef ROSE_QM_GEN_COMMAND_LINE_PROCESSING_H
+#define ROSE_QM_GEN_COMMAND_LINE_PROCESSING_H
+
+void commandLineProcessing();
+
+#endif
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/defs.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,26 +0,0 @@
-#ifndef ROSE_QM_GEN_DEFS_H
-#define ROSE_QM_GEN_DEFS_H
-
-#include <vector>
-#include <string>
-
-/*
- * This data structure is used in parsing command line options that pass
- * options to sub-components of a compiler such as gcc, -Wl, -Wp,
- *
- * The intention is to have a pair of vector of string and vector of vector
- * of strings. The first vector of strings holds the original argument used
- * to locate its index in the argv array. The second vector of vector of
- * strings holds the corresponding argument split into many strings using
- * boost string algorithms based on the comma ',' split delimiter.
- *
- * The split allows one to control the string manipulation only on the last
- * string result of the split such that only the passed argument is modified
- * for relative path to regression_root, etc. The completed and modified
- * argument is re-joined to produce the file qmtest argument.
- *
- * This data structure is designed to work with joinOptions()
- */
-typedef std::pair< std::vector< std::string >, std::vector< std::vector< std::string > > > pair_vector_options;
-
-#endif
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/defs.h)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/defs.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,26 @@
+#ifndef ROSE_QM_GEN_DEFS_H
+#define ROSE_QM_GEN_DEFS_H
+
+#include <vector>
+#include <string>
+
+/*
+ * This data structure is used in parsing command line options that pass
+ * options to sub-components of a compiler such as gcc, -Wl, -Wp,
+ *
+ * The intention is to have a pair of vector of string and vector of vector
+ * of strings. The first vector of strings holds the original argument used
+ * to locate its index in the argv array. The second vector of vector of
+ * strings holds the corresponding argument split into many strings using
+ * boost string algorithms based on the comma ',' split delimiter.
+ *
+ * The split allows one to control the string manipulation only on the last
+ * string result of the split such that only the passed argument is modified
+ * for relative path to regression_root, etc. The completed and modified
+ * argument is re-joined to produce the file qmtest argument.
+ *
+ * This data structure is designed to work with joinOptions()
+ */
+typedef std::pair< std::vector< std::string >, std::vector< std::vector< std::string > > > pair_vector_options;
+
+#endif
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/extern.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,47 +0,0 @@
-#ifndef ROSE_QM_GEN_EXTERN_H
-#define ROSE_QM_GEN_EXTERN_H
-
-#include <vector>
-#include <string>
-#include <map>
-
-#include <boost/program_options.hpp>
-
-#include "defs.h"
-
-/*
- * These are global data structures meant to be accessed from any part of this
- * program, please refer to roseQMGen.C for their descriptions.
- */
-
-extern std::vector< std::string > includes;
-extern std::vector< std::string > defines;
-extern std::vector< std::string > libincludes;
-extern std::vector< std::string > objects;
-extern std::vector< std::string > headers;
-extern std::vector< std::string > sources;
-extern std::vector< std::string > libraries;
-extern std::vector< std::string > relative_paths;
-extern std::vector< std::string > unrecognized_arguments;
-extern std::map<int, std::pair<std::string, std::string*> > qmtest_arguments;
-extern pair_vector_options option_passing_arguments;
-extern std::string qmtest_name;
-extern std::string executable;
-extern std::string shell;
-extern std::string output;
-extern std::string regression_root;
-extern std::string uplevel;
-extern std::string test_cc;
-extern std::string test_cxx;
-extern std::string host_cc;
-extern std::string host_cxx;
-extern std::string db_name;
-extern std::string pwd;
-extern std::string dotpwd;
-extern std::string dotdotpwd;
-extern std::string envoptions;
-extern bool isCompileOnly;
-extern boost::program_options::variables_map cmdLineMap;
-extern boost::program_options::variables_map confMap;
-
-#endif
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/extern.h)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/extern.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,47 @@
+#ifndef ROSE_QM_GEN_EXTERN_H
+#define ROSE_QM_GEN_EXTERN_H
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include <boost/program_options.hpp>
+
+#include "defs.h"
+
+/*
+ * These are global data structures meant to be accessed from any part of this
+ * program, please refer to roseQMGen.C for their descriptions.
+ */
+
+extern std::vector< std::string > includes;
+extern std::vector< std::string > defines;
+extern std::vector< std::string > libincludes;
+extern std::vector< std::string > objects;
+extern std::vector< std::string > headers;
+extern std::vector< std::string > sources;
+extern std::vector< std::string > libraries;
+extern std::vector< std::string > relative_paths;
+extern std::vector< std::string > unrecognized_arguments;
+extern std::map<int, std::pair<std::string, std::string*> > qmtest_arguments;
+extern pair_vector_options option_passing_arguments;
+extern std::string qmtest_name;
+extern std::string executable;
+extern std::string shell;
+extern std::string output;
+extern std::string regression_root;
+extern std::string uplevel;
+extern std::string test_cc;
+extern std::string test_cxx;
+extern std::string host_cc;
+extern std::string host_cxx;
+extern std::string db_name;
+extern std::string pwd;
+extern std::string dotpwd;
+extern std::string dotdotpwd;
+extern std::string envoptions;
+extern bool isCompileOnly;
+extern boost::program_options::variables_map cmdLineMap;
+extern boost::program_options::variables_map confMap;
+
+#endif
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/qmgen.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,446 +0,0 @@
-/*
- * Author: Gary Yuan
- * Modified by Andreas Saebjoernsen 1/5/09
- * Date: July 2008
- * File: roseQMGen/src/qmgen.C
- */
-
-#include <fstream>
-#include <iostream>
-#include <algorithm>
-#include <sstream>
-
-#include <ctype.h>
-#include <assert.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <boost/algorithm/string.hpp>
-
-#include "qmgen.h"
-#include "extern.h"
-#include "commandLineProcessing.h"
-#include "stringManipulations.h"
-
-//AS: Header to support sqlite3x
-#include "sqlite3x.h"
-#include <boost/lexical_cast.hpp>
-
-using namespace boost::algorithm;
-
-int output_parameter_position = 0; //1 + the position of the output flag '-o'
-
-/*
- * Function: constructMangledTestName
- * Arguments:
- * Returns: std::string, mangled name of .qmt test file name
- * Purpose: constructs the mangled name for the .qmt test file that is created
- *
- * The mangled name is of the form
- *
- * `date +%d%H%M%S%N`_DIR_OUTPUT.qmt
- *
- * Where:
- * The prefix `date +%d%H%M%S%N` is the creation timestamp of fixed width
- * that ensures lexigraphic order of all .qmt test files which is critically
- * important for the execution order of these files during testing
- *
- * DIR is the present working directory minus the regression_root path of
- * the .qmt test file creation location
- *
- * OUTPUT is the output flag option if given, otherwise it is the name of
- * the executable
- */
-std::string constructMangledTestName()
-{
- std::string dir( pwd );
- replace_first( dir, regression_root, "" );
-
- std::string obj;
-
- if( output != "" ) obj.assign(output);
- else if( !objects.empty() ) obj.assign( *objects.begin() );
- else obj.assign( executable );
-
- if( output == "" && isCompileOnly && !sources.empty() )
- {
- output.assign( *sources.begin() );
- int e = output.find_last_of(".");
- int s = output.find_last_of("/");
- obj.assign( output.substr(s+1, e-s-1) + ".o" );
- output.assign( pwd + output.substr(s, e-s) + ".o" );
-// std::cout << output << std::endl;
-// std::cout << obj << std::endl;
-
- int tail = qmtest_arguments.rbegin()->first;
-
- qmtest_arguments.insert(
- std::make_pair(tail+1, std::make_pair("",new std::string("-o"))) );
-
- qmtest_arguments.insert(
- std::make_pair(tail+2, std::make_pair("",&output)) );
-
- output_parameter_position = tail+2;
- } //if( isCompileOnly && !sources.empty() )
-
- std::string testname;
-
- do
- {
- FILE *fdate = popen( "date +%d%H%M%S%N", "r" );
- char timestamp[256] = "\0";
- fread( timestamp, sizeof(char), 17, fdate );
-
- testname.append( timestamp );
- testname.append( "_" );
-
- testname.append( dir + "_" + obj );
-
- //replace the following illegal QMTest characters in the test name:
- //'.' -> '_' in the object name
- //'/' -> '_'
- //'.' -> '_dot_' in the path name
- //'+' -> '_plus_'
- replace_all( obj, ".", "_" );
- replace_all( testname, "/", "_" );
- replace_all( testname, ".", "_dot_" );
- replace_all( testname, "+", "_plus_" );
-
- //.qmt test file names must be all lower-case
- std::transform(testname.begin(), testname.end(), testname.begin(), tolower);
-
- testname.append( ".qmt" );
- } while( open( testname.c_str(), O_RDONLY ) != -1 && sleep(1) == 0 );
- //do...while, this loop ensures unique generated file names for a single
- //instance of this program. If the file name generated already exists then
- //the program sleeps 1 second and tries again with another time stamp.
-
- return testname;
-} //constructMangledTestName()
-
-/*
- * Function: get_argv_index
- * Arguments:
- * std::string arg -- the original argument to search for in argv
- * char **argv -- the original command line argument strings
- * Returns:
- * integer -- the index where arg is located in argv
- * Purpose:
- * Performs a serial search for the occurence of arg in argv and returns the
- * index of the occurence or -1 if not found
- */
-int get_argv_index( std::string arg, int argc, char **argv )
-{
- int i;
- for( i = 1; i < argc; i++ )
- {
- if( arg == argv[i] && qmtest_arguments.find(i) == qmtest_arguments.end() )
- {
- return i;
- } //if(arg == argv[i] && qmtest_arguments.find(i) == qmtest_arguments.end())
- } //for
-
- return -1;
-} //get_argv_index( std::string arg, int argc, char **argv )
-
-/*
- * Function: initialize_qmtest_arguments_vector
- * Arguments:
- * int argc -- the number of command line arguments taken from
- * initialize_qmtest_arguments
- * char **argv -- the command line argument strings taken from
- * initialize_qmtest_arguments
- * std::string prefix -- the stripped argument prefix taken away by boost
- * program_options, ex. -I, -L, -D, "", etc.
- * std::vector< std::string > &arguments -- the boost parsed command line
- * arguments to insert into qmtest_arguments
- * Purpose:
- * This function takes the boost program_options parsed arguments and
- * inserts them into the primary data structure qmtest_arguments ordered
- * by their index into the argv array.
- */
-void initialize_qmtest_arguments_vector(
- int argc,
- char **argv,
- std::string prefix,
- std::vector< std::string > &arguments
-) {
- for( std::vector<std::string>::iterator itr = arguments.begin();
- itr != arguments.end(); itr++ ) {
- int pos = get_argv_index( (prefix+*itr), argc, argv );
-
- if( pos > 0 )
- {
- qmtest_arguments.insert(
- std::make_pair( pos, std::make_pair(prefix,&(*itr)) ) );
- } //if( pos > 0 ), only if valid index
- } //for
-
- return;
-} //initialize_qmtest_arguments_vector()
-
-/*
- * Function: initialize_qmtest_arguments
- * Arguments:
- * int argc -- the number of command line arguments taken form main
- * char **argv -- the command line argument strings taken from main
- * Purpose:
- * This function fills the qmtest_arguments data structure with the
- * 1. test executable name
- * 2. all the arguments taken from the command line and parsed by boost
- * 3. the output flag argument (if applicable)
- * 4. the pwd include and link search path (if applicable)
- */
-void initialize_qmtest_arguments( int argc, char **argv )
-{
- //set the program name used in test
- if( executable == host_cc )
- {
- qmtest_arguments.insert(
- std::make_pair(1, std::make_pair("",&test_cc)) );
- } //if( executable == host_cc )
- else if( executable == host_cxx )
- {
- qmtest_arguments.insert(
- std::make_pair(1, std::make_pair("",&test_cxx)) );
- } //else if( executable == host_cxx )
- else
- {
- qmtest_arguments.insert(
- std::make_pair(1, std::make_pair("",&executable)) );
- } //else
-
- // Set all program options given on command line
-
- //option_passing_arguments, i.e. -Wl, -Wp, etc.
- {
- std::vector< std::string >
- &original_options = option_passing_arguments.first;
- std::vector< std::vector< std::string > >
- &split_options = option_passing_arguments.second;
-
- assert( original_options.size() == split_options.size() );
-
- int size = original_options.size();
- for( int i = 0; i < size; i++ )
- {
- int pos = get_argv_index(original_options.at(i), argc, argv);
-
- if( pos > 0 )
- {
- std::string option_prefix = joinOptions(
- split_options.at(i).begin(),
- --split_options.at(i).end(), "," );
-
- qmtest_arguments.insert(
- std::make_pair(pos, std::make_pair(option_prefix,
- &(*split_options.at(i).rbegin()))) );
- } //
- } //for i
- } //option_passing_arguments, i.e. -Wl, -Wp, etc.
-
- if( !includes.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "-I", includes);
- if( !libincludes.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "-L", libincludes);
- if( !defines.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "-D", defines);
- if( !objects.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "", objects);
- if( !sources.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "", sources);
- if( !headers.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "", headers);
- if( !libraries.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "", libraries);
- if( !relative_paths.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "", relative_paths);
- if( !unrecognized_arguments.empty() )
- initialize_qmtest_arguments_vector(argc, argv, "", unrecognized_arguments);
-
- // Set the output flag option (if applicable)
-
- if( cmdLineMap.count("output") )
- {
- int pos = get_argv_index("-o", argc, argv);
-
- if( pos > 0 )
- {
- qmtest_arguments.insert(
- std::make_pair(pos, std::make_pair("",new std::string("-o"))) );
- qmtest_arguments.insert(
- std::make_pair(pos+1, std::make_pair("",&output)) );
-
- output_parameter_position = pos+1;
- } //if( pos > 0 )
- } //if( cmdLineMap.count("output") ), append the output flag option
-
- // Set the include and link paths (if applicable)
-
- /*int tail = qmtest_arguments.rbegin()->first;
-
- if( 0 && executable == host_cxx || executable == host_cc )
- {
- qmtest_arguments.insert(
- std::make_pair(tail+1, std::make_pair("-I",&dotdotpwd)) );
-
- qmtest_arguments.insert(
- std::make_pair(tail+2, std::make_pair("-L",&dotdotpwd)) );
- } //if( executable == test_cxx || executable == test_cc ) two additional
- //arguments for compiler executables to include the current directory
- //as an include and link search path */
-
- return;
-} //initialize_qmtest_arguments( int argc, char **argv )
-
-/*
- * Function: write_qmtest_raw
- * Purpose:
- * This function calls system() to generate the .qmt test file based on the
- * constructed command line calling `qmtest create'. An example of such
- * an invocation is:
- *
- * qmtest create -o 16111633834635000__home_yuan5_rose_externalprojects_roseqmgen_timescale.qmt -a program=rose_regression_cc -a arguments="['-DG_DISABLE_DEPRECATED','-g','-O2','-Wall','-o','/home/yuan5/ROSE/externalProjects/roseQMGen/timescale','/home/yuan5/ROSE/externalProjects/roseQMGen/timescale.o','-pthread','/home/yuan5/ROSE/externalProjects/roseQMGen/.libs/libpixops.a','-L/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libgobject-2.0.so','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libgmodule-2.0.so','-ldl','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libgthread-2.0.so','-lpthread','-lrt','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libglib-2.0.so','-lm','-Wl,--rpath','-Wl,/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib','-Wl,--rpath','-Wl,/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib']" test rose.RoseTest
- *
- */
-void write_qmtest_raw()
-{
- std::stringstream ss;
- std::vector< std::string > arguments;
-
- if( output_parameter_position > 0 )
- {
- qmtest_arguments.find(
- output_parameter_position )->second.second->assign(output);
- } //why is this necessary? somehow the output changes don't get reflected
-
- for( std::map<int,std::pair<std::string, std::string*> >::iterator
- itr = qmtest_arguments.begin();
- itr != qmtest_arguments.end(); itr++ )
- {
- arguments.push_back( itr->second.first + *itr->second.second );
- } //for
-
- ss << "qmtest create -o " << qmtest_name;
-
- if( open( "./rne", O_RDONLY ) != -1 )
- {
- ss << " -a expectation=\"XFAIL\"" << " " << envoptions
- << " -a program=" << *arguments.begin() << " -a arguments=\"[";
- } //if( open( "./rne", O_RDONLY ) != -1 )
- else
- {
- ss << " -a program=" << *arguments.begin() << " " << envoptions
- << " -a arguments=\"[";
- } //else
-
- for( unsigned int i = 1; i < arguments.size()-1; i++ )
- ss << "'" << arguments.at(i) << "',";
-
- ss << "'" << arguments.at(arguments.size()-1) << "']\""
- << " test rose.RoseTest";
- std::cout << std::endl;
-
- std::cout << std::endl;
- for( unsigned int i = 0; i < arguments.size()-1; i++ )
- std::cout << "'" << arguments.at(i) << "',";
- std::cout << std::endl;
-
- std::cout << std::endl;
-
- std::cerr << ss.str() << std::endl;
-// system( ss.str().c_str() );
-
- return;
-} //write_qmtest_raw()
-
-
-/*
- * Function: write_rose_db
- * Purpose:
- * This function creates a database of command line options based on the
- * constructed command line. An example of such
- */
-void write_rose_db()
-{
- if(db_name.size() == 0)
- {
- std::cerr << "Error: Please set the database name.\n";
- abort();
- }
- std::stringstream ss;
- std::vector< std::string > arguments;
-
- if( output_parameter_position > 0 )
- {
- qmtest_arguments.find(
- output_parameter_position )->second.second->assign(output);
- } //why is this necessary? somehow the output changes don't get reflected
-
-
-
-
- sqlite3x::sqlite3_connection con(db_name.c_str());
-
- //con.executenonquery("create table IF NOT EXISTS clusters(row_number INTEGER PRIMARY KEY, cluster INTEGER, function_id INTEGER, index_within_function INTEGER, vectors_row INTEGER, dist INTEGER)")
- try {
- con.executenonquery("create table IF NOT EXISTS build_interpreted( row_number INTEGER PRIMARY KEY, compile_line TEXT)");
-
- }
- catch(std::exception &ex) {
- std::cerr << "Exception Occurred: " << ex.what() << std::endl;
- }
-
- try {
- con.executenonquery("create table IF NOT EXISTS build_interpreted_split( row_number INTEGER PRIMARY KEY, build_index INTEGER, first TEXT, second TEXT)");
- }
- catch(std::exception &ex) {
- std::cerr << "Exception Occurred: " << ex.what() << std::endl;
- }
-
- std::string db_select_n = "";
-
- std::string argumentString;
-
- std::vector<char*> argv;
-
- for( std::map<int,std::pair<std::string, std::string*> >::iterator
- itr = qmtest_arguments.begin();
- itr != qmtest_arguments.end(); itr++ )
- {
- argumentString+= ( itr->second.first + *itr->second.second +" " );
- argv.push_back(strdup(argumentString.c_str()));
- } //for
-
-
- { // Insert the string version of each commandline
-
- sqlite3x::sqlite3_command cmd(con, "INSERT INTO build_interpreted( compile_line ) VALUES(\""+argumentString+"\")" );
- cmd.executenonquery();
- }
-
- { // Insert the argv version of the command line
- int build_index = con.executeint("SELECT row_number from build_interpreted where compile_line=\""+argumentString+"\"");
-
- std::string insert_split = "INSERT INTO build_interpreted_split(build_index, first,second ) VALUES(?,?,?)";
- for( std::map<int,std::pair<std::string, std::string*> >::iterator
- itr = qmtest_arguments.begin();
- itr != qmtest_arguments.end(); itr++ )
- {
-
- sqlite3x::sqlite3_command cmd(con, insert_split);
- cmd.bind(1,build_index);
- cmd.bind(2, itr->second.first);
- cmd.bind(3, *itr->second.second);
- cmd.executenonquery();
-
- }
-
-
- }
-
-
- return;
-} //write_rose_db()
-
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/qmgen.C)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,446 @@
+/*
+ * Author: Gary Yuan
+ * Modified by Andreas Saebjoernsen 1/5/09
+ * Date: July 2008
+ * File: roseQMGen/src/qmgen.C
+ */
+
+#include <fstream>
+#include <iostream>
+#include <algorithm>
+#include <sstream>
+
+#include <ctype.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <boost/algorithm/string.hpp>
+
+#include "qmgen.h"
+#include "extern.h"
+#include "commandLineProcessing.h"
+#include "stringManipulations.h"
+
+//AS: Header to support sqlite3x
+#include "sqlite3x.h"
+#include <boost/lexical_cast.hpp>
+
+using namespace boost::algorithm;
+
+int output_parameter_position = 0; //1 + the position of the output flag '-o'
+
+/*
+ * Function: constructMangledTestName
+ * Arguments:
+ * Returns: std::string, mangled name of .qmt test file name
+ * Purpose: constructs the mangled name for the .qmt test file that is created
+ *
+ * The mangled name is of the form
+ *
+ * `date +%d%H%M%S%N`_DIR_OUTPUT.qmt
+ *
+ * Where:
+ * The prefix `date +%d%H%M%S%N` is the creation timestamp of fixed width
+ * that ensures lexigraphic order of all .qmt test files which is critically
+ * important for the execution order of these files during testing
+ *
+ * DIR is the present working directory minus the regression_root path of
+ * the .qmt test file creation location
+ *
+ * OUTPUT is the output flag option if given, otherwise it is the name of
+ * the executable
+ */
+std::string constructMangledTestName()
+{
+ std::string dir( pwd );
+ replace_first( dir, regression_root, "" );
+
+ std::string obj;
+
+ if( output != "" ) obj.assign(output);
+ else if( !objects.empty() ) obj.assign( *objects.begin() );
+ else obj.assign( executable );
+
+ if( output == "" && isCompileOnly && !sources.empty() )
+ {
+ output.assign( *sources.begin() );
+ int e = output.find_last_of(".");
+ int s = output.find_last_of("/");
+ obj.assign( output.substr(s+1, e-s-1) + ".o" );
+ output.assign( pwd + output.substr(s, e-s) + ".o" );
+// std::cout << output << std::endl;
+// std::cout << obj << std::endl;
+
+ int tail = qmtest_arguments.rbegin()->first;
+
+ qmtest_arguments.insert(
+ std::make_pair(tail+1, std::make_pair("",new std::string("-o"))) );
+
+ qmtest_arguments.insert(
+ std::make_pair(tail+2, std::make_pair("",&output)) );
+
+ output_parameter_position = tail+2;
+ } //if( isCompileOnly && !sources.empty() )
+
+ std::string testname;
+
+ do
+ {
+ FILE *fdate = popen( "date +%d%H%M%S%N", "r" );
+ char timestamp[256] = "\0";
+ fread( timestamp, sizeof(char), 17, fdate );
+
+ testname.append( timestamp );
+ testname.append( "_" );
+
+ testname.append( dir + "_" + obj );
+
+ //replace the following illegal QMTest characters in the test name:
+ //'.' -> '_' in the object name
+ //'/' -> '_'
+ //'.' -> '_dot_' in the path name
+ //'+' -> '_plus_'
+ replace_all( obj, ".", "_" );
+ replace_all( testname, "/", "_" );
+ replace_all( testname, ".", "_dot_" );
+ replace_all( testname, "+", "_plus_" );
+
+ //.qmt test file names must be all lower-case
+ std::transform(testname.begin(), testname.end(), testname.begin(), tolower);
+
+ testname.append( ".qmt" );
+ } while( open( testname.c_str(), O_RDONLY ) != -1 && sleep(1) == 0 );
+ //do...while, this loop ensures unique generated file names for a single
+ //instance of this program. If the file name generated already exists then
+ //the program sleeps 1 second and tries again with another time stamp.
+
+ return testname;
+} //constructMangledTestName()
+
+/*
+ * Function: get_argv_index
+ * Arguments:
+ * std::string arg -- the original argument to search for in argv
+ * char **argv -- the original command line argument strings
+ * Returns:
+ * integer -- the index where arg is located in argv
+ * Purpose:
+ * Performs a serial search for the occurence of arg in argv and returns the
+ * index of the occurence or -1 if not found
+ */
+int get_argv_index( std::string arg, int argc, char **argv )
+{
+ int i;
+ for( i = 1; i < argc; i++ )
+ {
+ if( arg == argv[i] && qmtest_arguments.find(i) == qmtest_arguments.end() )
+ {
+ return i;
+ } //if(arg == argv[i] && qmtest_arguments.find(i) == qmtest_arguments.end())
+ } //for
+
+ return -1;
+} //get_argv_index( std::string arg, int argc, char **argv )
+
+/*
+ * Function: initialize_qmtest_arguments_vector
+ * Arguments:
+ * int argc -- the number of command line arguments taken from
+ * initialize_qmtest_arguments
+ * char **argv -- the command line argument strings taken from
+ * initialize_qmtest_arguments
+ * std::string prefix -- the stripped argument prefix taken away by boost
+ * program_options, ex. -I, -L, -D, "", etc.
+ * std::vector< std::string > &arguments -- the boost parsed command line
+ * arguments to insert into qmtest_arguments
+ * Purpose:
+ * This function takes the boost program_options parsed arguments and
+ * inserts them into the primary data structure qmtest_arguments ordered
+ * by their index into the argv array.
+ */
+void initialize_qmtest_arguments_vector(
+ int argc,
+ char **argv,
+ std::string prefix,
+ std::vector< std::string > &arguments
+) {
+ for( std::vector<std::string>::iterator itr = arguments.begin();
+ itr != arguments.end(); itr++ ) {
+ int pos = get_argv_index( (prefix+*itr), argc, argv );
+
+ if( pos > 0 )
+ {
+ qmtest_arguments.insert(
+ std::make_pair( pos, std::make_pair(prefix,&(*itr)) ) );
+ } //if( pos > 0 ), only if valid index
+ } //for
+
+ return;
+} //initialize_qmtest_arguments_vector()
+
+/*
+ * Function: initialize_qmtest_arguments
+ * Arguments:
+ * int argc -- the number of command line arguments taken form main
+ * char **argv -- the command line argument strings taken from main
+ * Purpose:
+ * This function fills the qmtest_arguments data structure with the
+ * 1. test executable name
+ * 2. all the arguments taken from the command line and parsed by boost
+ * 3. the output flag argument (if applicable)
+ * 4. the pwd include and link search path (if applicable)
+ */
+void initialize_qmtest_arguments( int argc, char **argv )
+{
+ //set the program name used in test
+ if( executable == host_cc )
+ {
+ qmtest_arguments.insert(
+ std::make_pair(1, std::make_pair("",&test_cc)) );
+ } //if( executable == host_cc )
+ else if( executable == host_cxx )
+ {
+ qmtest_arguments.insert(
+ std::make_pair(1, std::make_pair("",&test_cxx)) );
+ } //else if( executable == host_cxx )
+ else
+ {
+ qmtest_arguments.insert(
+ std::make_pair(1, std::make_pair("",&executable)) );
+ } //else
+
+ // Set all program options given on command line
+
+ //option_passing_arguments, i.e. -Wl, -Wp, etc.
+ {
+ std::vector< std::string >
+ &original_options = option_passing_arguments.first;
+ std::vector< std::vector< std::string > >
+ &split_options = option_passing_arguments.second;
+
+ assert( original_options.size() == split_options.size() );
+
+ int size = original_options.size();
+ for( int i = 0; i < size; i++ )
+ {
+ int pos = get_argv_index(original_options.at(i), argc, argv);
+
+ if( pos > 0 )
+ {
+ std::string option_prefix = joinOptions(
+ split_options.at(i).begin(),
+ --split_options.at(i).end(), "," );
+
+ qmtest_arguments.insert(
+ std::make_pair(pos, std::make_pair(option_prefix,
+ &(*split_options.at(i).rbegin()))) );
+ } //
+ } //for i
+ } //option_passing_arguments, i.e. -Wl, -Wp, etc.
+
+ if( !includes.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "-I", includes);
+ if( !libincludes.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "-L", libincludes);
+ if( !defines.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "-D", defines);
+ if( !objects.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "", objects);
+ if( !sources.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "", sources);
+ if( !headers.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "", headers);
+ if( !libraries.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "", libraries);
+ if( !relative_paths.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "", relative_paths);
+ if( !unrecognized_arguments.empty() )
+ initialize_qmtest_arguments_vector(argc, argv, "", unrecognized_arguments);
+
+ // Set the output flag option (if applicable)
+
+ if( cmdLineMap.count("output") )
+ {
+ int pos = get_argv_index("-o", argc, argv);
+
+ if( pos > 0 )
+ {
+ qmtest_arguments.insert(
+ std::make_pair(pos, std::make_pair("",new std::string("-o"))) );
+ qmtest_arguments.insert(
+ std::make_pair(pos+1, std::make_pair("",&output)) );
+
+ output_parameter_position = pos+1;
+ } //if( pos > 0 )
+ } //if( cmdLineMap.count("output") ), append the output flag option
+
+ // Set the include and link paths (if applicable)
+
+ /*int tail = qmtest_arguments.rbegin()->first;
+
+ if( 0 && executable == host_cxx || executable == host_cc )
+ {
+ qmtest_arguments.insert(
+ std::make_pair(tail+1, std::make_pair("-I",&dotdotpwd)) );
+
+ qmtest_arguments.insert(
+ std::make_pair(tail+2, std::make_pair("-L",&dotdotpwd)) );
+ } //if( executable == test_cxx || executable == test_cc ) two additional
+ //arguments for compiler executables to include the current directory
+ //as an include and link search path */
+
+ return;
+} //initialize_qmtest_arguments( int argc, char **argv )
+
+/*
+ * Function: write_qmtest_raw
+ * Purpose:
+ * This function calls system() to generate the .qmt test file based on the
+ * constructed command line calling `qmtest create'. An example of such
+ * an invocation is:
+ *
+ * qmtest create -o 16111633834635000__home_yuan5_rose_externalprojects_roseqmgen_timescale.qmt -a program=rose_regression_cc -a arguments="['-DG_DISABLE_DEPRECATED','-g','-O2','-Wall','-o','/home/yuan5/ROSE/externalProjects/roseQMGen/timescale','/home/yuan5/ROSE/externalProjects/roseQMGen/timescale.o','-pthread','/home/yuan5/ROSE/externalProjects/roseQMGen/.libs/libpixops.a','-L/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libgobject-2.0.so','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libgmodule-2.0.so','-ldl','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libgthread-2.0.so','-lpthread','-lrt','/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib/libglib-2.0.so','-lm','-Wl,--rpath','-Wl,/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib','-Wl,--rpath','-Wl,/home/yuan5/ren/ROSE_Regression/mozilla/glib-2.12.12-install/lib']" test rose.RoseTest
+ *
+ */
+void write_qmtest_raw()
+{
+ std::stringstream ss;
+ std::vector< std::string > arguments;
+
+ if( output_parameter_position > 0 )
+ {
+ qmtest_arguments.find(
+ output_parameter_position )->second.second->assign(output);
+ } //why is this necessary? somehow the output changes don't get reflected
+
+ for( std::map<int,std::pair<std::string, std::string*> >::iterator
+ itr = qmtest_arguments.begin();
+ itr != qmtest_arguments.end(); itr++ )
+ {
+ arguments.push_back( itr->second.first + *itr->second.second );
+ } //for
+
+ ss << "qmtest create -o " << qmtest_name;
+
+ if( open( "./rne", O_RDONLY ) != -1 )
+ {
+ ss << " -a expectation=\"XFAIL\"" << " " << envoptions
+ << " -a program=" << *arguments.begin() << " -a arguments=\"[";
+ } //if( open( "./rne", O_RDONLY ) != -1 )
+ else
+ {
+ ss << " -a program=" << *arguments.begin() << " " << envoptions
+ << " -a arguments=\"[";
+ } //else
+
+ for( unsigned int i = 1; i < arguments.size()-1; i++ )
+ ss << "'" << arguments.at(i) << "',";
+
+ ss << "'" << arguments.at(arguments.size()-1) << "']\""
+ << " test rose.RoseTest";
+ std::cout << std::endl;
+
+ std::cout << std::endl;
+ for( unsigned int i = 0; i < arguments.size()-1; i++ )
+ std::cout << "'" << arguments.at(i) << "',";
+ std::cout << std::endl;
+
+ std::cout << std::endl;
+
+ std::cerr << ss.str() << std::endl;
+// system( ss.str().c_str() );
+
+ return;
+} //write_qmtest_raw()
+
+
+/*
+ * Function: write_rose_db
+ * Purpose:
+ * This function creates a database of command line options based on the
+ * constructed command line. An example of such
+ */
+void write_rose_db()
+{
+ if(db_name.size() == 0)
+ {
+ std::cerr << "Error: Please set the database name.\n";
+ abort();
+ }
+ std::stringstream ss;
+ std::vector< std::string > arguments;
+
+ if( output_parameter_position > 0 )
+ {
+ qmtest_arguments.find(
+ output_parameter_position )->second.second->assign(output);
+ } //why is this necessary? somehow the output changes don't get reflected
+
+
+
+
+ sqlite3x::sqlite3_connection con(db_name.c_str());
+
+ //con.executenonquery("create table IF NOT EXISTS clusters(row_number INTEGER PRIMARY KEY, cluster INTEGER, function_id INTEGER, index_within_function INTEGER, vectors_row INTEGER, dist INTEGER)")
+ try {
+ con.executenonquery("create table IF NOT EXISTS build_interpreted( row_number INTEGER PRIMARY KEY, compile_line TEXT)");
+
+ }
+ catch(std::exception &ex) {
+ std::cerr << "Exception Occurred: " << ex.what() << std::endl;
+ }
+
+ try {
+ con.executenonquery("create table IF NOT EXISTS build_interpreted_split( row_number INTEGER PRIMARY KEY, build_index INTEGER, first TEXT, second TEXT)");
+ }
+ catch(std::exception &ex) {
+ std::cerr << "Exception Occurred: " << ex.what() << std::endl;
+ }
+
+ std::string db_select_n = "";
+
+ std::string argumentString;
+
+ std::vector<char*> argv;
+
+ for( std::map<int,std::pair<std::string, std::string*> >::iterator
+ itr = qmtest_arguments.begin();
+ itr != qmtest_arguments.end(); itr++ )
+ {
+ argumentString+= ( itr->second.first + *itr->second.second +" " );
+ argv.push_back(strdup(argumentString.c_str()));
+ } //for
+
+
+ { // Insert the string version of each commandline
+
+ sqlite3x::sqlite3_command cmd(con, "INSERT INTO build_interpreted( compile_line ) VALUES(\""+argumentString+"\")" );
+ cmd.executenonquery();
+ }
+
+ { // Insert the argv version of the command line
+ int build_index = con.executeint("SELECT row_number from build_interpreted where compile_line=\""+argumentString+"\"");
+
+ std::string insert_split = "INSERT INTO build_interpreted_split(build_index, first,second ) VALUES(?,?,?)";
+ for( std::map<int,std::pair<std::string, std::string*> >::iterator
+ itr = qmtest_arguments.begin();
+ itr != qmtest_arguments.end(); itr++ )
+ {
+
+ sqlite3x::sqlite3_command cmd(con, insert_split);
+ cmd.bind(1,build_index);
+ cmd.bind(2, itr->second.first);
+ cmd.bind(3, *itr->second.second);
+ cmd.executenonquery();
+
+ }
+
+
+ }
+
+
+ return;
+} //write_rose_db()
+
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/qmgen.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,20 +0,0 @@
-#ifndef ROSE_QM_GEN_QM_H
-#define ROSE_QM_GEN_QM_H
-
-#include <string>
-#include <vector>
-
-std::string constructMangledTestName();
-int get_argv_index( std::string arg, int argc, char **argv );
-
-void initialize_qmtest_arguments_vector(
- int argc,
- char **argv, std::string prefix,
- std::vector< std::string > &arguments );
-
-void initialize_qmtest_arguments( int argc, char **argv );
-
-void write_qmtest_raw();
-void write_rose_db();
-
-#endif
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/qmgen.h)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/qmgen.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,20 @@
+#ifndef ROSE_QM_GEN_QM_H
+#define ROSE_QM_GEN_QM_H
+
+#include <string>
+#include <vector>
+
+std::string constructMangledTestName();
+int get_argv_index( std::string arg, int argc, char **argv );
+
+void initialize_qmtest_arguments_vector(
+ int argc,
+ char **argv, std::string prefix,
+ std::vector< std::string > &arguments );
+
+void initialize_qmtest_arguments( int argc, char **argv );
+
+void write_qmtest_raw();
+void write_rose_db();
+
+#endif
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/roseQMGen.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,378 +0,0 @@
-/*
- * Author: Gary Yuan
- * Modified by Andreas Saebjoernsen 1/5/09
- * Date: July 2008
- * File: roseQMGen/src/qmgen.C
- */
-
-/*=============================================================================
- Boost.Wave: A Standard compliant C++ preprocessor library
-
- http://www.boost.org/
-
- Copyright (c) 2001-2007 Hartmut Kaiser. Distributed under the Boost
- Software License, Version 1.0. (See accompanying file
- LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-=============================================================================*/
-
-
-#define BOOST_WAVE_SERIALIZATION 0 // enable serialization
-#define BOOST_WAVE_BINARY_SERIALIZATION 0 // use binary archives
-#define BOOST_WAVE_XML_SERIALIZATION 1 // use XML archives
-
-///////////////////////////////////////////////////////////////////////////////
-// include often used files from the stdlib
-#include <iostream>
-#include <fstream>
-#include <string>
-#include <vector>
-#include <algorithm>
-#include <iterator>
-#include <map>
-
-///////////////////////////////////////////////////////////////////////////////
-// include boost config
-#include <boost/config.hpp> // global configuration information
-
-
-///////////////////////////////////////////////////////////////////////////////
-// include required boost libraries
-#include <boost/assert.hpp>
-#include <boost/pool/pool_alloc.hpp>
-
-///////////////////////////////////////////////////////////////////////////////
-// Include additional Boost libraries
-#include <boost/filesystem/path.hpp>
-#include <boost/filesystem/convenience.hpp>
-#include <boost/timer.hpp>
-#include <boost/any.hpp>
-#include <boost/program_options.hpp>
-
-#include <stdlib.h>
-#include <assert.h>
-
-#include "defs.h"
-#include "commandLinePreProcessing.h"
-#include "commandLineProcessing.h"
-#include "stringManipulations.h"
-#include "qmgen.h"
-#include "rose_config.h"
-using namespace boost;
-using namespace boost::program_options;
-
-////////////////////////////////////////////////////////////////////////////////
-//OH-NO GLOBALS!! AND THEY'RE ALL EXTERN'D!!!
-////////////////////////////////////////////////////////////////////////////////
-/*
- * This section describes the data structures used throughout this program
- * to store and manipulate information about the environment and command line
- * arguments. Each is described individually below:
- *
- * includes -- include paths, ex. -I/my/include/path
- * defines -- definitions, ex. -DDEBUG=1
- * libincludes -- linking paths, ex. -L/my/lib/search/path
- * objects -- positional files with extension *.o
- * headers -- positional files with extension *.h
- * sources -- positional files with extension *.[Cc]* *.[Ff]*
- * libraries -- positional linked libraries or other files with extension
- * *.so, *.lo, *.a, *.s, *.S, *.pp, *.gz
- * relative_paths -- positional arguments beginning with '.' indicating a
- * relative path
- * unrecognized_arguments -- all other arguments not recognized by boost
- * program_options
- *
- * qmtest_arguments -- the primary data structure that contains the command
- * line argument information for creating a .qmt test file. This data
- * structure is a map of integer key and std::pair<std::string, std::string*>
- * data. The integer key is simply the array index into the argv array which
- * the argument occurs. The data is a pair of type std::string (first) and
- * std::string* (second). The first string is an argument prefix stripped by
- * boost program_options; like, "-I", "-L", "-D", "", etc. The second
- * string* is a pointer refering to the location of a string in another
- * data structure such as includes, defines, headers, sources, etc. that go
- * go through command line (pre)processing. The concatenation of the first
- * and second members of the pair construct the entire command line argument
- * given to qmtest create
- *
- * option_passing_arguments -- command line arguments that pass options to
- * other components such as the preprocessor or linker; e.g. -Wl, -Wp,
- * Please refer to defs.h for a full explanation of the data structure
- *
- * qmtest_name -- the mangled string name of the .qmt test file
- * executable -- the name of the program which this program wraps
- * shell -- the environment shell, BASH
- * output -- the option of the '-o' flag if exists
- * regression_root -- the absolute path value of ROSE_TEST_REGRESSION_ROOT
- * uplevel -- the string representing a relative path up to the root level of
- * testing at regression_root; usually, ../../ or 2 levels up
- * test_cc -- the C compiler to be used for testing in .qmt files
- * test_cxx -- the C++ compiler to be used for testing in .qmt files
- * host_cc -- the C compiler used when generating .qmt files, usually gcc
- * host_cxx -- the C++ compiler used when generating .qmt files, usually g++
- * pwd -- the present working directory
- * isCompileOny -- boolean == true if '-c' option used on command line
- * cmdnLineMap -- data structure used in boost program_options to hold command
- * line arguments
- * confMap -- data structure used in boost program_options to hold
- * configuration file options
- */
-
-std::vector< std::string > includes;
-std::vector< std::string > defines;
-std::vector< std::string > libincludes;
-std::vector< std::string > objects;
-std::vector< std::string > headers;
-std::vector< std::string > sources;
-std::vector< std::string > libraries;
-std::vector< std::string > relative_paths;
-std::vector< std::string > unrecognized_arguments;
-std::map<int, std::pair<std::string, std::string*> > qmtest_arguments;
-pair_vector_options option_passing_arguments;
-std::string qmtest_name;
-std::string executable;
-std::string shell;
-std::string output;
-std::string regression_root;
-std::string uplevel;
-std::string test_cc;
-std::string test_cxx;
-std::string host_cc;
-std::string host_cxx;
-std::string db_name;
-std::string pwd;
-std::string dotpwd;
-std::string dotdotpwd;
-std::string envoptions;
-bool isCompileOnly;
-boost::program_options::variables_map cmdLineMap;
-boost::program_options::variables_map confMap;
-
-////////////////////////////////////////////////////////////////////////////////
-
-/*
- * Function: initialize_configuration_file_options
- * Arguments:
- * Purpose: parse the configuration file options for this program using boost
- * program_options. The options currently supported are: (see sample.rqmgc)
- *
- * uplevel, test_cc, test_cxx, host_cc, host_cxx
- *
- * The config file must be located in the path given by regression_root and
- * be name .rqmgc
- */
-void initialize_configuration_file_options()
-{
-// std::ifstream conf((std::string(PREFIX)+"/rqmgc").c_str());
- std::cout << ROSE_COMPILE_TREE_PATH"/projects/compass/tools/compass/buildInterpreter/rqmgc" << std::endl;
- //std::ifstream conf(RCFILE);
- std::ifstream conf(ROSE_COMPILE_TREE_PATH"/projects/compass/tools/compass/buildInterpreter/rqmgc");
-
- assert( conf.good() == true );
-
- try
- {
- options_description config("Configuration");
- config.add_options()
- ("uplevel", value<std::string>(&uplevel)->default_value("./"),
- "level up to regression root")
- ("testcc", value<std::string>(&test_cc)->default_value("gcc"),
- "testing C compiler")
- ("testcxx", value<std::string>(&test_cxx)->default_value("g++"),
- "testing C++ compiler")
- ("hostcc", value<std::string>(&host_cc)->default_value("gcc"),
- "host C compiler")
- ("hostcxx", value<std::string>(&host_cxx)->default_value("g++"),
- "host C++ compiler")
- ("dbname", value<std::string>(&db_name)->default_value("buildInterpreterDefault.db"),
- "output database name")
- ;
-
- store(parse_config_file(conf,config),confMap);
- notify(confMap);
- } //try
- catch( std::exception &e )
- {
- }
-
- conf.close();
-
- return;
-} //initialize_configuration_file_options()
-
-/*
- * Function: initialize_command_line_options
- * Arguments:
- * int argc -- the number of command line arguments taken from
- * initialize_options()
- * char **argv -- the command line argument strings taken from
- * initialize_options()
- * Purpose:
- * This function uses boost program_options to parse the command line
- * arguments into data structures declared globally, such as defines,
- * includes, ..., unrecognized_arguments.
- */
-void initialize_command_line_options( int argc, char **argv )
-{
- try
- {
- options_description desc( "Allowed options" );
- desc.add_options()
-// ("help", "TODO: HELP MESSAGE" )
-// ("compile,c", "Compile or assemble the source files, but do not link.")
- ("executable", value<std::string>(&executable))
- ("output,o", value<std::string>(&output)->default_value(""),
- " Write output to file. This is the same as specifying file as the second non-option argument to cpp.")
- ("object", value<std::vector<std::string> >(&objects)->composing(),
- "An object file.")
- ("header", value<std::vector<std::string> >(&headers)->composing(),
- "A header file.")
- ("source", value<std::vector<std::string> >(&sources)->composing(),
- "A source file.")
- ("library", value<std::vector<std::string> >(&libraries)->composing(),
- "A dynamically linked library file.")
- ("include,I", value<std::vector<std::string> >(&includes)->composing(),
- "Add the directory dir to the list of directories to be searched for header files. Directories named by -I are searched before the standard system include directories. If the directory dir is a standard system include directory, the option is ignored to ensure that the default search order for system directories and the special treatment of system headers are not defeated." )
- ("link,L", value<std::vector<std::string> >(&libincludes)->composing(),
- "This option specifies where to find the executables, libraries, include files, and data files of the compiler itself." )
- ("passing_option", value<std::vector<std::string> >(&option_passing_arguments.first)->composing(), "")
- ("relative_path", value<std::vector<std::string> >(&relative_paths)->composing(), "")
- ("define,D", value<std::vector<std::string> >(&defines)->composing(),
- "The contents of definition are tokenized and processed as if they appeared during translation phase three in a #define directive." )
- ;
-
- basic_parsed_options<char> bpo = command_line_parser(argc,argv).options(desc).allow_unregistered().run();
-
- //The command line preprocessing function commandLinePreprocessor is run
- store(command_line_parser(argc,argv).options(desc).extra_parser(commandLinePreprocessor).allow_unregistered().run(),cmdLineMap);
-
- unrecognized_arguments = collect_unrecognized( bpo.options, include_positional );
-
- notify(cmdLineMap);
- } //try
- catch( std::exception &e )
- {
- exit(1);
- } //catch( exception &e )
-
- return;
-} //initialize_command_line_options()
-
-/*
- * Function: initialize_options
- * Arguments:
- * int argc -- the number of command line arguments taken from main
- * char **argv -- the command line arguments taken from main
- * Purpose:
- * This function parses the command line options using boost program_options.
- * Additionally, the internal options of this program itself are parsed
- * using the configuration file .rqmgc; please refer to sample.rqmgc for an
- * example of these options.
- *
- * The actual command line arguments are then assigned to the global argument
- * data structure in initialize_qmtest_arguments().
- */
-void initialize_options( int argc, char **argv )
-{
- char **my_argv = &argv[1]; //skip the zeroth argument that is this program
- int my_argc = argc-1;
-
- executable.assign(argv[1]); //the program name actually being wrapped
-
- //read this program's options through the configuration file
- initialize_configuration_file_options();
-
- //initialize the command line arguments using boost program_options
- initialize_command_line_options(my_argc, my_argv);
-
- commandLinePreprocessing();
-
- //set all boost processed options in their original indices in argv
- initialize_qmtest_arguments(argc,argv);
-
- return;
-} //initialize_options( int argc, char **argv )
-
-/*
- * Function: init
- * Arguments:
- * Purpose:
- * This function initializes the variables holding values taken from the
- * system environment. In particular we record the working SHELL, e.g. bash,
- * the present working directory, and the value for ROSE_TEST_REGRESSION_ROOT.
- */
-void init()
-{
- isCompileOnly = false;
-
-
- if( !getenv("SHELL") )
- {
- std::cerr << "Error: Environment variable $SHELL not defined\n";
- abort();
-
- }
-
- shell.assign( getenv("SHELL") );
-
- //The ROSE_TEST_REGRESSION_ROOT environment variable must be set. This should
- //be done as part of setting up your testing package.
-
- if( !getenv("ROSE_TEST_REGRESSION_ROOT") )
- {
- std::cerr << "Error: Environment variable $ROSE_TEST_REGRESSION_ROOT not defined\n";
- abort();
-
- }
-
- regression_root.assign( getenv("ROSE_TEST_REGRESSION_ROOT") );
-
- pwd.assign( getenv("PWD") );
-
- dotpwd.assign(pwd); setRealRelativePath( dotpwd );
- dotdotpwd.assign(pwd); setRelativePathToRegressionRoot( dotdotpwd );
-
- char *qmsh_flags = getenv("QMSHFLAGS");
-
- if( qmsh_flags != NULL )
- envoptions.assign( qmsh_flags );
- else
- envoptions = "";
-
- return;
-} //init()
-
-/*
- * Function: main
- * Arguments:
- * int argc -- number of command line arguments
- * char **argv -- array of command line argument strings
- * Purpose:
- * Program entry point, performs the steps to generate a .qmt test file in
- * this order:
- * 1. initialize the environment variables
- * 2. initialize the command line arguments
- * 3. perform processing on the command line arguments
- * 4. write the .qmt test file
- * 5. echo to stdout the name of the newly created .qmt test file
- */
-int main( int argc, char **argv )
-{
- if( argc < 2 )
- {
- std::cerr << argv[0] << " must be called with at least one argument!\n";
- exit(1);
- } //if( argc < 2 ), the executable, e.g. "gcc" should always be an argument
-
- init();
- initialize_options( argc, argv );
-
- qmtest_name = constructMangledTestName();
-
- commandLineProcessing();
-
- write_rose_db();
-
- std::cout << qmtest_name << std::endl;
-
- return 0;
-} //main()
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/roseQMGen.C)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/roseQMGen.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,378 @@
+/*
+ * Author: Gary Yuan
+ * Modified by Andreas Saebjoernsen 1/5/09
+ * Date: July 2008
+ * File: roseQMGen/src/qmgen.C
+ */
+
+/*=============================================================================
+ Boost.Wave: A Standard compliant C++ preprocessor library
+
+ http://www.boost.org/
+
+ Copyright (c) 2001-2007 Hartmut Kaiser. Distributed under the Boost
+ Software License, Version 1.0. (See accompanying file
+ LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+=============================================================================*/
+
+
+#define BOOST_WAVE_SERIALIZATION 0 // enable serialization
+#define BOOST_WAVE_BINARY_SERIALIZATION 0 // use binary archives
+#define BOOST_WAVE_XML_SERIALIZATION 1 // use XML archives
+
+///////////////////////////////////////////////////////////////////////////////
+// include often used files from the stdlib
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <iterator>
+#include <map>
+
+///////////////////////////////////////////////////////////////////////////////
+// include boost config
+#include <boost/config.hpp> // global configuration information
+
+
+///////////////////////////////////////////////////////////////////////////////
+// include required boost libraries
+#include <boost/assert.hpp>
+#include <boost/pool/pool_alloc.hpp>
+
+///////////////////////////////////////////////////////////////////////////////
+// Include additional Boost libraries
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include <boost/timer.hpp>
+#include <boost/any.hpp>
+#include <boost/program_options.hpp>
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "defs.h"
+#include "commandLinePreProcessing.h"
+#include "commandLineProcessing.h"
+#include "stringManipulations.h"
+#include "qmgen.h"
+#include "rose_config.h"
+using namespace boost;
+using namespace boost::program_options;
+
+////////////////////////////////////////////////////////////////////////////////
+//OH-NO GLOBALS!! AND THEY'RE ALL EXTERN'D!!!
+////////////////////////////////////////////////////////////////////////////////
+/*
+ * This section describes the data structures used throughout this program
+ * to store and manipulate information about the environment and command line
+ * arguments. Each is described individually below:
+ *
+ * includes -- include paths, ex. -I/my/include/path
+ * defines -- definitions, ex. -DDEBUG=1
+ * libincludes -- linking paths, ex. -L/my/lib/search/path
+ * objects -- positional files with extension *.o
+ * headers -- positional files with extension *.h
+ * sources -- positional files with extension *.[Cc]* *.[Ff]*
+ * libraries -- positional linked libraries or other files with extension
+ * *.so, *.lo, *.a, *.s, *.S, *.pp, *.gz
+ * relative_paths -- positional arguments beginning with '.' indicating a
+ * relative path
+ * unrecognized_arguments -- all other arguments not recognized by boost
+ * program_options
+ *
+ * qmtest_arguments -- the primary data structure that contains the command
+ * line argument information for creating a .qmt test file. This data
+ * structure is a map of integer key and std::pair<std::string, std::string*>
+ * data. The integer key is simply the array index into the argv array which
+ * the argument occurs. The data is a pair of type std::string (first) and
+ * std::string* (second). The first string is an argument prefix stripped by
+ * boost program_options; like, "-I", "-L", "-D", "", etc. The second
+ * string* is a pointer refering to the location of a string in another
+ * data structure such as includes, defines, headers, sources, etc. that go
+ * go through command line (pre)processing. The concatenation of the first
+ * and second members of the pair construct the entire command line argument
+ * given to qmtest create
+ *
+ * option_passing_arguments -- command line arguments that pass options to
+ * other components such as the preprocessor or linker; e.g. -Wl, -Wp,
+ * Please refer to defs.h for a full explanation of the data structure
+ *
+ * qmtest_name -- the mangled string name of the .qmt test file
+ * executable -- the name of the program which this program wraps
+ * shell -- the environment shell, BASH
+ * output -- the option of the '-o' flag if exists
+ * regression_root -- the absolute path value of ROSE_TEST_REGRESSION_ROOT
+ * uplevel -- the string representing a relative path up to the root level of
+ * testing at regression_root; usually, ../../ or 2 levels up
+ * test_cc -- the C compiler to be used for testing in .qmt files
+ * test_cxx -- the C++ compiler to be used for testing in .qmt files
+ * host_cc -- the C compiler used when generating .qmt files, usually gcc
+ * host_cxx -- the C++ compiler used when generating .qmt files, usually g++
+ * pwd -- the present working directory
+ * isCompileOny -- boolean == true if '-c' option used on command line
+ * cmdnLineMap -- data structure used in boost program_options to hold command
+ * line arguments
+ * confMap -- data structure used in boost program_options to hold
+ * configuration file options
+ */
+
+std::vector< std::string > includes;
+std::vector< std::string > defines;
+std::vector< std::string > libincludes;
+std::vector< std::string > objects;
+std::vector< std::string > headers;
+std::vector< std::string > sources;
+std::vector< std::string > libraries;
+std::vector< std::string > relative_paths;
+std::vector< std::string > unrecognized_arguments;
+std::map<int, std::pair<std::string, std::string*> > qmtest_arguments;
+pair_vector_options option_passing_arguments;
+std::string qmtest_name;
+std::string executable;
+std::string shell;
+std::string output;
+std::string regression_root;
+std::string uplevel;
+std::string test_cc;
+std::string test_cxx;
+std::string host_cc;
+std::string host_cxx;
+std::string db_name;
+std::string pwd;
+std::string dotpwd;
+std::string dotdotpwd;
+std::string envoptions;
+bool isCompileOnly;
+boost::program_options::variables_map cmdLineMap;
+boost::program_options::variables_map confMap;
+
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Function: initialize_configuration_file_options
+ * Arguments:
+ * Purpose: parse the configuration file options for this program using boost
+ * program_options. The options currently supported are: (see sample.rqmgc)
+ *
+ * uplevel, test_cc, test_cxx, host_cc, host_cxx
+ *
+ * The config file must be located in the path given by regression_root and
+ * be name .rqmgc
+ */
+void initialize_configuration_file_options()
+{
+// std::ifstream conf((std::string(PREFIX)+"/rqmgc").c_str());
+ std::cout << ROSE_COMPILE_TREE_PATH"/projects/compass/tools/compass/buildInterpreter/rqmgc" << std::endl;
+ //std::ifstream conf(RCFILE);
+ std::ifstream conf(ROSE_COMPILE_TREE_PATH"/projects/compass/tools/compass/buildInterpreter/rqmgc");
+
+ assert( conf.good() == true );
+
+ try
+ {
+ options_description config("Configuration");
+ config.add_options()
+ ("uplevel", value<std::string>(&uplevel)->default_value("./"),
+ "level up to regression root")
+ ("testcc", value<std::string>(&test_cc)->default_value("gcc"),
+ "testing C compiler")
+ ("testcxx", value<std::string>(&test_cxx)->default_value("g++"),
+ "testing C++ compiler")
+ ("hostcc", value<std::string>(&host_cc)->default_value("gcc"),
+ "host C compiler")
+ ("hostcxx", value<std::string>(&host_cxx)->default_value("g++"),
+ "host C++ compiler")
+ ("dbname", value<std::string>(&db_name)->default_value("buildInterpreterDefault.db"),
+ "output database name")
+ ;
+
+ store(parse_config_file(conf,config),confMap);
+ notify(confMap);
+ } //try
+ catch( std::exception &e )
+ {
+ }
+
+ conf.close();
+
+ return;
+} //initialize_configuration_file_options()
+
+/*
+ * Function: initialize_command_line_options
+ * Arguments:
+ * int argc -- the number of command line arguments taken from
+ * initialize_options()
+ * char **argv -- the command line argument strings taken from
+ * initialize_options()
+ * Purpose:
+ * This function uses boost program_options to parse the command line
+ * arguments into data structures declared globally, such as defines,
+ * includes, ..., unrecognized_arguments.
+ */
+void initialize_command_line_options( int argc, char **argv )
+{
+ try
+ {
+ options_description desc( "Allowed options" );
+ desc.add_options()
+// ("help", "TODO: HELP MESSAGE" )
+// ("compile,c", "Compile or assemble the source files, but do not link.")
+ ("executable", value<std::string>(&executable))
+ ("output,o", value<std::string>(&output)->default_value(""),
+ " Write output to file. This is the same as specifying file as the second non-option argument to cpp.")
+ ("object", value<std::vector<std::string> >(&objects)->composing(),
+ "An object file.")
+ ("header", value<std::vector<std::string> >(&headers)->composing(),
+ "A header file.")
+ ("source", value<std::vector<std::string> >(&sources)->composing(),
+ "A source file.")
+ ("library", value<std::vector<std::string> >(&libraries)->composing(),
+ "A dynamically linked library file.")
+ ("include,I", value<std::vector<std::string> >(&includes)->composing(),
+ "Add the directory dir to the list of directories to be searched for header files. Directories named by -I are searched before the standard system include directories. If the directory dir is a standard system include directory, the option is ignored to ensure that the default search order for system directories and the special treatment of system headers are not defeated." )
+ ("link,L", value<std::vector<std::string> >(&libincludes)->composing(),
+ "This option specifies where to find the executables, libraries, include files, and data files of the compiler itself." )
+ ("passing_option", value<std::vector<std::string> >(&option_passing_arguments.first)->composing(), "")
+ ("relative_path", value<std::vector<std::string> >(&relative_paths)->composing(), "")
+ ("define,D", value<std::vector<std::string> >(&defines)->composing(),
+ "The contents of definition are tokenized and processed as if they appeared during translation phase three in a #define directive." )
+ ;
+
+ basic_parsed_options<char> bpo = command_line_parser(argc,argv).options(desc).allow_unregistered().run();
+
+ //The command line preprocessing function commandLinePreprocessor is run
+ store(command_line_parser(argc,argv).options(desc).extra_parser(commandLinePreprocessor).allow_unregistered().run(),cmdLineMap);
+
+ unrecognized_arguments = collect_unrecognized( bpo.options, include_positional );
+
+ notify(cmdLineMap);
+ } //try
+ catch( std::exception &e )
+ {
+ exit(1);
+ } //catch( exception &e )
+
+ return;
+} //initialize_command_line_options()
+
+/*
+ * Function: initialize_options
+ * Arguments:
+ * int argc -- the number of command line arguments taken from main
+ * char **argv -- the command line arguments taken from main
+ * Purpose:
+ * This function parses the command line options using boost program_options.
+ * Additionally, the internal options of this program itself are parsed
+ * using the configuration file .rqmgc; please refer to sample.rqmgc for an
+ * example of these options.
+ *
+ * The actual command line arguments are then assigned to the global argument
+ * data structure in initialize_qmtest_arguments().
+ */
+void initialize_options( int argc, char **argv )
+{
+ char **my_argv = &argv[1]; //skip the zeroth argument that is this program
+ int my_argc = argc-1;
+
+ executable.assign(argv[1]); //the program name actually being wrapped
+
+ //read this program's options through the configuration file
+ initialize_configuration_file_options();
+
+ //initialize the command line arguments using boost program_options
+ initialize_command_line_options(my_argc, my_argv);
+
+ commandLinePreprocessing();
+
+ //set all boost processed options in their original indices in argv
+ initialize_qmtest_arguments(argc,argv);
+
+ return;
+} //initialize_options( int argc, char **argv )
+
+/*
+ * Function: init
+ * Arguments:
+ * Purpose:
+ * This function initializes the variables holding values taken from the
+ * system environment. In particular we record the working SHELL, e.g. bash,
+ * the present working directory, and the value for ROSE_TEST_REGRESSION_ROOT.
+ */
+void init()
+{
+ isCompileOnly = false;
+
+
+ if( !getenv("SHELL") )
+ {
+ std::cerr << "Error: Environment variable $SHELL not defined\n";
+ abort();
+
+ }
+
+ shell.assign( getenv("SHELL") );
+
+ //The ROSE_TEST_REGRESSION_ROOT environment variable must be set. This should
+ //be done as part of setting up your testing package.
+
+ if( !getenv("ROSE_TEST_REGRESSION_ROOT") )
+ {
+ std::cerr << "Error: Environment variable $ROSE_TEST_REGRESSION_ROOT not defined\n";
+ abort();
+
+ }
+
+ regression_root.assign( getenv("ROSE_TEST_REGRESSION_ROOT") );
+
+ pwd.assign( getenv("PWD") );
+
+ dotpwd.assign(pwd); setRealRelativePath( dotpwd );
+ dotdotpwd.assign(pwd); setRelativePathToRegressionRoot( dotdotpwd );
+
+ char *qmsh_flags = getenv("QMSHFLAGS");
+
+ if( qmsh_flags != NULL )
+ envoptions.assign( qmsh_flags );
+ else
+ envoptions = "";
+
+ return;
+} //init()
+
+/*
+ * Function: main
+ * Arguments:
+ * int argc -- number of command line arguments
+ * char **argv -- array of command line argument strings
+ * Purpose:
+ * Program entry point, performs the steps to generate a .qmt test file in
+ * this order:
+ * 1. initialize the environment variables
+ * 2. initialize the command line arguments
+ * 3. perform processing on the command line arguments
+ * 4. write the .qmt test file
+ * 5. echo to stdout the name of the newly created .qmt test file
+ */
+int main( int argc, char **argv )
+{
+ if( argc < 2 )
+ {
+ std::cerr << argv[0] << " must be called with at least one argument!\n";
+ exit(1);
+ } //if( argc < 2 ), the executable, e.g. "gcc" should always be an argument
+
+ init();
+ initialize_options( argc, argv );
+
+ qmtest_name = constructMangledTestName();
+
+ commandLineProcessing();
+
+ write_rose_db();
+
+ std::cout << qmtest_name << std::endl;
+
+ return 0;
+} //main()
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/rqmgc 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,6 +0,0 @@
-uplevel=./
-hostcc=gcc
-hostcxx=g++
-testcc=rose_regression_cc
-testcxx=rose_regression_cxx
-dbname=test.db
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/rqmgc)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/rqmgc 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,6 @@
+uplevel=./
+hostcc=gcc
+hostcxx=g++
+testcc=rose_regression_cc
+testcxx=rose_regression_cxx
+dbname=test.db
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/stringManipulations.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,277 +0,0 @@
-/*
- * Author: Gary Yuan
- * Date: July 2008
- * File: roseQMGen/src/stringManipulations.C
- */
-
-#include <libgen.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <boost/algorithm/string.hpp>
-
-#include "defs.h"
-#include "extern.h"
-#include "stringManipulations.h"
-
-using namespace boost::algorithm;
-
-/*
- * Function: joinOptions
- * Arguments:
- * std::vector< std::string >::iterator b -- begin iterator
- * std::vector< std::string >::iterator e -- end iterator
- * const char *jc -- join character, ex. ","
- * Returns:
- * std::string, the concatenation of the strings in vector and jc character
- * Purpose:
- * This function joins the strings in a vector with the joining character
- *
- * This function is used with the pair_vector_options data-type in defs.h
- */
-std::string joinOptions(
- std::vector< std::string >::iterator b,
- std::vector< std::string >::iterator e,
- const char *jc )
-{
- std::string r("");
- for( std::vector< std::string >::iterator itr = b; itr != e; itr++ )
- {
- r.append(*itr);
- r.append(jc);
- } //for, itr
-
- return r;
-} //joinOptions()
-
-
-
-/*
- * Function: escapeQuotations, wrapper for vector of strings
- */
-void escapeQuotations( std::vector< std::string > &arguments )
-{
- for( std::vector< std::string >::iterator itr = arguments.begin();
- itr != arguments.end(); itr++ )
- {
- escapeQuotations( *itr );
- } //for
-} //escapeQuotations( std::vector< std::string > &arguments )
-
-
-
-/*
- * Function: escapeQuotations
- * Arguments:
- * std::string &argument -- escape the quotations in argument
- * Returns:
- * std::string &argument -- escaped quotations in argument
- * Purpose:
- * This function escapes all instances of single and double quotes
- * in the string given by argument with the backslash character
- */
-void escapeQuotations( std::string &argument )
-{
- replace_all( argument, "\"", "\\\"" );
- replace_all( argument, "'", "\\'" );
-
- return;
-} //escapeQuotations( std::string &argument )
-
-
-
-/*
- * Function: insertQuotations, wrapper for vector of strings
- */
-void insertQuotations( std::vector< std::string > &arguments )
-{
- for( std::vector< std::string >::iterator itr = arguments.begin();
- itr != arguments.end(); itr++ )
- {
- insertQuotations( *itr );
- } //for
-} //insertQuotations( std::vector< std::string > &arguments )
-
-
-
-/*
- * Function: insertQuotations
- * Arguments:
- * std::string &argument -- insert double quotes into argument
- * Returns:
- * std::string &argument -- inserted double quotes into argument
- * Purpose:
- * This function inserts double quotes where needed of a command
- * line argument, usually for defines -D
- */
-void insertQuotations( std::string &argument )
-{
- if( argument.find("\"") == std::string::npos &&
- argument.find(" ") != std::string::npos &&
- argument.find("=") != std::string::npos )
- {
- replace_first( argument, "=", "=\\\"" );
- argument.assign( argument + "\\\"" );
- } //if, argument does not contain quotations, contains spaces and "="
-} //insertQuotations( std::string &argument )
-
-
-
-/*
- * Function: setRelativePathToRegressionRoot, wrapper for pair_vector_options
- */
-void setRelativePathToRegressionRoot( pair_vector_options & options )
-{
- std::vector< std::vector< std::string > > &split_options = options.second;
-
- std::vector< std::vector<std::string> >::iterator itr = split_options.begin();
- for( ; itr != split_options.end(); itr++ )
- {
- setRelativePathToRegressionRoot( *itr->rbegin() );
- } //for, itr
-
- return;
-} //setRelativePathToRegressionRoot( pair_vector_options & options )
-
-
-
-/*
- * Function: setRelativePathToRegressionRoot, wrapper for vector of strings
- */
-void setRelativePathToRegressionRoot( std::vector< std::string > &arguments )
-{
- for( std::vector< std::string >::iterator itr = arguments.begin();
- itr != arguments.end(); itr++ )
- {
- setRelativePathToRegressionRoot( *itr );
- } //for, itr
-} //setRelativePathToRegressionRoot( std::vector< std::string > &arguments )
-
-
-
-/*
- * Function: adjustForRealPath
- * Arguments:
- * std::string &argument -- input absolute or relative path argument
- * Returns:
- * std::string &argument -- resolved absolute realpath of argument
- * Purpose:
- * This function resolves the absolute realpath of an argument
- */
-void adjustForRealPath( std::string &argument )
-{
- char path_max_buffer[4096] = "\0";
- std::string dir( dirname(strdup(argument.c_str())) );
- std::string base( basename(strdup(argument.c_str())) );
-
- realpath( dir.c_str(), path_max_buffer );
- dir.assign( path_max_buffer );
-
- assert( dir.find_first_of(".") != 0 );
- replace_first( dir, regression_root, uplevel );
-
- argument.assign( dir + "/" + base );
-
- return;
-} //adjustForRealPath( std::string &argument )
-
-
-
-/*
- * Function: setRelativePathToRegressionRoot
- * Arguments:
- * std::string &argument -- absolute or relative path argument
- * Returns:
- * std::string &argument -- resolved path of argument using uplevel
- * Purpose:
- * This function replaces any instance of regression_root with
- * uplevel in the resolved real path of an absolute path argument
- */
-void setRelativePathToRegressionRoot( std::string &argument )
-{
- if( open(argument.c_str(), O_RDONLY) != -1 || argument.find(".") == 0 )
- adjustForRealPath( argument );
-
- replace_first( argument, regression_root, uplevel );
-// replace_first( argument, "/home/yuan5/", uplevel );
-
- return;
-} //setRelativePathToRegressionRoot( std::string &argument )
-
-
-
-/*
- * Function: setRealRelativePath, wrapper for vector of strings
- */
-void setRealRelativePath( std::vector< std::string > &arguments )
-{
- for( std::vector< std::string >::iterator itr = arguments.begin();
- itr != arguments.end(); itr++ )
- {
- setRealRelativePath( *itr );
- } //for
-
- return;
-} //setRealRelativePath( std::vector< std::string > &arguments )
-
-
-
-/*
- * Function: setRealRelativePath
- * Arguments:
- * std::string &argument -- absolute or relative path argument
- * Returns:
- * std::string &argument -- resolved path of argument using "./"
- * Purpose:
- * This function replaces any instance of regression_root with
- * "./" in the resolved real path of an absolute path argument.
- */
-void setRealRelativePath( std::string &argument )
-{
- char path_max_buffer[4096] = "\0";
-
- realpath( argument.c_str(), path_max_buffer );
-
- argument.assign( path_max_buffer );
-
- replace_first( argument, regression_root, "./" );
-
-// replace_first( argument, "/home/yuan5/ren/roseQMGen", "./" );
-} //void setRealRelativePath( std::string &argument )
-
-
-
-/*
- * Function: setRealRelativePathToRegressionRoot, wrapper for vector of strings
- */
-void setRealRelativePathToRegressionRoot( std::vector<std::string> &arguments )
-{
- for( std::vector< std::string >::iterator itr = arguments.begin();
- itr != arguments.end(); itr++ )
- {
- setRealRelativePathToRegressionRoot( *itr );
- } //for, itr
-
- return;
-} //setRealRelativePathToRegressionRoot( std::vector<std::string> &arguments )
-
-
-
-/*
- * Function: setRealRelativePathToRegressionRoot
- * Arguments:
- * std::string &argument -- absolute or relative path argument
- * Returns:
- * std::string &argument -- resolved realpath of argument using uplevel
- * Purpose:
- * This function unconditionally, resolves the realpath of an absolute or
- * relative path and replaces any instance of regression_root with uplevel.
- */
-void setRealRelativePathToRegressionRoot( std::string &argument )
-{
- adjustForRealPath( argument );
-
- replace_first( argument, regression_root, uplevel );
-} //setRealRelativePathToRegressionRoot( std::string &argument )
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/stringManipulations.C)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,277 @@
+/*
+ * Author: Gary Yuan
+ * Date: July 2008
+ * File: roseQMGen/src/stringManipulations.C
+ */
+
+#include <libgen.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <boost/algorithm/string.hpp>
+
+#include "defs.h"
+#include "extern.h"
+#include "stringManipulations.h"
+
+using namespace boost::algorithm;
+
+/*
+ * Function: joinOptions
+ * Arguments:
+ * std::vector< std::string >::iterator b -- begin iterator
+ * std::vector< std::string >::iterator e -- end iterator
+ * const char *jc -- join character, ex. ","
+ * Returns:
+ * std::string, the concatenation of the strings in vector and jc character
+ * Purpose:
+ * This function joins the strings in a vector with the joining character
+ *
+ * This function is used with the pair_vector_options data-type in defs.h
+ */
+std::string joinOptions(
+ std::vector< std::string >::iterator b,
+ std::vector< std::string >::iterator e,
+ const char *jc )
+{
+ std::string r("");
+ for( std::vector< std::string >::iterator itr = b; itr != e; itr++ )
+ {
+ r.append(*itr);
+ r.append(jc);
+ } //for, itr
+
+ return r;
+} //joinOptions()
+
+
+
+/*
+ * Function: escapeQuotations, wrapper for vector of strings
+ */
+void escapeQuotations( std::vector< std::string > &arguments )
+{
+ for( std::vector< std::string >::iterator itr = arguments.begin();
+ itr != arguments.end(); itr++ )
+ {
+ escapeQuotations( *itr );
+ } //for
+} //escapeQuotations( std::vector< std::string > &arguments )
+
+
+
+/*
+ * Function: escapeQuotations
+ * Arguments:
+ * std::string &argument -- escape the quotations in argument
+ * Returns:
+ * std::string &argument -- escaped quotations in argument
+ * Purpose:
+ * This function escapes all instances of single and double quotes
+ * in the string given by argument with the backslash character
+ */
+void escapeQuotations( std::string &argument )
+{
+ replace_all( argument, "\"", "\\\"" );
+ replace_all( argument, "'", "\\'" );
+
+ return;
+} //escapeQuotations( std::string &argument )
+
+
+
+/*
+ * Function: insertQuotations, wrapper for vector of strings
+ */
+void insertQuotations( std::vector< std::string > &arguments )
+{
+ for( std::vector< std::string >::iterator itr = arguments.begin();
+ itr != arguments.end(); itr++ )
+ {
+ insertQuotations( *itr );
+ } //for
+} //insertQuotations( std::vector< std::string > &arguments )
+
+
+
+/*
+ * Function: insertQuotations
+ * Arguments:
+ * std::string &argument -- insert double quotes into argument
+ * Returns:
+ * std::string &argument -- inserted double quotes into argument
+ * Purpose:
+ * This function inserts double quotes where needed of a command
+ * line argument, usually for defines -D
+ */
+void insertQuotations( std::string &argument )
+{
+ if( argument.find("\"") == std::string::npos &&
+ argument.find(" ") != std::string::npos &&
+ argument.find("=") != std::string::npos )
+ {
+ replace_first( argument, "=", "=\\\"" );
+ argument.assign( argument + "\\\"" );
+ } //if, argument does not contain quotations, contains spaces and "="
+} //insertQuotations( std::string &argument )
+
+
+
+/*
+ * Function: setRelativePathToRegressionRoot, wrapper for pair_vector_options
+ */
+void setRelativePathToRegressionRoot( pair_vector_options & options )
+{
+ std::vector< std::vector< std::string > > &split_options = options.second;
+
+ std::vector< std::vector<std::string> >::iterator itr = split_options.begin();
+ for( ; itr != split_options.end(); itr++ )
+ {
+ setRelativePathToRegressionRoot( *itr->rbegin() );
+ } //for, itr
+
+ return;
+} //setRelativePathToRegressionRoot( pair_vector_options & options )
+
+
+
+/*
+ * Function: setRelativePathToRegressionRoot, wrapper for vector of strings
+ */
+void setRelativePathToRegressionRoot( std::vector< std::string > &arguments )
+{
+ for( std::vector< std::string >::iterator itr = arguments.begin();
+ itr != arguments.end(); itr++ )
+ {
+ setRelativePathToRegressionRoot( *itr );
+ } //for, itr
+} //setRelativePathToRegressionRoot( std::vector< std::string > &arguments )
+
+
+
+/*
+ * Function: adjustForRealPath
+ * Arguments:
+ * std::string &argument -- input absolute or relative path argument
+ * Returns:
+ * std::string &argument -- resolved absolute realpath of argument
+ * Purpose:
+ * This function resolves the absolute realpath of an argument
+ */
+void adjustForRealPath( std::string &argument )
+{
+ char path_max_buffer[4096] = "\0";
+ std::string dir( dirname(strdup(argument.c_str())) );
+ std::string base( basename(strdup(argument.c_str())) );
+
+ realpath( dir.c_str(), path_max_buffer );
+ dir.assign( path_max_buffer );
+
+ assert( dir.find_first_of(".") != 0 );
+ replace_first( dir, regression_root, uplevel );
+
+ argument.assign( dir + "/" + base );
+
+ return;
+} //adjustForRealPath( std::string &argument )
+
+
+
+/*
+ * Function: setRelativePathToRegressionRoot
+ * Arguments:
+ * std::string &argument -- absolute or relative path argument
+ * Returns:
+ * std::string &argument -- resolved path of argument using uplevel
+ * Purpose:
+ * This function replaces any instance of regression_root with
+ * uplevel in the resolved real path of an absolute path argument
+ */
+void setRelativePathToRegressionRoot( std::string &argument )
+{
+ if( open(argument.c_str(), O_RDONLY) != -1 || argument.find(".") == 0 )
+ adjustForRealPath( argument );
+
+ replace_first( argument, regression_root, uplevel );
+// replace_first( argument, "/home/yuan5/", uplevel );
+
+ return;
+} //setRelativePathToRegressionRoot( std::string &argument )
+
+
+
+/*
+ * Function: setRealRelativePath, wrapper for vector of strings
+ */
+void setRealRelativePath( std::vector< std::string > &arguments )
+{
+ for( std::vector< std::string >::iterator itr = arguments.begin();
+ itr != arguments.end(); itr++ )
+ {
+ setRealRelativePath( *itr );
+ } //for
+
+ return;
+} //setRealRelativePath( std::vector< std::string > &arguments )
+
+
+
+/*
+ * Function: setRealRelativePath
+ * Arguments:
+ * std::string &argument -- absolute or relative path argument
+ * Returns:
+ * std::string &argument -- resolved path of argument using "./"
+ * Purpose:
+ * This function replaces any instance of regression_root with
+ * "./" in the resolved real path of an absolute path argument.
+ */
+void setRealRelativePath( std::string &argument )
+{
+ char path_max_buffer[4096] = "\0";
+
+ realpath( argument.c_str(), path_max_buffer );
+
+ argument.assign( path_max_buffer );
+
+ replace_first( argument, regression_root, "./" );
+
+// replace_first( argument, "/home/yuan5/ren/roseQMGen", "./" );
+} //void setRealRelativePath( std::string &argument )
+
+
+
+/*
+ * Function: setRealRelativePathToRegressionRoot, wrapper for vector of strings
+ */
+void setRealRelativePathToRegressionRoot( std::vector<std::string> &arguments )
+{
+ for( std::vector< std::string >::iterator itr = arguments.begin();
+ itr != arguments.end(); itr++ )
+ {
+ setRealRelativePathToRegressionRoot( *itr );
+ } //for, itr
+
+ return;
+} //setRealRelativePathToRegressionRoot( std::vector<std::string> &arguments )
+
+
+
+/*
+ * Function: setRealRelativePathToRegressionRoot
+ * Arguments:
+ * std::string &argument -- absolute or relative path argument
+ * Returns:
+ * std::string &argument -- resolved realpath of argument using uplevel
+ * Purpose:
+ * This function unconditionally, resolves the realpath of an absolute or
+ * relative path and replaces any instance of regression_root with uplevel.
+ */
+void setRealRelativePathToRegressionRoot( std::string &argument )
+{
+ adjustForRealPath( argument );
+
+ replace_first( argument, regression_root, uplevel );
+} //setRealRelativePathToRegressionRoot( std::string &argument )
Deleted: branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h
===================================================================
--- trunk/projects/compass/tools/compass/buildInterpreter/stringManipulations.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,27 +0,0 @@
-#ifndef ROSE_QM_GEN_STRING_MANIPULATION_H
-#define ROSE_QM_GEN_STRING_MANIPULATION_H
-
-#include <string>
-#include <vector>
-
-std::string joinOptions(
- std::vector< std::string >::iterator b,
- std::vector< std::string >::iterator e,
- const char *jc );
-
-void escapeQuotations( std::vector< std::string > &arguments );
-void escapeQuotations( std::string &argument );
-
-void insertQuotations( std::vector< std::string > &arguments );
-void insertQuotations( std::string &argument );
-
-void setRelativePathToRegressionRoot( pair_vector_options & options );
-void setRelativePathToRegressionRoot( std::vector< std::string > &arguments );
-void setRelativePathToRegressionRoot( std::string &argument );
-
-void setRealRelativePath( std::string &argument );
-void setRealRelativePath( std::vector< std::string > &arguments );
-
-void setRealRelativePathToRegressionRoot( std::vector<std::string> &arguments );void setRealRelativePathToRegressionRoot( std::string &argument );
-
-#endif
Copied: branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h (from rev 188, trunk/projects/compass/tools/compass/buildInterpreter/stringManipulations.h)
===================================================================
--- branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h (rev 0)
+++ branches/imperial/projects/compass/tools/compass/buildInterpreter/stringManipulations.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,27 @@
+#ifndef ROSE_QM_GEN_STRING_MANIPULATION_H
+#define ROSE_QM_GEN_STRING_MANIPULATION_H
+
+#include <string>
+#include <vector>
+
+std::string joinOptions(
+ std::vector< std::string >::iterator b,
+ std::vector< std::string >::iterator e,
+ const char *jc );
+
+void escapeQuotations( std::vector< std::string > &arguments );
+void escapeQuotations( std::string &argument );
+
+void insertQuotations( std::vector< std::string > &arguments );
+void insertQuotations( std::string &argument );
+
+void setRelativePathToRegressionRoot( pair_vector_options & options );
+void setRelativePathToRegressionRoot( std::vector< std::string > &arguments );
+void setRelativePathToRegressionRoot( std::string &argument );
+
+void setRealRelativePath( std::string &argument );
+void setRealRelativePath( std::vector< std::string > &arguments );
+
+void setRealRelativePathToRegressionRoot( std::vector<std::string> &arguments );void setRealRelativePathToRegressionRoot( std::string &argument );
+
+#endif
Modified: branches/imperial/projects/compass/tools/compass/doc/Makefile.am
===================================================================
--- branches/imperial/projects/compass/tools/compass/doc/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/doc/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -39,6 +39,7 @@
ToolGear_gui_compass_01.pdf \
ToolGear_gui_compass_01.png \
usingCompass.tex \
+ usingCompassGui.tex \
compass_categories.tex \
usingCompassVerifier.tex
Modified: branches/imperial/projects/compass/tools/compass/doc/compass.tex.in
===================================================================
--- branches/imperial/projects/compass/tools/compass/doc/compass.tex.in 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/doc/compass.tex.in 2009-01-14 15:08:15 UTC (rev 189)
@@ -180,6 +180,10 @@
\newpage
+\input{usingCompassGui}
+
+\newpage
+
\input{usingCompassVerifier}
\newpage
Modified: branches/imperial/projects/compass/tools/compass/doc/usingCompass.tex
===================================================================
--- branches/imperial/projects/compass/tools/compass/doc/usingCompass.tex 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/doc/usingCompass.tex 2009-01-14 15:08:15 UTC (rev 189)
@@ -8,6 +8,7 @@
compass directory.
\section{Installation}
+\label{usingCompassInstallation}
Please follow
\htmladdnormallink{ROSE Installation
Guide}{http://www.rosecompiler.org/ROSE_InstallationInstructions.pdf} to
@@ -44,7 +45,7 @@
\section{Running Compass}
-Once properly installed and configured, running compass is a matter if typing {\tt compassMain}
+Once properly installed and configured, running compass is a matter of typing {\tt compassMain}
and handing in a number of options. The {\tt compassMain} program acts just
like a compiler so it is appropriate to hand it the same options required to
compile your source file (e.g {\tt -I} directory paths and a source file.
Copied: branches/imperial/projects/compass/tools/compass/doc/usingCompassGui.tex (from rev 188, trunk/projects/compass/tools/compass/doc/usingCompassGui.tex)
===================================================================
--- branches/imperial/projects/compass/tools/compass/doc/usingCompassGui.tex (rev 0)
+++ branches/imperial/projects/compass/tools/compass/doc/usingCompassGui.tex 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,88 @@
+\chapter{Using Compass GUI}
+
+Compass has a GUI available for exploring the checker warnings for either the compilation
+of a single source file or the compilation of a whole project. This GUI allow the user to
+interactively select checkers, run those checkers on the source file(s) of
+interest and display the source location of each violation. As a user convenience the
+interface will either display the violating source region in a text editor or a
+non-editable display window.
+
+The Compass GUI is located in the 'projects/compass/tools/compass/gui' directory of the
+ROSE distribution. The Compass GUI is build as part of the standard Compass build when
+ROSE is configured with qt4. In order to enable simple compilation of whole projects using
+one-button clicks in the Compass GUI ROSE must be configured with sqlite3 as well.
+
+\section{Running Compass GUI on a Single File}
+\label{runningCompassGUISingleFile}
+
+Before running the Compass GUI on a single file the files listed
+in \ref{usingCompassInstallation} must be available and the environment variable
+'\$COMPASS\_PARAMETERS' must specify which compass\_paramaters file to use. CompassGUI can
+then be invoked as a normal compiler like e.g:
+\begin{verbatim}
+compassMainGui -o ex1 ex1.C
+\end{verbatim}
+If it is not desirable to export the '\$COMPASS\_PARAMETERS' variable a shorthand is:
+\begin{verbatim}
+env COMPASS_PARAMETERS=/location/of/compass_pramateres compassMainGui -o ex1 ex1.C
+\end{verbatim}
+
+\section{Running Compass GUI on an Autotools Project}
+
+A goal of this section is to show how to run the compass checkers on a whole project (like e.g ROSE)
+using a one button click in the Compass GUI and present an easy interface for exploring the violations
+as found during the build. This interface is currently limited to sequentially building the
+project and it requires ROSE to be configured with sqlite3. The Compass GUI does not try to replace the
+build system; it simply captures how the build system compiles the source files for a specific version of the
+project. Although there is no guarantee that this will work when the source code changes it is reasonable to
+expect the capturing of the build system should be the same as the code evolves as long as no changes are done
+to the build system.
+
+These instructions can apply to Autotool projects as well as projects build in other build
+systems, but the shorthands used here for discerning the build system are specific for Autotools.
+
+
+\subsection{Capturing a Build System State}
+
+\fixme{Document: that this requires --with-sqlite3}
+
+The first step of running the Compass GUI on an autotools project is to figure out how the build system
+works. Capturing the build system state is done with the 'buildInterpreter' tool provided in the Compass
+distribution in the 'projects/compass/tools/compass/buildInterpreter' directory.
+
+In order to facilitate capturing the build system once and moving the source files around the '\$ROSE\_TEST\_REGRESSION\_ROOT' environment variable must be defined to the string that should be replaced. For instance if a
+projects is build within /home/user/project and it is desired to move the files inside that directoy to a
+different directory define it to be
+\begin{verbatim}
+export ROSE_TEST_REGRESSION_ROOT=/home/user/project
+\end{verbatim}
+
+\fixme{Document: Need to be in the buildInterpreter directory.}
+
+The buildInterpreter tool works as a replacement for the C/C++ compiler during compilation like e.g:
+\begin{verbatim}
+buildInterpreter -o ex1 ex1.C
+\end{verbatim}
+The output of the run is a database representing how to compile ex1.C. The name of the output database is specified
+by the 'dbname' field in the rqmc file found in the ROSE build directory under 'projects/compass/tools/compass/buildInterpreter/rqmc' and defaults to 'test.db'.
+
+To capture the state of a whole build system use 'buildInterpreter' as a replacement for the C/C++ compiler during
+the build. E.g for gnu make:
+\begin{verbatim}
+make CC=buildInterpreter CXX=buildInterpreter
+\end{verbatim}
+
+\subsection{Build A Project Using the Discerned Build }
+
+To build a project using Compass specify the output database from the capturing of the build state with the
+'--outputDb' paramater to the Compass GUI. The environment variable must be defined like in \ref{runningCompassGUISingleFile}, e.g:
+\begin{verbatim}
+cd /directory/with/build/project/sources
+env COMPASS_PARAMETERS=/location/of/compass_pramateres /compass/gui/build/compassMainGui --outputDb test.db
+\end{verbatim}
+In the GUI click on regenerate to build the project. The violations found during the build is put into the database
+for subsequent lookup. After regenerating select the checkers that you are interested and and click 'refresh' to display the corresponding violations.
+
+
+
+
Modified: branches/imperial/projects/compass/tools/compass/gui/compassGui.C
===================================================================
--- branches/imperial/projects/compass/tools/compass/gui/compassGui.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/gui/compassGui.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -10,13 +10,20 @@
#include "disks.xpm"
+
+//For fork()
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+
#define EMACS
using namespace qrs;
typedef enum
{
- TB_RUN, TB_RESET, TB_SEL_ALL, TB_SEL_EN, TB_SEL_REV, TB_UNSEL_ALL,
+ TB_RUN, TB_REFRESH, TB_RESET, TB_SEL_ALL, TB_SEL_EN, TB_SEL_REV, TB_UNSEL_ALL,
TB_SORT_NAME, TB_SORT_TIMING, TB_SORT_VIOLATIONS, TB_SAVE, TB_QUIT
} ButtonID;
@@ -33,8 +40,9 @@
{
CompassGui *instance = QROSE::cbData<CompassGui *>();
switch (id)
- {
- case TB_RUN: instance->run(); break;
+ {
+ case TB_RUN: instance->run(); break;
+ case TB_REFRESH: instance->refresh(); break;
case TB_RESET: instance->reset(); break;
case TB_SEL_ALL:
case TB_SEL_EN:
@@ -87,19 +95,22 @@
QRToolBar *toolbar = (*window)["toolbar"] << new QRToolBar(QROSE::LeftRight, true, true, true);
// icons are defined in <icons.h>
- toolbar->addButton("run"); toolbar->setPicture(0, iconRun);
- toolbar->addButton("reset"); toolbar->setPicture(1, iconReset);
+ toolbar->addButton("regenerate"); toolbar->setPicture(0, iconRun);
+ toolbar->addButton("refresh"); toolbar->setPicture(1, iconRun);
+ toolbar->addButton("reset"); toolbar->setPicture(2, iconReset);
toolbar->addSeparator();
- toolbar->addButton("select all"); toolbar->setPicture(2, iconSelectAll);
- toolbar->addButton("select enabled"); toolbar->setPicture(3, iconSelectEnabled);
- toolbar->addButton("select reverse"); toolbar->setPicture(4, iconSelectReversed); toolbar->addButton("unselect all"); toolbar->setPicture(5, iconUnselectAll);
+ toolbar->addButton("select all"); toolbar->setPicture(3, iconSelectAll);
+ toolbar->addButton("select enabled"); toolbar->setPicture(4, iconSelectEnabled);
+ toolbar->addButton("select reverse"); toolbar->setPicture(5, iconSelectReversed);
+ toolbar->addButton("unselect all"); toolbar->setPicture(6, iconUnselectAll);
toolbar->addSeparator();
- toolbar->addButton("sort by name"); toolbar->setPicture(6, iconSortByName);
- toolbar->addButton("sort by time"); toolbar->setPicture(7, iconSortByTime);
- toolbar->addButton("sort by violations"); toolbar->setPicture(8, iconSortByViolations);
+ toolbar->addButton("sort by name"); toolbar->setPicture(7, iconSortByName);
+ toolbar->addButton("sort by time"); toolbar->setPicture(8, iconSortByTime);
+ toolbar->addButton("sort by violations"); toolbar->setPicture(9, iconSortByViolations);
toolbar->addSeparator();
- toolbar->addButton("save"); toolbar->setPicture(9, disks_xpm);
- toolbar->addButton("quit"); toolbar->setPicture(10, iconQuit);
+ toolbar->addButton("save"); toolbar->setPicture(10, disks_xpm);
+ toolbar->addButton("quit"); toolbar->setPicture(11, iconQuit);
+// toolbar->addButton("regenerate"); toolbar->setPicture(12, iconRun);
QROSE::link(toolbar, SIGNAL(clicked(int)), &toolbarClick, this);
@@ -246,7 +257,7 @@
return;
} //CompassGui::updateTableWidget()
-void CompassGui::run()
+void CompassGui::refresh()
{
CompassCheckers_v checkers = compassInterface.getCompassCheckers();
QRProgress *progress = (*window)["progress"];
@@ -267,8 +278,172 @@
updateTableWidget();
return;
-} //CompassGui::run()
+} //CompassGui::refresh()
+
+#ifdef HAVE_SQLITE3
+
+#include "sqlite3x.h"
+#include <boost/lexical_cast.hpp>
+
+#endif
+
+
+struct BuildLine{
+ int build_index;
+ std::string compile_line;
+ std::vector<std::pair<std::string, std::string> > argv;
+};
+
+void CompassGui::run()
+{
+#ifdef HAVE_SQLITE3
+ std::vector<BuildLine> buildLines;
+
+ //Make sure that the violations table exists and is empty
+ try {
+ sqlite3x::sqlite3_command cmd(Compass::con, "drop table if exists violations" );
+ cmd.executenonquery();
+ } catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}
+ try {
+ Compass::con.executenonquery("create table IF NOT EXISTS violations( row_number INTEGER PRIMARY KEY, checker_name TEXT, error_body TEXT, filename TEXT, line INTEGER, short_description TEXT )");
+ } catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}
+
+
+
+ if ( Compass::UseDbOutput == true )
+ {
+
+ try { // Read each build_index from the database
+ /* Read in from database here */
+ sqlite3x::sqlite3_command cmd(Compass::con, "SELECT row_number,compile_line from build_interpreted" );
+ sqlite3x::sqlite3_reader r = cmd.executereader();
+ while (r.read()) {
+ int build_index = r.getint(0);
+ std::string compile_line = r.getstring(1);
+
+ BuildLine commandLine;
+ commandLine.build_index = build_index;
+ commandLine.compile_line= compile_line;
+
+ buildLines.push_back(commandLine);
+ std::cout << compile_line << std::endl;
+ }
+
+ } catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}
+
+
+ //For each build index find the argv in the database
+ for(unsigned int i = 0; i < buildLines.size(); i++)
+ {
+ BuildLine& commandLine = buildLines[i];
+ try {
+ /* Read in from database here */
+ sqlite3x::sqlite3_command cmd(Compass::con, "SELECT first,second from build_interpreted_split where build_index=? ORDER BY row_number" );
+ cmd.bind(1,commandLine.build_index);
+ sqlite3x::sqlite3_reader r = cmd.executereader();
+ while (r.read()) {
+ std::string first = r.getstring(0);
+ std::string second = r.getstring(1);
+
+ commandLine.argv.push_back(std::pair<std::string,std::string>(first,second) );
+
+ }
+
+ } catch (std::exception& e) {std::cerr << "Exception: " << e.what() << std::endl;}
+
+
+ }
+
+ }
+
+
+ if(buildLines.size() != 0) // If there are something to build, build it.
+ {
+
+
+
+
+ QRProgress *progress = (*window)["progress"];
+
+
+ compassInterface.getResult()->reset();
+ progress->set(buildLines.size());
+
+
+ progress->set(0,buildLines.size());
+
+ for(unsigned int i=0; i < buildLines.size() ; i++)
+ {
+ progress->tick();
+ std::string runCompassPath = std::string(ROSE_COMPILE_TREE_PATH) + "/projects/compass/tools/compass/compassMain";
+
+ BuildLine& commandLine = buildLines[i];
+ std::vector<char*> argv;
+ argv.push_back(strdup(runCompassPath.c_str()));
+ for(int j =0; j < commandLine.argv.size(); j++ )
+ {
+ std::string cur_arg = commandLine.argv[j].first + commandLine.argv[j].second;
+ argv.push_back( strdup( (char*) cur_arg.c_str() ));
+
+ }
+
+ argv.push_back("--outputDb");
+ argv.push_back(strdup(Compass::outputDbName.c_str()));
+
+ std::cout << "Executing " << commandLine.compile_line << std::endl;
+
+
+ //Execute compass to find violations
+
+ std::cout << std::endl << "normal compile: ";
+ std::string runningROSE;
+ for(int i=0; i<argv.size(); i++)
+ {
+ runningROSE+= std::string(argv[i]) + " ";
+
+ //std::cout << argv[i] << " ";
+
+
+ };
+ std::cout << std::endl;
+
+
+ //AS(1/9/09) execv(..) does not work on Dan's machine so we have to use system(..)
+ int errorCodeROSE = system(runningROSE.c_str());
+
+ if(errorCodeROSE)
+ {
+ runningROSE+=" -rose:skip_rose ";
+
+ errorCodeROSE = system(runningROSE.c_str()) ;
+ if(errorCodeROSE) abort();
+
+
+ }
+
+
+ std::cerr << "Status: " << errorCodeROSE << std::endl;
+ std::cerr << "Done execution " << commandLine.compile_line << std::endl;
+
+
+ }
+
+ updateTableWidget();
+ }
+
+#else
+// refresh();
+#endif
+
+ return;
+} //CompassGui::refresh()
+
+
+
+
+
+
void CompassGui::reset()
{
compassInterface.reset();
Modified: branches/imperial/projects/compass/tools/compass/gui/compassGui.h
===================================================================
--- branches/imperial/projects/compass/tools/compass/gui/compassGui.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/compass/tools/compass/gui/compassGui.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -17,6 +17,7 @@
~CompassGui();
void updateTableWidget();
void run();
+ void refresh();
void reset();
void select(int);
void sort(int);
Modified: branches/imperial/projects/runtimeErrorCheck/Makefile.am
===================================================================
--- branches/imperial/projects/runtimeErrorCheck/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/projects/runtimeErrorCheck/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -58,17 +58,16 @@
./runtimeCheck -DCAN_NOT_COMPILE_WITH_ROSE=true $(TESTCODES5) -pdf -o test_bin5
./test_bin5
if !ROSE_USE_BINARY_SQL
- ./runtimeCheck -DCAN_NOT_COMPILE_WITH_ROSE=true $(TESTCODES3) -run -c -o test_bin3.o $(INCLUDES2)
- $(LIBTOOL) --mode=link $(CXX) -o test_bin3 test_bin3.o $(LDADD)
- ./test_bin3 $(srcdir)/example.C -run
+# DQ (12/23/2008): Commented out this example which fails...
+# ./runtimeCheck -DCAN_NOT_COMPILE_WITH_ROSE=true $(TESTCODES3) -run -c -o test_bin3.o $(INCLUDES2)
+# $(LIBTOOL) --mode=link $(CXX) -o test_bin3 test_bin3.o $(LDADD)
+# ./test_bin3
endif
endif
-# @echo "*********************************************************************************************************************"
-# @echo "*** ROSE/tests/roseTests/programAnalysisTests/defUseAnalysisTests: make check rule complete (terminated normally) ***"
-# @echo "*********************************************************************************************************************"
+ @echo "***************************************************************************************"
+ @echo "*** ROSE/projects/runtimeErrorCheck: make check rule complete (terminated normally) ***"
+ @echo "***************************************************************************************"
-
-
clean-local:
rm -rf $(CXX_TEMPLATE_OBJECTS) test_bin* *.o rose_*.C *.dot Templates.DB
Modified: branches/imperial/src/ROSETTA/Grammar/BinaryInstruction.code
===================================================================
--- branches/imperial/src/ROSETTA/Grammar/BinaryInstruction.code 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/Grammar/BinaryInstruction.code 2009-01-14 15:08:15 UTC (rev 189)
@@ -772,10 +772,10 @@
};
SgAsmGenericSection(SgAsmGenericFile *f, SgAsmGenericHeader *fhdr)
- : p_file(f), p_header(NULL), p_size(1), p_offset(f->get_current_size()), p_file_alignment(0),
- p_purpose(SP_UNSPECIFIED), p_synthesized(false), p_id(-1), p_name(0), p_mapped_rva(0), p_mapped_size(0),
- p_mapped_alignment(0), p_mapped_rperm(false), p_mapped_wperm(false), p_mapped_xperm(false),
- p_congealed(false)
+ : local_data_pool(0), p_file(f), p_header(NULL), p_size(1), p_offset(f->get_current_size()),
+ p_file_alignment(0), p_purpose(SP_UNSPECIFIED), p_synthesized(false), p_id(-1), p_name(0),
+ p_mapped_rva(0), p_mapped_size(0), p_mapped_alignment(0), p_mapped_rperm(false), p_mapped_wperm(false),
+ p_mapped_xperm(false), p_congealed(false)
{ctor(f, fhdr);}
// This destructor modifies the SgAsmGenericFile data to remove its section from the section list!
@@ -813,6 +813,7 @@
ExtentMap get_internal_holes() const; /* weak form of congeal() */
const ExtentMap& congeal(); /* congeal referenced areas into holes */
const ExtentMap& uncongeal(); /* uncongeal holes back into references */
+ unsigned char *local_content(size_t nbytes); /* obtain a local, writable pool to hold content */
/* Functions related to mapping of sections into executable memory */
bool is_mapped() const; /* True iff non-zero mapped address and size */
@@ -836,6 +837,14 @@
protected:
void ctor(SgAsmGenericFile*, SgAsmGenericHeader*);
+
+ private:
+ /* This is an optional local, writable pool for the p_data member. Normally a section will point into the pool
+ * for its SgAsmGenericFile which is memory-mapped (read-only) from the actual file being parsed. The default
+ * unparsing action is to write the original data back to the file. By allowing a section to allocate its own
+ * pool for p_data we create a very easy way to get data into the unparsed file (the alternative is to derive
+ * a new class and override the unparse() method). */
+ unsigned char *local_data_pool;
HEADER_GENERIC_SECTION_END
@@ -919,7 +928,7 @@
HEADER_GENERIC_FILE_START
public:
SgAsmGenericFile() /* Non-parsing constructor */
- : p_fd(-1), p_headers(NULL), p_holes(NULL)
+ : p_fd(-1), p_headers(NULL), p_holes(NULL), p_truncate_zeros(false)
{ctor();}
virtual ~SgAsmGenericFile(); /* Destructor deletes children and unmaps/closes file */
SgAsmGenericFile* parse(std::string file_name); /* Attach an existing file for parsing */
@@ -1001,27 +1010,8 @@
HEADER_GENERIC_FORMAT_START
- public:
-
-// typedef uint64_t addr_t; /* address and size (file and memory) */
-
-
-#if 0
- // This is automatically generated.
- SgAsmGenericFormat() :
- family(FAMILY_UNSPECIFIED),
- purpose(PURPOSE_UNSPECIFIED),
- sex(ORDER_UNSPECIFIED),
- version(0),
- is_current_version(false),
- abi(ABI_UNSPECIFIED),
- abi_version(0),
- word_size(4)
- {}
-#endif
-
- void dump(FILE*, const char *prefix, ssize_t idx) const;
-
+ public:
+ void dump(FILE*, const char *prefix, ssize_t idx) const;
HEADER_GENERIC_FORMAT_END
@@ -1254,10 +1244,15 @@
/* Non-parsing constructor */
explicit SgAsmElfFileHeader(SgAsmGenericFile *f)
- : SgAsmGenericHeader(f)
+ : SgAsmGenericHeader(f) , p_e_ident_file_class(0), p_e_ident_file_version(1), p_e_type(0),
+ p_e_machine(0), p_e_flags(0), p_e_ehsize(0), p_phextrasz(0), p_e_phnum(0), p_shextrasz(0),
+ p_e_shnum(0), p_e_shstrndx(0), p_section_table(NULL), p_segment_table(NULL)
{ctor();}
uint64_t max_page_size();
+ SgAsmExecutableFileFormat::InsSetArchitecture machine_to_isa(unsigned machine) const;
+ unsigned isa_to_machine(SgAsmExecutableFileFormat::InsSetArchitecture isa) const;
+
virtual SgAsmElfFileHeader *parse();
virtual bool reallocate();
virtual void unparse(std::ostream&) const;
@@ -1374,9 +1369,11 @@
SgAsmElfSection *init_from_segment_table(SgAsmElfSegmentTableEntry*, bool mmap_only=false);
rose_addr_t calculate_sizes(size_t r32size, size_t r64size, const std::vector<size_t> &optsizes,
size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const;
+ virtual void finish_parsing() {}
virtual rose_addr_t calculate_sizes(size_t *entsize, size_t *required, size_t *optional, size_t *entcount) const;
virtual bool reallocate();
virtual void dump(FILE*, const char *prefix, ssize_t idx) const;
+ void allocate_name_to_storage(SgAsmElfStringSection*);
/* Convenience functions */
SgAsmElfFileHeader *get_elf_header() const;
@@ -1519,7 +1516,7 @@
: SgAsmElfSection(fhdr)
{ctor(strsec);}
virtual SgAsmElfDynamicSection* parse();
- void finish_parsing();
+ virtual void finish_parsing();
using SgAsmElfSection::calculate_sizes;
virtual rose_addr_t calculate_sizes(size_t *total, size_t *required, size_t *optional, size_t *entcount) const;
virtual bool reallocate();
@@ -1749,7 +1746,7 @@
: SgAsmElfSection(fhdr), p_is_dynamic(false)
{ctor(strsec);}
virtual SgAsmElfSymbolSection* parse();
- void finish_parsing();
+ virtual void finish_parsing();
size_t index_of(SgAsmElfSymbol*);
using SgAsmElfSection::calculate_sizes;
virtual rose_addr_t calculate_sizes(size_t *total, size_t *required, size_t *optional, size_t *nentries) const;
Modified: branches/imperial/src/ROSETTA/Grammar/Expression.code
===================================================================
--- branches/imperial/src/ROSETTA/Grammar/Expression.code 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/Grammar/Expression.code 2009-01-14 15:08:15 UTC (rev 189)
@@ -2343,25 +2343,43 @@
// printf ("In SgFunctionCallExp::get_type(): calling get_type() on p_function = %p = %s \n",p_function,p_function->class_name().c_str());
SgType* likelyFunctionType = p_function->get_type();
ROSE_ASSERT(likelyFunctionType != NULL);
- while (likelyFunctionType && isSgTypedefType(likelyFunctionType)) {
- likelyFunctionType = isSgTypedefType(likelyFunctionType)->get_base_type();
- ROSE_ASSERT(likelyFunctionType != NULL);
- }
+ while (likelyFunctionType && isSgTypedefType(likelyFunctionType))
+ {
+ likelyFunctionType = isSgTypedefType(likelyFunctionType)->get_base_type();
+ ROSE_ASSERT(likelyFunctionType != NULL);
+ }
+
SgFunctionType* functionType = isSgFunctionType(likelyFunctionType);
if (functionType == NULL)
{
- // printf ("Error: unexpected type found for likelyFunctionType = %p = %s \n",likelyFunctionType,likelyFunctionType->class_name().c_str());
+ printf ("Error: unexpected type found for likelyFunctionType = %p = %s \n",likelyFunctionType,likelyFunctionType->class_name().c_str());
// get_file_info()->display("Location of call to SgFunctionCallExp::get_type(): debug");
// DQ (7/15/2007): Handle case of typedef of function type
likelyFunctionType = likelyFunctionType->stripType(SgType::STRIP_TYPEDEF_TYPE);
+ printf ("After calling stripType(SgType::STRIP_TYPEDEF_TYPE): likelyFunctionType = %p = %s \n",likelyFunctionType,likelyFunctionType->class_name().c_str());
+
functionType = isSgFunctionType(likelyFunctionType);
+
+#ifdef ROSE_USE_EDG_VERSION_4
+ // DQ (12/31/2008): EDG version 4.0 has a simpler representation which translates a bit differently.
+ // I think this is an improvement to this functionality of this function.
+ if (functionType == NULL)
+ returnType = likelyFunctionType;
+#else
ROSE_ASSERT(functionType != NULL);
+#endif
}
-
+
+#ifdef ROSE_USE_EDG_VERSION_4
+ // if not already set
+ if (returnType == NULL)
+ returnType = functionType->get_return_type();
+#else
ROSE_ASSERT(functionType != NULL);
returnType = functionType->get_return_type();
+#endif
ROSE_ASSERT(returnType != NULL);
return returnType;
@@ -2445,6 +2463,9 @@
SgType* returnType = NULL;
keepStripping:
+
+ // printf ("$CLASSNAME::get_type(): someType = %s \n",someType->class_name().c_str());
+
ROSE_ASSERT (someType != NULL);
switch(someType->variantT())
{
@@ -2488,11 +2509,17 @@
someType = modifierType->get_base_type();
goto keepStripping;
}
-
default:
{
+#ifdef ROSE_USE_EDG_VERSION_4
+ // DQ (12/31/2008): This appears to be the correct fix for EDG version 4.0,
+ // but it is unclear why this is not an issue for EDG 3.x previously.
+ // printf ("Using default case in $CLASSNAME::get_type() differently with EDG version 4.x someType = %s \n",someType->class_name().c_str());
+ returnType = someType;
+#else
printf ("Error: default reached in In $CLASSNAME::get_type() someType = %s \n",someType->class_name().c_str());
ROSE_ASSERT(false);
+#endif
}
}
@@ -2831,7 +2858,7 @@
// SgType* SgPointerDerefExp::get_type() const
SgType*
-$CLASSNAME::get_type() const
+SgPointerDerefExp::get_type() const
{
// DQ (1/14/2006): p_expression_type has been removed, we have to compute the appropriate type (IR specific code)
@@ -2899,12 +2926,21 @@
someType = modifierType->get_base_type();
goto keepStripping;
}
- // Liao (1/25/2008) SgTypeUnknown is used (abused ?) to specify a temporary InitializedName generated in translation when the corresponding variable declaration is not yet available. SageBuilder::fixVariableReferences() will fix this temporary inconsistence in AST after transformation is complete.
+
+// #ifndef ROSE_USE_EDG_VERSION_4
+#ifndef ROSE_USE_NEW_EDG_INTERFACE
+ // DQ (12/31/2008): This is the old behavior from EDG version 3.x (which I don't want to change since it is stable)
+ // Note also that calling the static creatType() function, is the same as returning "someType".
+
+ // Liao (1/25/2008) SgTypeUnknown is used (abused ?) to specify a temporary InitializedName generated
+ // in translation when the corresponding variable declaration is not yet available. SageBuilder::fixVariableReferences()
+ // will fix this temporary inconsistence in AST after transformation is complete.
case V_SgTypeUnknown:
{
returnType = SgTypeUnknown::createType();
break;
}
+
// DQ (6/18/2007): The dereference of a function type is a function call so the type is it's return type (I think)
case V_SgFunctionType:
{
@@ -2913,6 +2949,22 @@
returnType = functionType;
break;
}
+
+ // DQ (12/30/2008): Added case to support EDG 4.0 (see test2001_03.C)
+ case V_SgTypeString:
+ {
+ returnType = SgTypeString::createType();
+ break;
+ }
+
+ // DQ (12/30/2008): Added case to support EDG 4.0 (see test2001_03.C)
+ case V_SgTypeInt:
+ {
+ returnType = SgTypeInt::createType();
+ break;
+ }
+#endif
+
#if 0
// DQ (10/3/2006): I think this is no longer required, since we fixed the case of sizeof taking an
// expression (not required to be an lvalue)!
@@ -2927,8 +2979,11 @@
#endif
default:
{
+// #ifndef ROSE_USE_EDG_VERSION_4
+#ifndef ROSE_USE_NEW_EDG_INTERFACE
+ // DQ (12/31/2008): This is the old behavior from EDG version 3.x (which I don't want to change since it is stable)
#if 1
- printf ("Error: default reached in In $CLASSNAME::get_type() someType = %s \n",someType->class_name().c_str());
+ printf ("Error: default reached in In SgPointerDerefExp::get_type() someType = %s \n",someType->class_name().c_str());
get_file_info()->display("location of error: debug");
// DQ (9/27/2006): This can be a compiler generated IR nde so look at the parent.
@@ -2937,6 +2992,11 @@
locatedNode->get_file_info()->display("location of parent: debug");
#endif
ROSE_ASSERT(false);
+#else
+ // DQ (12/31/2008): This is the new behavior for EDG version 4.x.
+ printf ("Warning: default reached in In SgPointerDerefExp::get_type() someType = %s \n",someType->class_name().c_str());
+ returnType = someType;
+#endif
}
}
@@ -3297,6 +3357,7 @@
goto keepStripping;
}
+#ifndef ROSE_USE_NEW_EDG_INTERFACE
// DQ (10/3/2006): Added case of array reference of string type (assume it returns a char).
// Once we have a wcharString type then we have to add that case to this list as well!
case V_SgTypeString:
@@ -3328,6 +3389,13 @@
printf ("Error: default reached in In $CLASSNAME::get_type() someType = %s \n",someType->class_name().c_str());
ROSE_ASSERT(false);
}
+#else
+ // DQ (12/31/2008): This is a better fit for the new EDG/ROSE translation interface.
+ default:
+ {
+ returnType = someType;
+ }
+#endif
}
ROSE_ASSERT(returnType != NULL);
Modified: branches/imperial/src/ROSETTA/Grammar/Node.code
===================================================================
--- branches/imperial/src/ROSETTA/Grammar/Node.code 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/Grammar/Node.code 2009-01-14 15:08:15 UTC (rev 189)
@@ -243,7 +243,7 @@
// typedef Rose_STL_Container<char*> SgCharPtrList;
// typedef SgCharPtrList* SgCharPtrListPtr;
typedef Rose_STL_Container<unsigned char> SgCharList;
-typedef SgCharList* SgCharListPtr;
+typedef SgCharList* SgCharListPtr;
typedef SgExpression* SgExpressionPtr;
typedef SgStatement* SgStatementPtr;
@@ -451,7 +451,10 @@
typedef Rose_STL_Container<SgAsmDwarfCompilationUnit*> SgAsmDwarfCompilationUnitPtrList;
typedef SgAsmDwarfCompilationUnitPtrList* SgAsmDwarfCompilationUnitPtrListPtr;
+// DQ (11/28/2008): Added support for list of integers (used for flag list in SgLinemarkerDirectiveStatement).
+// typedef std::vector<int> SgIntegerList;
+
// FIXME: This might not the the right place for this class. (RPM 2008-08-26)
/* An SgSharedVector is like an STL vector except for two things:
*
Modified: branches/imperial/src/ROSETTA/Grammar/Statement.code
===================================================================
--- branches/imperial/src/ROSETTA/Grammar/Statement.code 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/Grammar/Statement.code 2009-01-14 15:08:15 UTC (rev 189)
@@ -2688,8 +2688,17 @@
// void post_construction_initialization();
static SgC_PreprocessorDirectiveStatement* createDirective ( PreprocessingInfo* currentPreprocessingInfo );
+
+ // DQ (11/29/2008): Added for uniform support of mangled names
+ virtual SgName get_mangled_name() const;
+
HEADER_PREPROCESSOR_DIRECTIVE_STATEMENT_END
+HEADER_LINEMARKER_PREPROCESSOR_DIRECTIVE_STATEMENT_START
+
+HEADER_LINEMARKER_PREPROCESSOR_DIRECTIVE_STATEMENT_END
+
+
// #########################################################
// #########################################################
// SOURCE CODE
@@ -3601,6 +3610,18 @@
{
assert (p_symbol_table != NULL);
+#if 0
+ ROSE_ASSERT(s != NULL);
+ SgNode* symbolBasis = s->get_symbol_basis();
+ // printf ("In SgScopeStatement::insert_symbol(%s,%p) into scope = %p = %s parent = %p = %s symbol = %p = %s s->get_symbol_basis() = %p = %s \n",
+ printf ("In SgScopeStatement::insert_symbol(%s,%p) into scope = %p = %s symbol = %p = %s s->get_symbol_basis() = %p = %s \n",
+ n.str(),s,
+ this,this->class_name().c_str(),
+ // this->get_parent(),this->get_parent()->class_name().c_str(),
+ s,s->class_name().c_str(),
+ symbolBasis,symbolBasis != NULL ? symbolBasis->class_name().c_str() : "NULL");
+#endif
+
// Make sure that this specific symbol and name combination don't already exist in the AST.
bool symbolAlreadyPresentLookupName = p_symbol_table->exists(n,s);
if (symbolAlreadyPresentLookupName == true)
@@ -13447,6 +13468,15 @@
{
}
+// DQ (11/29/2008): Added for uniform support of mangled names
+SgName SgC_PreprocessorDirectiveStatement::get_mangled_name() const
+ {
+ return "__c_language_preprocessor_directive__";
+ }
+
SOURCE_PREPROCESSOR_DIRECTIVE_STATEMENT_END
+SOURCE_LINEMARKER_PREPROCESSOR_DIRECTIVE_STATEMENT_START
+SOURCE_LINEMARKER_PREPROCESSOR_DIRECTIVE_STATEMENT_END
+
Modified: branches/imperial/src/ROSETTA/Grammar/Support.code
===================================================================
--- branches/imperial/src/ROSETTA/Grammar/Support.code 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/Grammar/Support.code 2009-01-14 15:08:15 UTC (rev 189)
@@ -520,7 +520,7 @@
Function modifiers (inline, virtual, pure-virtual, explicit).
- \internal Only one value can be specified (at least in C and C++)
+ \internal Many values can be specified (when the gnu attributes are included), so the implementation uses an STL bit vector.
*/
enum function_modifier_enum
{
@@ -538,7 +538,7 @@
e_recursive = 9, /*!< Fortran recursive attribute for functions (see also type modifier) */
// DQ (12/4/2007): Added support for GNU specific attributes
- e_gnu_attribute__constructor__ = 10,/*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__constructor__ = 10,/*!< GNU specific attribute for (GNU extension) (a separately stored value permits the priority to be specified). */
e_gnu_attribute__destructor__ = 11,/*!< GNU specific attribute for (GNU extension) */
e_gnu_attribute__pure__ = 12,/*!< GNU specific attribute for (GNU extension) */
e_gnu_attribute__weak__ = 13,/*!< GNU specific attribute for (GNU extension) */
@@ -549,6 +549,11 @@
e_gnu_attribute__naked__ = 18,/*!< GNU specific attribute for (GNU extension) */
e_gnu_attribute__no_instrument_function__ = 19,/*!< GNU specific attribute for (GNU extension) */
e_gnu_attribute__no_check_memory_usage__ = 20,/*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__noinline__ = 21,/*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__always_inline__ = 22,/*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__nothrow__ = 23,/*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__weakref__ = 24,/*!< GNU specific attribute for (GNU extension) */
+
e_last_modifier /*!< last value (upper bound on range of values, used in error checking) */
};
@@ -589,21 +594,82 @@
void setBind();
void unsetBind();
#endif
- // DQ (11/21/2007): support for Fortran bind attribute on functions
+ // DQ (11/21/2007): support for Fortran pure attribute on functions
bool isPure() const;
void setPure();
void unsetPure();
- // DQ (11/30/2007): support for Fortran bind attribute on functions
+ // DQ (11/30/2007): support for Fortran elemental attribute on functions
bool isElemental() const;
void setElemental();
void unsetElemental();
- // DQ (11/30/2007): support for Fortran bind attribute on functions
+ // DQ (11/30/2007): support for Fortran recursive attribute on functions
bool isRecursive() const;
void setRecursive();
void unsetRecursive();
+ // DQ (1/3/2009): Added GNU specific attributes
+ bool isGnuAttributeConstructor() const;
+ void setGnuAttributeConstructor();
+ void unsetGnuAttributeConstructor();
+
+ bool isGnuAttributeDestructor() const;
+ void setGnuAttributeDestructor();
+ void unsetGnuAttributeDestructor();
+
+ bool isGnuAttributePure() const;
+ void setGnuAttributePure();
+ void unsetGnuAttributePure();
+
+ bool isGnuAttributeWeak() const;
+ void setGnuAttributeWeak();
+ void unsetGnuAttributeWeak();
+
+ bool isGnuAttributeUnused() const;
+ void setGnuAttributeUnused();
+ void unsetGnuAttributeUnused();
+
+ bool isGnuAttributeUsed() const;
+ void setGnuAttributeUsed();
+ void unsetGnuAttributeUsed();
+
+ bool isGnuAttributeDeprecated() const;
+ void setGnuAttributeDeprecated();
+ void unsetGnuAttributeDeprecated();
+
+ bool isGnuAttributeMalloc() const;
+ void setGnuAttributeMalloc();
+ void unsetGnuAttributeMalloc();
+
+ bool isGnuAttributeNaked() const;
+ void setGnuAttributeNaked();
+ void unsetGnuAttributeNaked();
+
+ bool isGnuAttributeNoInstrumentFunction() const;
+ void setGnuAttributeNoInstrumentFunction();
+ void unsetGnuAttributeNoInstrumentFunction();
+
+ bool isGnuAttributeNoCheckMemoryUsage() const;
+ void setGnuAttributeNoCheckMemoryUsage();
+ void unsetGnuAttributeNoCheckMemoryUsage();
+
+ bool isGnuAttributeNoInline() const;
+ void setGnuAttributeNoInline();
+ void unsetGnuAttributeNoInline();
+
+ bool isGnuAttributeAlwaysInline() const;
+ void setGnuAttributeAlwaysInline();
+ void unsetGnuAttributeAlwaysInline();
+
+ bool isGnuAttributeNoThrow() const;
+ void setGnuAttributeNoThrow();
+ void unsetGnuAttributeNoThrow();
+
+ bool isGnuAttributeWeakReference() const;
+ void setGnuAttributeWeakReference();
+ void unsetGnuAttributeWeakReference();
+
std::string displayString() const;
void display ( std::string label ) const;
friend std::ostream & operator<< ( std::ostream & os, SgFunctionModifier & m );
@@ -760,6 +826,24 @@
e_last_modifier /*!< last modifier value (upper bound on range of values, used in error checking) */
};
+ /*! \brief GNU attribute for visability (only one value can be specified)
+
+ visability values are: default, hidden, protected or internal visibility.
+
+ \internal Only one value can be specified (at least in C and C++)
+ */
+ enum gnu_declaration_visability_enum
+ {
+ e_unknown_visibility = 0, /*!< Unknown value (error) */
+ e_error_visibility = 1, /*!< Error value (error) */
+ e_unspecified_visibility = 2, /*!< Unspecified visibility (not the default value) */
+ e_hidden_visibility = 3, /*!< hidden visibility */
+ e_protected_visibility = 4, /*!< protected visibility */
+ e_internal_visibility = 5, /*!< internal visibility (not clear if this is used, I don't think typedef is a modifier) */
+ e_default_visibility = 6, /*!< default visibility */
+ e_last_visibility_attribute /*!< last visibility attribute (upper bound on range of values, used in error checking) */
+ };
+
// Copy constructor
SgDeclarationModifier ( const SgDeclarationModifier & X );
@@ -878,6 +962,12 @@
e_gnu_attribute__cdecl__ = 22,/*!< GNU specific attribute for function type (GNU extension) */
e_gnu_attribute__stdcall__ = 23,/*!< GNU specific attribute for function type (GNU extension) */
+ // DQ (1/3/2009): New GNU attributes not previously supported in ROSE
+ e_gnu_attribute__warn_unused_result__ = 24,/*!< GNU specific attribute for function type (GNU extension) */
+ e_gnu_attribute__nonnull__ = 25,/*!< GNU specific attribute for function type (GNU extension) */
+ e_gnu_attribute__sentinel__ = 26,/*!< GNU specific attribute for function type (GNU extension) */
+
+ // Last attribute enum (used for internal bounds checking)
e_last_modifier /*!< last value (upper bound on range of values, used in error checking) */
};
@@ -1045,6 +1135,51 @@
void setValue();
void unsetValue();
+ // DQ (1/3/2009): Added GNU specific attributes
+ bool isGnuAttributeUnused() const;
+ void setGnuAttributeUnused();
+ void unsetGnuAttributeUnused();
+
+ bool isGnuAttributePacked() const;
+ void setGnuAttributePacked();
+ void unsetGnuAttributePacked();
+
+ bool isGnuAttributeDeprecated() const;
+ void setGnuAttributeDeprecated();
+ void unsetGnuAttributeDeprecated();
+
+ bool isGnuAttributeTransparentUnion() const;
+ void setGnuAttributeTransparentUnion();
+ void unsetGnuAttributeTransparentUnion();
+
+ bool isGnuAttributeNoReturn() const;
+ void setGnuAttributeNoReturn();
+ void unsetGnuAttributeNoReturn();
+
+ bool isGnuAttributeConst() const;
+ void setGnuAttributeConst();
+ void unsetGnuAttributeConst();
+
+ bool isGnuAttributeCdecl() const;
+ void setGnuAttributeCdecl();
+ void unsetGnuAttributeCdecl();
+
+ bool isGnuAttributeStdcall() const;
+ void setGnuAttributeStdcall();
+ void unsetGnuAttributeStdcall();
+
+ bool isGnuAttributeWarnUnusedResult() const;
+ void setGnuAttributeWarnUnusedResult();
+ void unsetGnuAttributeWarnUnusedResult();
+
+ bool isGnuAttributeNonnull() const;
+ void setGnuAttributeNonnull();
+ void unsetGnuAttributeNonnull();
+
+ bool isGnuAttributeSentinel() const;
+ void setGnuAttributeSentinel();
+ void unsetGnuAttributeSentinel();
+
std::string displayString() const;
void display ( std::string label ) const;
friend std::ostream & operator<< ( std::ostream & os, SgTypeModifier & m );
@@ -1447,21 +1582,21 @@
}
bool
-$CLASSNAME::checkBit ( unsigned int bit, const SgBitVector & bitVector ) const
+SgModifier::checkBit ( unsigned int bit, const SgBitVector & bitVector ) const
{
ROSE_ASSERT (bit < bitVector.size());
return bitVector[bit];
}
void
-$CLASSNAME::setBit ( unsigned int bit, SgBitVector & bitVector ) const
+SgModifier::setBit ( unsigned int bit, SgBitVector & bitVector ) const
{
ROSE_ASSERT (bit < bitVector.size());
bitVector[bit] = true;
}
void
-$CLASSNAME::unsetBit ( unsigned int bit, SgBitVector & bitVector ) const
+SgModifier::unsetBit ( unsigned int bit, SgBitVector & bitVector ) const
{
ROSE_ASSERT (bit < bitVector.size());
bitVector[bit] = false;
@@ -1869,7 +2004,84 @@
void SgFunctionModifier::setRecursive() { setBit(e_recursive,p_modifierVector); }
void SgFunctionModifier::unsetRecursive() { unsetBit(e_recursive,p_modifierVector); }
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeConstructor() const { return checkBit(e_gnu_attribute__constructor__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeConstructor() { setBit(e_gnu_attribute__constructor__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeConstructor() { unsetBit(e_gnu_attribute__constructor__,p_modifierVector); }
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeDestructor() const { return checkBit(e_gnu_attribute__destructor__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeDestructor() { setBit(e_gnu_attribute__destructor__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeDestructor() { unsetBit(e_gnu_attribute__destructor__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributePure() const { return checkBit(e_gnu_attribute__pure__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributePure() { setBit(e_gnu_attribute__pure__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributePure() { unsetBit(e_gnu_attribute__pure__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeWeak() const { return checkBit(e_gnu_attribute__weak__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeWeak() { setBit(e_gnu_attribute__weak__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeWeak() { unsetBit(e_gnu_attribute__weak__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeUnused() const { return checkBit(e_gnu_attribute__unused__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeUnused() { setBit(e_gnu_attribute__unused__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeUnused() { unsetBit(e_gnu_attribute__unused__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeUsed() const { return checkBit(e_gnu_attribute__used__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeUsed() { setBit(e_gnu_attribute__used__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeUsed() { unsetBit(e_gnu_attribute__used__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeDeprecated() const { return checkBit(e_gnu_attribute__deprecated__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeDeprecated() { setBit(e_gnu_attribute__deprecated__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeDeprecated() { unsetBit(e_gnu_attribute__deprecated__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeMalloc() const { return checkBit(e_gnu_attribute__malloc__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeMalloc() { setBit(e_gnu_attribute__malloc__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeMalloc() { unsetBit(e_gnu_attribute__malloc__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeNaked() const { return checkBit(e_gnu_attribute__naked__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeNaked() { setBit(e_gnu_attribute__naked__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeNaked() { unsetBit(e_gnu_attribute__naked__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeNoInstrumentFunction() const { return checkBit(e_gnu_attribute__no_instrument_function__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeNoInstrumentFunction() { setBit(e_gnu_attribute__no_instrument_function__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeNoInstrumentFunction() { unsetBit(e_gnu_attribute__no_instrument_function__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeNoCheckMemoryUsage() const { return checkBit(e_gnu_attribute__no_check_memory_usage__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeNoCheckMemoryUsage() { setBit(e_gnu_attribute__no_check_memory_usage__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeNoCheckMemoryUsage() { unsetBit(e_gnu_attribute__no_check_memory_usage__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeNoInline() const { return checkBit(e_gnu_attribute__noinline__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeNoInline() { setBit(e_gnu_attribute__noinline__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeNoInline() { unsetBit(e_gnu_attribute__noinline__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeAlwaysInline() const { return checkBit(e_gnu_attribute__always_inline__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeAlwaysInline() { setBit(e_gnu_attribute__always_inline__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeAlwaysInline() { unsetBit(e_gnu_attribute__always_inline__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeNoThrow() const { return checkBit(e_gnu_attribute__nothrow__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeNoThrow() { setBit(e_gnu_attribute__nothrow__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeNoThrow() { unsetBit(e_gnu_attribute__nothrow__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgFunctionModifier::isGnuAttributeWeakReference() const { return checkBit(e_gnu_attribute__weakref__,p_modifierVector); }
+void SgFunctionModifier::setGnuAttributeWeakReference() { setBit(e_gnu_attribute__weakref__,p_modifierVector); }
+void SgFunctionModifier::unsetGnuAttributeWeakReference() { unsetBit(e_gnu_attribute__weakref__,p_modifierVector); }
+
+
+
+
std::ostream & operator<< ( std::ostream & os, SgFunctionModifier & m)
{
os << m.get_modifierVector();
@@ -2382,7 +2594,62 @@
void SgTypeModifier::setValue() { setBit(e_value,p_modifierVector); }
void SgTypeModifier::unsetValue() { unsetBit(e_value,p_modifierVector); }
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeUnused() const { return checkBit(e_gnu_attribute__unused__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeUnused() { setBit(e_gnu_attribute__unused__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeUnused() { unsetBit(e_gnu_attribute__unused__,p_modifierVector); }
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributePacked() const { return checkBit(e_gnu_attribute__packed__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributePacked() { setBit(e_gnu_attribute__packed__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributePacked() { unsetBit(e_gnu_attribute__packed__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeDeprecated() const { return checkBit(e_gnu_attribute__deprecated__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeDeprecated() { setBit(e_gnu_attribute__deprecated__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeDeprecated() { unsetBit(e_gnu_attribute__deprecated__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeTransparentUnion() const { return checkBit(e_gnu_attribute__transparent_union__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeTransparentUnion() { setBit(e_gnu_attribute__transparent_union__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeTransparentUnion() { unsetBit(e_gnu_attribute__transparent_union__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeNoReturn() const { return checkBit(e_gnu_attribute__noreturn__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeNoReturn() { setBit(e_gnu_attribute__noreturn__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeNoReturn() { unsetBit(e_gnu_attribute__noreturn__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeConst() const { return checkBit(e_gnu_attribute__const__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeConst() { setBit(e_gnu_attribute__const__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeConst() { unsetBit(e_gnu_attribute__const__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeCdecl() const { return checkBit(e_gnu_attribute__cdecl__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeCdecl() { setBit(e_gnu_attribute__cdecl__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeCdecl() { unsetBit(e_gnu_attribute__cdecl__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeStdcall() const { return checkBit(e_gnu_attribute__stdcall__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeStdcall() { setBit(e_gnu_attribute__stdcall__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeStdcall() { unsetBit(e_gnu_attribute__stdcall__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeWarnUnusedResult() const { return checkBit(e_gnu_attribute__warn_unused_result__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeWarnUnusedResult() { setBit(e_gnu_attribute__warn_unused_result__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeWarnUnusedResult() { unsetBit(e_gnu_attribute__warn_unused_result__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeNonnull() const { return checkBit(e_gnu_attribute__nonnull__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeNonnull() { setBit(e_gnu_attribute__nonnull__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeNonnull() { unsetBit(e_gnu_attribute__nonnull__,p_modifierVector); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgTypeModifier::isGnuAttributeSentinel() const { return checkBit(e_gnu_attribute__sentinel__,p_modifierVector); }
+void SgTypeModifier::setGnuAttributeSentinel() { setBit(e_gnu_attribute__sentinel__,p_modifierVector); }
+void SgTypeModifier::unsetGnuAttributeSentinel() { unsetBit(e_gnu_attribute__sentinel__,p_modifierVector); }
+
+
std::ostream& operator<< (std::ostream& os, SgTypeModifier& tm)
{
os << tm.get_modifierVector();
@@ -3120,9 +3387,57 @@
e_last_register
};
+ // DQ (1/3/2009): This might imply that we need a variable modifier (SgVariableModifier
+ // (as a new IR node, but for now implement these directly since they are GNU specific
+ // attributes (extensions)).
+ enum gnu_variable_attribute_enum
+ {
+ // DQ (12/4/2007): Added support for GNU specific attributes
+ e_gnu_attribute__weak__ = 0, /*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__unused__ = 1, /*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__used__ = 2, /*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__deprecated__ = 3, /*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__nocommon__ = 4, /*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__transparent_union__ = 5, /*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__weakref__ = 6,/*!< GNU specific attribute for (GNU extension) */
+ e_gnu_attribute__packed__ = 6,/*!< GNU specific attribute for (GNU extension) */
+ e_last_gnu_variable_attribute /*!< last value (upper bound on range of values, used in error checking) */
+ };
+ bool checkBit ( unsigned int bit ) const;
+ void setBit ( unsigned int bit );
+ void unsetBit ( unsigned int bit );
+
+ bool isGnuAttributeWeak() const;
+ void setGnuAttributeWeak();
+ void unsetGnuAttributeWeak();
+
+ bool isGnuAttributeUnused() const;
+ void setGnuAttributeUnused();
+ void unsetGnuAttributeUnused();
+
+ bool isGnuAttributeUsed() const;
+ void setGnuAttributeUsed();
+ void unsetGnuAttributeUsed();
+
+ bool isGnuAttributeDeprecated() const;
+ void setGnuAttributeDeprecated();
+ void unsetGnuAttributeDeprecated();
+
+ bool isGnuAttributeNoCommon() const;
+ void setGnuAttributeNoCommon();
+ void unsetGnuAttributeNoCommon();
+
+ bool isGnuAttributeTransparentUnion() const;
+ void setGnuAttributeTransparentUnion();
+ void unsetGnuAttributeTransparentUnion();
+
+ bool isGnuAttributeWeakReference() const;
+ void setGnuAttributeWeakReference();
+ void unsetGnuAttributeWeakReference();
+
void post_construction_initialization();
- // Overriding SgNode versions of these
+ // Overriding SgNode versions of these
virtual unsigned int cfgIndexForEnd() const;
virtual bool cfgIsIndexInteresting(unsigned int index) const;
virtual unsigned int cfgFindChildIndex(SgNode* n);
@@ -3130,7 +3445,6 @@
virtual std::vector<VirtualCFG::CFGEdge> cfgOutEdges(unsigned int index);
virtual std::vector<VirtualCFG::CFGEdge> cfgInEdges(unsigned int index);
-
SgStorageModifier & get_storageModifier();
// These are automatically generated! (not an option currently)
@@ -3890,6 +4204,10 @@
//! Access function calling set_startOfConstruct(), provided to support older interface.
void set_file_info( Sg_File_Info* fileinfo );
+ // DQ (12/23/2008): This sets up the Sg_File_Info in the SgFile and initializes it with the correct name etc.
+ // This function is called at several locations to build SgSourceFiles of different types (languages).
+ void initializeSourcePosition( const std::string & sourceFilename );
+
#if 0
// DQ (9/5/2008): Moved to SgSourceFile
#if ALT_FIXUP_COPY
@@ -3926,9 +4244,16 @@
int build_PHP_AST();
virtual void doSetupForConstructor(const std::vector<std::string>& argv, SgProject* project);
+ // DQ (12/19/2008): Added support for translation source position information using CPP linemarkers.
+ void processCppLinemarkers();
+
// DQ (9/5/2008): Support for older name of the SgGlobal in SgSourceFile
// SgGlobal* get_root() const;
+ // DQ (12/23/2008): This sets up the Sg_File_Info in the SgFile and initializes it with the correct name etc.
+ // This should be the only place where the SgGlobal (global scope object) is built.
+ void initializeGlobalScope();
+
#if ALT_FIXUP_COPY
// DQ (11/7/2007): These need to be called separately (see documentation)
virtual void fixupCopy_scopes (SgNode* copy, SgCopyHelp & help) const;
@@ -4359,6 +4684,7 @@
private:
+ // DQ (1/3/2009): This is similar code to what is in SgModifier::checkBit, setBit, unsetBit; so it could be refactored.
int checkBit(unparse_type_num bit) const;
void setBit(unparse_type_num bit);
void unsetBit(unparse_type_num bit);
@@ -5229,13 +5555,17 @@
ROSE_ASSERT(p_table != NULL);
ROSE_ASSERT(statement != NULL);
- // printf ("Inside of SgSymbolTable::find( const SgStatement* ): statement = %p = %s = %s \n",statement,statement->class_name().c_str(),SageInterface::get_name(statement).c_str());
+#if 0
+ printf ("Inside of SgSymbolTable::find( const SgStatement* ): statement = %p = %s = %s \n",statement,statement->class_name().c_str(),SageInterface::get_name(statement).c_str());
+#endif
SgSymbol* returnSymbol = NULL;
SgName name = get_name(statement);
- // printf ("Inside of SgSymbolTable::find( const SgStatement* ): name = %s \n",name.str());
+#if 0
+ printf ("Inside of SgSymbolTable::find( const SgStatement* ): name = %s \n",name.str());
+#endif
// Get a quick pointer into the symbol table using the name (log n complexity)
p_iterator = p_table->find(name);
@@ -5260,25 +5590,33 @@
if (symbolBasis->variantT() == statement->variantT())
{
- // printf ("matching variants \n");
+#if 0
+ printf ("matching variants \n");
+#endif
returnSymbol = p_iterator->second;
- // This is a very presice test which might be a problem because of defining and non-defining versions
+ // This is a very precise test which might be a problem because of defining and non-defining versions
// of declarations (we might be able to always use the non-defining declaration in these cases. The
// switch which computes the names could normalize this aspect.
if (returnSymbol->get_symbol_basis() == statement)
{
- // printf ("returnSymbol->get_symbol_basis() == statement returnSymbol = %p = %s \n",returnSymbol,returnSymbol->class_name().c_str());
+#if 0
+ printf ("returnSymbol->get_symbol_basis() == statement returnSymbol = %p = %s \n",returnSymbol,returnSymbol->class_name().c_str());
+#endif
return returnSymbol;
}
else
{
- // printf ("returnSymbol->get_symbol_basis() != statement \n");
+#if 0
+ printf ("returnSymbol->get_symbol_basis() != statement \n");
+#endif
}
}
else
{
- // printf ("Some other symbol was found (no matching variants) \n");
+#if 0
+ printf ("Some other symbol was found (no matching variants) \n");
+#endif
}
p_iterator++;
@@ -6997,7 +7335,7 @@
}
}
- // Increment the symbol table's symble iterator
+ // Increment the symbol table's symbol iterator
i++;
// Increment the symbol counter (used for output)
@@ -7264,6 +7602,14 @@
// printf ("In SgInitializedName::post_construction_initialization(): resetting parent of valid initializer (p_initptr = %p) \n",p_initptr);
p_initptr->set_parent(this);
}
+
+ // DQ (1/3/2009): Added support for GNU variable attributes (std::strings will default to null, so they are not setup).
+ p_gnu_attribute_modifierVector = SgBitVector(e_last_gnu_variable_attribute,false);
+ p_gnu_attribute_initialization_priority = 0;
+ p_gnu_attribute_alignment = 0;
+
+ // Borrow the enum definition (and default value from SgDeclarationModifier).
+ p_gnu_attribute_visability = SgDeclarationModifier::e_unknown_visibility;
}
// This constructor is specific to the creation of SgInitializedName objects used as initializers
@@ -7390,6 +7736,12 @@
// DQ (10/10/2007): Added support for initialization of this data member (reported as uninitialized by valgrind).
p_requiresGlobalNameQualificationOnType = ptr.p_requiresGlobalNameQualificationOnType;
+
+ // DQ (1/3/2009): Added support for GNU variable attribues
+ p_gnu_attribute_modifierVector = ptr.p_gnu_attribute_modifierVector;
+ p_gnu_attribute_initialization_priority = ptr.p_gnu_attribute_initialization_priority;
+ p_gnu_attribute_alignment = ptr.p_gnu_attribute_alignment;
+ p_gnu_attribute_visability = ptr.p_gnu_attribute_visability;
}
SgInitializedName&
@@ -7468,6 +7820,12 @@
// DQ (10/10/2007): Added support for initialization of this data member (reported as uninitialized by valgrind).
p_requiresGlobalNameQualificationOnType = ptr.p_requiresGlobalNameQualificationOnType;
+
+ // DQ (1/3/2009): Added support for GNU variable attribues
+ p_gnu_attribute_modifierVector = ptr.p_gnu_attribute_modifierVector;
+ p_gnu_attribute_initialization_priority = ptr.p_gnu_attribute_initialization_priority;
+ p_gnu_attribute_alignment = ptr.p_gnu_attribute_alignment;
+ p_gnu_attribute_visability = ptr.p_gnu_attribute_visability;
}
else
{
@@ -7808,8 +8166,63 @@
set_declptr(def);
}
+bool
+SgInitializedName::checkBit ( unsigned int bit ) const
+ {
+ ROSE_ASSERT (bit < e_last_gnu_variable_attribute);
+ return p_gnu_attribute_modifierVector[bit];
+ }
+void
+SgInitializedName::setBit ( unsigned int bit )
+ {
+ ROSE_ASSERT (bit < e_last_gnu_variable_attribute);
+ p_gnu_attribute_modifierVector[bit] = true;
+ }
+void
+SgInitializedName::unsetBit ( unsigned int bit )
+ {
+ ROSE_ASSERT (bit < e_last_gnu_variable_attribute);
+ p_gnu_attribute_modifierVector[bit] = false;
+ }
+
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeWeak() const { return checkBit(e_gnu_attribute__weak__); }
+void SgInitializedName::setGnuAttributeWeak() { setBit(e_gnu_attribute__weak__); }
+void SgInitializedName::unsetGnuAttributeWeak() { unsetBit(e_gnu_attribute__weak__); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeUnused() const { return checkBit(e_gnu_attribute__unused__); }
+void SgInitializedName::setGnuAttributeUnused() { setBit(e_gnu_attribute__unused__); }
+void SgInitializedName::unsetGnuAttributeUnused() { unsetBit(e_gnu_attribute__unused__); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeUsed() const { return checkBit(e_gnu_attribute__used__); }
+void SgInitializedName::setGnuAttributeUsed() { setBit(e_gnu_attribute__used__); }
+void SgInitializedName::unsetGnuAttributeUsed() { unsetBit(e_gnu_attribute__used__); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeDeprecated() const { return checkBit(e_gnu_attribute__deprecated__); }
+void SgInitializedName::setGnuAttributeDeprecated() { setBit(e_gnu_attribute__deprecated__); }
+void SgInitializedName::unsetGnuAttributeDeprecated() { unsetBit(e_gnu_attribute__deprecated__); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeNoCommon() const { return checkBit(e_gnu_attribute__nocommon__); }
+void SgInitializedName::setGnuAttributeNoCommon() { setBit(e_gnu_attribute__nocommon__); }
+void SgInitializedName::unsetGnuAttributeNoCommon() { unsetBit(e_gnu_attribute__nocommon__); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeTransparentUnion() const { return checkBit(e_gnu_attribute__transparent_union__); }
+void SgInitializedName::setGnuAttributeTransparentUnion() { setBit(e_gnu_attribute__transparent_union__); }
+void SgInitializedName::unsetGnuAttributeTransparentUnion() { unsetBit(e_gnu_attribute__transparent_union__); }
+
+// DQ (1/3/2009): Added GNU specific attributes
+bool SgInitializedName::isGnuAttributeWeakReference() const { return checkBit(e_gnu_attribute__weakref__); }
+void SgInitializedName::setGnuAttributeWeakReference() { setBit(e_gnu_attribute__weakref__); }
+void SgInitializedName::unsetGnuAttributeWeakReference() { unsetBit(e_gnu_attribute__weakref__); }
+
SOURCE_INITIALIZED_NAME_END
@@ -9571,6 +9984,9 @@
// enforce that the filename is always an absolute path (starting with "/").
// Sg_File_Info* fileInfo = new Sg_File_Info("SgFile::SgFile",0,0);
// Sg_File_Info* fileInfo = new Sg_File_Info("",0,0);
+
+#if 0
+ // DQ (12/23/2008): Build this later when we have a valid filename.
Sg_File_Info* fileInfo = new Sg_File_Info("",1,1);
ROSE_ASSERT(fileInfo != NULL);
@@ -9579,6 +9995,7 @@
fileInfo->set_parent(this);
ROSE_ASSERT(get_startOfConstruct() != NULL);
ROSE_ASSERT(get_file_info() != NULL);
+#endif
// DQ (9/4/2008): This is now part of the SgSourceFile
// ROSE_ASSERT (p_root == NULL);
@@ -9586,7 +10003,9 @@
// DQ (9/2/2008): This is moved to the new SgBinaryFile (derived from SgFile)
// ROSE_ASSERT (p_binaryFile == NULL);
-#if 1
+#if 0
+ // DQ (12/23/2008): Build this later when we have a valid filename.
+
// DQ (9/5/2008): This part needs to be rewritten, this is temporary code!
SgSourceFile* sourceFile = const_cast<SgSourceFile*>(isSgSourceFile(this));
if (sourceFile != NULL)
@@ -9597,6 +10016,8 @@
Sg_File_Info* globalScopeFileInfo = new Sg_File_Info("",0,0);
ROSE_ASSERT (globalScopeFileInfo != NULL);
+ printf ("@@@@@@@@ In SgFile::initialization(): Building SgGlobal (with empty filename) @@@@@@@@@ \n");
+
sourceFile->set_globalScope( new SgGlobal( globalScopeFileInfo ) );
ROSE_ASSERT (sourceFile->get_globalScope() != NULL);
@@ -9882,9 +10303,10 @@
// in the generation of DOT files. This is helpful for debugging and in
// tutorial examples/presentations.
p_visualize_executable_file_format_skip_symbols = false;
- p_visualize_dwarf_only = false;
- p_read_instructions_only = false;
+ p_visualize_dwarf_only = false;
+ p_skip_unparse_asm_commands = false;
+ p_read_instructions_only = false;
// DQ (9/2/2008): This is moved to the new SgBinaryFile (derived from SgFile)
// p_aggressive = false;
@@ -10976,6 +11398,12 @@
printf (" p_excludeFileList.size() = %zu \n", p_excludeFileList.size());
printf (" p_excludeFileList = \n %s \n",StringUtility::listToString(p_excludeFileList).c_str());
+ printf (" p_preincludeFileList.size() = %zu \n", p_preincludeFileList.size());
+ printf (" p_preincludeFileList = \n %s \n",StringUtility::listToString(p_preincludeFileList).c_str());
+
+ printf (" p_preincludeDirectoryList.size() = %zu \n", p_preincludeDirectoryList.size());
+ printf (" p_preincludeDirectoryList = \n %s \n",StringUtility::listToString(p_preincludeDirectoryList).c_str());
+
printf ("In this project: numberOfFiles() = %d \n",numberOfFiles());
for (int i = 0; i < numberOfFiles(); i++)
{
Modified: branches/imperial/src/ROSETTA/Grammar/Type.code
===================================================================
--- branches/imperial/src/ROSETTA/Grammar/Type.code 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/Grammar/Type.code 2009-01-14 15:08:15 UTC (rev 189)
@@ -2813,7 +2813,7 @@
SOURCE_MEMBER_FUNCTION_TYPE_START
-$CLASSNAME::$CLASSNAME ( SgPartialFunctionType* ft )
+SgMemberFunctionType::SgMemberFunctionType ( SgPartialFunctionType* ft )
: SgFunctionType(ft)
{
p_struct_name = ft->p_struct_name;
@@ -2821,7 +2821,7 @@
}
void
-$CLASSNAME::post_construction_initialization()
+SgMemberFunctionType::post_construction_initialization()
{
p_struct_name=0;
p_mfunc_specifier = 0;
@@ -2831,39 +2831,39 @@
// RV (2/1/2006): Made a 'const' member function.
int
-$CLASSNAME::isConstFunc() const
+SgMemberFunctionType::isConstFunc() const
{ return (p_mfunc_specifier & e_const); }
void
-$CLASSNAME::setConstFunc()
+SgMemberFunctionType::setConstFunc()
{ p_mfunc_specifier |= e_const; }
void
-$CLASSNAME::unsetConstFunc()
+SgMemberFunctionType::unsetConstFunc()
{ p_mfunc_specifier &= ~e_const; }
-// RV (2/1/2006): Made a 'const' member function.
+// RV (2/1/2006): Made a 'volatile' member function.
int
-$CLASSNAME::isVolatileFunc() const
+SgMemberFunctionType::isVolatileFunc() const
{ return (p_mfunc_specifier & e_volatile); }
void
-$CLASSNAME::setVolatileFunc()
+SgMemberFunctionType::setVolatileFunc()
{ p_mfunc_specifier |= e_volatile; }
void
-$CLASSNAME::unsetVolatileFunc()
+SgMemberFunctionType::unsetVolatileFunc()
{ p_mfunc_specifier &= ~e_volatile; }
SgName
-$CLASSNAME::get_mangled_name (void) const
+SgMemberFunctionType::get_mangled_name (void) const
{
return get_mangled ();
}
// RV (1/31/2006): Changed form of mangling to include begin/end tags.
SgName
-$CLASSNAME::get_mangled (void) const
+SgMemberFunctionType::get_mangled (void) const
{
// Member-function specific information (class name, const/volatile qualifiers)
SgName mangled_cls_tag;
@@ -2898,7 +2898,7 @@
#if 0
SgName
-$CLASSNAME::get_mangled_type()
+SgMemberFunctionType::get_mangled_type()
{
SgUnparse_Info info;
@@ -2917,7 +2917,7 @@
//! This function repreents the name mangleing support for unparsing
SgName
-$CLASSNAME::get_mangled_name(SgUnparse_Info& info)
+SgMemberFunctionType::get_mangled_name(SgUnparse_Info& info)
{
SgName rtmp;
// SgDeclarationStatement *dstmt = info.get_decl_stmt();
@@ -3114,7 +3114,7 @@
mangle a complete function declaration with name and class name
*/
SgName
-$CLASSNAME::get_mangled(SgUnparse_Info & info)
+SgMemberFunctionType::get_mangled(SgUnparse_Info & info)
{
SgName tmp;
@@ -3198,7 +3198,7 @@
// SgMemberFunctionType * mkAnotherType(SgType *);
SgMemberFunctionType *
-$CLASSNAME::mkAnotherType(SgType *rtype)
+SgMemberFunctionType::mkAnotherType(SgType *rtype)
{
if (rtype == get_return_type())
return NULL;
@@ -3229,7 +3229,7 @@
SOURCE_PARTIAL_FUNCTION_TYPE_START
//! This is an empty function (no data to initialize)
void
-$CLASSNAME::post_construction_initialization ()
+SgPartialFunctionType::post_construction_initialization ()
{
}
@@ -3468,7 +3468,7 @@
// shared. During function creation. As a result we don't have to call the functions to mangle
// the names of things (which traverse parents to compute scopes and can be a problem if called
// before the parents are set, done in post processing of AST). However, this design requires
- // that the funtion type symbol table be constructed after the AST is build (and parent pointers
+ // that the funtion type symbol table be constructed after the AST is built (and parent pointers
// are set). If functions are created then the function type table must also be updated.
SgFunctionType* theType = new SgFunctionType(ft);
Modified: branches/imperial/src/ROSETTA/astNodeList
===================================================================
--- branches/imperial/src/ROSETTA/astNodeList 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/astNodeList 2009-01-14 15:08:15 UTC (rev 189)
@@ -584,7 +584,13 @@
SgAsmDwarfUnknownConstruct
SgAsmDwarfConstructList
SgAsmDwarfCompilationUnitList
+<<<<<<< .mine
+SgIncludeNextDirectiveStatement
+SgIdentDirectiveStatement
+SgLinemarkerDirectiveStatement
+=======
SgTypeSignedLongLong
SgRealPartOp
SgImagPartOp
SgConjugateOp
+>>>>>>> .r3782
Modified: branches/imperial/src/ROSETTA/src/binaryInstruction.C
===================================================================
--- branches/imperial/src/ROSETTA/src/binaryInstruction.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/src/binaryInstruction.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -469,19 +469,18 @@
// DQ (8/28/2008): Ask Thomas if we should change "unsigned int" to "addr_t"
AsmBlock.setDataPrototype("rose_addr_t","id","= 0",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE, COPY_DATA);
-
- AsmOperandList.setFunctionPrototype ( "HEADER_BINARY_OPERAND_LIST", "../Grammar/BinaryInstruction.code");
- AsmOperandList.setDataPrototype("SgAsmExpressionPtrList","operands","",
- NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, DEF_TRAVERSAL, NO_DELETE);
-
AsmBlock.setDataPrototype("SgAsmStatementPtrList","statementList","",
NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, DEF_TRAVERSAL, NO_DELETE);
-
AsmBlock.setDataPrototype("bool","externallyVisible","= true", // Can this block be called into from random code?
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ AsmOperandList.setFunctionPrototype ( "HEADER_BINARY_OPERAND_LIST", "../Grammar/BinaryInstruction.code");
+ AsmOperandList.setDataPrototype("SgAsmExpressionPtrList","operands","",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, DEF_TRAVERSAL, NO_DELETE);
+
+
AsmFile.setFunctionPrototype ( "HEADER_BINARY_FILE", "../Grammar/BinaryInstruction.code");
// This is the filename of the binary executable...
@@ -1690,7 +1689,7 @@
AsmGenericFile.setDataPrototype("SgAsmGenericSectionList*", "holes", "= NULL",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, DEF_TRAVERSAL, NO_DELETE);
AsmGenericFile.setDataPrototype("bool", "truncate_zeros", "= false",
- NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ NO_CONSTRUCTOR_PARAMETER, BUILD_FLAG_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
// This data structure represents the ExecFile from file: ExecGeneric.h
@@ -1707,7 +1706,7 @@
AsmGenericFormat.setDataPrototype("SgAsmGenericFormat::ExecFamily","family","= SgAsmGenericFormat::FAMILY_UNSPECIFIED",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
/* executable, library, etc. */
- AsmGenericFormat.setDataPrototype("SgAsmGenericFormat::ExecPurpose","purpose","= SgAsmGenericFormat::PURPOSE_UNSPECIFIED",
+ AsmGenericFormat.setDataPrototype("SgAsmGenericFormat::ExecPurpose","purpose","= SgAsmGenericFormat::PURPOSE_EXECUTABLE",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
/* No comment available */
AsmGenericFormat.setDataPrototype("SgAsmGenericFormat::ByteOrder","sex","= SgAsmGenericFormat::ORDER_UNSPECIFIED",
Modified: branches/imperial/src/ROSETTA/src/buildStorageClasses.C
===================================================================
--- branches/imperial/src/ROSETTA/src/buildStorageClasses.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/src/buildStorageClasses.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -702,6 +702,7 @@
( varTypeString == "SgUPC_AccessModifier::upc_access_modifier_enum" ) ||
( varTypeString == "SgElaboratedTypeModifier::elaborated_type_modifier_enum" ) ||
( varTypeString == "SgDeclarationStatement::template_specialization_enum" ) ||
+ ( varTypeString == "SgDeclarationModifier::gnu_declaration_visability_enum" ) ||
( varTypeString == "SgTemplateDeclaration::template_type_enum" ) ||
( varTypeString == "SgBaseClassModifier::baseclass_modifier_enum" ) ||
( varTypeString == "SgLinkageModifier::linkage_modifier_enum" ) ||
Modified: branches/imperial/src/ROSETTA/src/expression.C
===================================================================
--- branches/imperial/src/ROSETTA/src/expression.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/src/expression.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1264,7 +1264,18 @@
AsmOp.setDataPrototype ( "SgExpression*", "expression", "= NULL",
CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, DEF_TRAVERSAL, DEF_DELETE);
+ // DQ (1/8/2009): Added support for asm operand handling with EDG RECORD_RAW_ASM_OPERAND_DESCRIPTIONS == TRUE
+ // This allows us to handle "asm" statements that reference non-x86 specific details (registers and instructions).
+ AsmOp.setDataPrototype ( "bool", "recordRawAsmOperandDescriptions", "= false",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ AsmOp.setDataPrototype ( "bool", "isOutputOperand", "= false",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ AsmOp.setDataPrototype ( "std::string", "constraintString", "= \"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ AsmOp.setDataPrototype ( "std::string", "name", "= \"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
#if USE_FORTRAN_IR_NODES
// DQ (11/24/2007): Removed this IR node
// DQ (3/20/2007): Support for Fortran IR nodes.
Modified: branches/imperial/src/ROSETTA/src/statement.C
===================================================================
--- branches/imperial/src/ROSETTA/src/statement.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/src/statement.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -293,26 +293,34 @@
#endif
// DQ (8/17/2007): Added CPP directives back into the IR to better support analysis and transformations.
- NEW_TERMINAL_MACRO (IncludeDirectiveStatement, "IncludeDirectiveStatement", "INCLUDE_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (DefineDirectiveStatement, "DefineDirectiveStatement", "DEFINE_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (UndefDirectiveStatement, "UndefDirectiveStatement", "UNDEF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (IfdefDirectiveStatement, "IfdefDirectiveStatement", "IFDEF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (IfndefDirectiveStatement, "IfndefDirectiveStatement", "IFNDEF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (IfDirectiveStatement, "IfDirectiveStatement", "IF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (DeadIfDirectiveStatement, "DeadIfDirectiveStatement", "DEAD_IF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (ElseDirectiveStatement, "ElseDirectiveStatement", "ELSE_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (ElseifDirectiveStatement, "ElseifDirectiveStatement", "ELSEIF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (EndifDirectiveStatement, "EndifDirectiveStatement", "ENDIF_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (LineDirectiveStatement, "LineDirectiveStatement", "LINE_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (WarningDirectiveStatement, "WarningDirectiveStatement", "WARNING_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (ErrorDirectiveStatement, "ErrorDirectiveStatement", "ERROR_DIRECTIVE_STMT" );
- NEW_TERMINAL_MACRO (EmptyDirectiveStatement, "EmptyDirectiveStatement", "EMPTY_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (IncludeDirectiveStatement, "IncludeDirectiveStatement", "INCLUDE_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (DefineDirectiveStatement, "DefineDirectiveStatement", "DEFINE_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (UndefDirectiveStatement, "UndefDirectiveStatement", "UNDEF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (IfdefDirectiveStatement, "IfdefDirectiveStatement", "IFDEF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (IfndefDirectiveStatement, "IfndefDirectiveStatement", "IFNDEF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (IfDirectiveStatement, "IfDirectiveStatement", "IF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (DeadIfDirectiveStatement, "DeadIfDirectiveStatement", "DEAD_IF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (ElseDirectiveStatement, "ElseDirectiveStatement", "ELSE_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (ElseifDirectiveStatement, "ElseifDirectiveStatement", "ELSEIF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (EndifDirectiveStatement, "EndifDirectiveStatement", "ENDIF_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (LineDirectiveStatement, "LineDirectiveStatement", "LINE_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (WarningDirectiveStatement, "WarningDirectiveStatement", "WARNING_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (ErrorDirectiveStatement, "ErrorDirectiveStatement", "ERROR_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (EmptyDirectiveStatement, "EmptyDirectiveStatement", "EMPTY_DIRECTIVE_STMT" );
+ // DQ (11/28/2008): Added new IR nodes.
+ NEW_TERMINAL_MACRO (IncludeNextDirectiveStatement, "IncludeNextDirectiveStatement", "INCLUDE_NEXT_DIRECTIVE_STMT" );
+ NEW_TERMINAL_MACRO (IdentDirectiveStatement, "IdentDirectiveStatement", "IDENT_DIRECTIVE_STMT" );
+
+ // Note that this IR nodes is critical to Fortran support for CPP processed generated code.
+ NEW_TERMINAL_MACRO (LinemarkerDirectiveStatement, "LinemarkerDirectiveStatement", "LINEMARKER_DIRECTIVE_STMT" );
+
NEW_NONTERMINAL_MACRO (C_PreprocessorDirectiveStatement,
- IncludeDirectiveStatement | DefineDirectiveStatement | UndefDirectiveStatement |
- IfdefDirectiveStatement | IfndefDirectiveStatement | IfDirectiveStatement | DeadIfDirectiveStatement |
- ElseDirectiveStatement | ElseifDirectiveStatement | EndifDirectiveStatement |
- LineDirectiveStatement | WarningDirectiveStatement | ErrorDirectiveStatement | EmptyDirectiveStatement,
+ IncludeDirectiveStatement | DefineDirectiveStatement | UndefDirectiveStatement |
+ IfdefDirectiveStatement | IfndefDirectiveStatement | IfDirectiveStatement | DeadIfDirectiveStatement |
+ ElseDirectiveStatement | ElseifDirectiveStatement | EndifDirectiveStatement |
+ LineDirectiveStatement | WarningDirectiveStatement | ErrorDirectiveStatement | EmptyDirectiveStatement |
+ IncludeNextDirectiveStatement | IdentDirectiveStatement | LinemarkerDirectiveStatement,
"C_PreprocessorDirectiveStatement", "CPP_DIRECTIVE_STMT", false );
NEW_TERMINAL_MACRO (ClinkageStartStatement,"ClinkageStartStatement","C_LINKAGE_START_STMT" );
@@ -1681,6 +1689,8 @@
// DQ (7/26/2006): The clobber list is a list of register codes (architecture specific, but gnu standard register names).
AsmStmt.setDataPrototype ( "SgAsmStmt::AsmRegisterNameList", "clobberRegisterList", "",
NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ AsmStmt.setDataPrototype ( "bool", "isVolatile", "= false",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
#endif
SpawnStmt.setFunctionPrototype ( "HEADER_SPAWN_STATEMENT", "../Grammar/Statement.code" );
@@ -2501,7 +2511,7 @@
// 2) the integer values used for compiler generate line numbers, etc.
// For now the "directiveString" stores the full line represented by the CPP directive.
C_PreprocessorDirectiveStatement.setDataPrototype ( "std::string" , "directiveString", "= \"\"",
- NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
#if 0
// DQ (11/23/2008): I am unclear why this is here, these are not used anywhere.
@@ -2535,6 +2545,16 @@
NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
#endif
+ // DQ (11/28/2008): Thes are used to mark line numbers in generated CPP output.
+ LinemarkerDirectiveStatement.setFunctionPrototype ( "HEADER_LINEMARKER_PREPROCESSOR_DIRECTIVE_STATEMENT", "../Grammar/Statement.code" );
+ LinemarkerDirectiveStatement.setDataPrototype ( "int", "linenumber", "= -1",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ LinemarkerDirectiveStatement.setDataPrototype ( "std::string", "filename", "= \"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // The integer values are stored as char (values are '1', '2', '3', '4'), flag values are seperated by spaces.
+ LinemarkerDirectiveStatement.setDataPrototype ( "SgUnsignedCharList", "flaglist", "",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
// Support for extern "C" and extern "C++"
ClinkageDeclarationStatement.setDataPrototype ( "std::string" , "languageSpecifier", "= \"\"",
NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
@@ -2827,6 +2847,7 @@
// DQ (11/23/2008): Added support for CPP directives as IR nodes.
C_PreprocessorDirectiveStatement.setFunctionSource ( "SOURCE_PREPROCESSOR_DIRECTIVE_STATEMENT", "../Grammar/Statement.code" );
+ LinemarkerDirectiveStatement.setFunctionSource ( "SOURCE_LINEMARKER_PREPROCESSOR_DIRECTIVE_STATEMENT", "../Grammar/Statement.code" );
#if 1
// DQ (11/23/2008): Removed this by putting the post_construction_initialization into the base class.
@@ -2851,6 +2872,10 @@
ClinkageEndStatement.setFunctionSource ( "SOURCE_POST_CONSTRUCTION_INITIALIZATION_STATEMENT", "../Grammar/Statement.code" );
FortranIncludeLine.setFunctionSource ( "SOURCE_POST_CONSTRUCTION_INITIALIZATION_STATEMENT", "../Grammar/Statement.code" );
+
+ LinemarkerDirectiveStatement.setFunctionSource ( "SOURCE_POST_CONSTRUCTION_INITIALIZATION_STATEMENT", "../Grammar/Statement.code" );
+ IncludeNextDirectiveStatement.setFunctionSource ( "SOURCE_POST_CONSTRUCTION_INITIALIZATION_STATEMENT", "../Grammar/Statement.code" );
+ IdentDirectiveStatement.setFunctionSource ( "SOURCE_POST_CONSTRUCTION_INITIALIZATION_STATEMENT", "../Grammar/Statement.code" );
#endif
FortranIncludeLine.setFunctionSource ( "SOURCE_FORTRAN_INCLUDE_LINE", "../Grammar/Statement.code" );
Modified: branches/imperial/src/ROSETTA/src/support.C
===================================================================
--- branches/imperial/src/ROSETTA/src/support.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/ROSETTA/src/support.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -419,6 +419,37 @@
InitializedName.setDataPrototype("bool", "initializationDeferred", "= false",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for gnu variable attributes. Note that these can be specified on a per variable
+ // basis and because a variable declaration can contain many variables, the attributs must live with the
+ // SgInitializedName (in the future we might define aSgVariableModifier and refactor this code there).
+ // Note that more than one value can be set, so this implements a bit vector of flags to be used.
+ InitializedName.setDataPrototype("SgBitVector", "gnu_attribute_modifierVector", "",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU constructor priority (added paramter "N" as in "void f __attribute__((constructor (N)));")
+ InitializedName.setDataPrototype("unsigned long int", "gnu_attribute_initialization_priority", "= 0",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU attributes
+ InitializedName.setDataPrototype("std::string", "gnu_attribute_named_weak_reference", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU attributes
+ InitializedName.setDataPrototype("std::string", "gnu_attribute_named_alias", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU attributes
+ InitializedName.setDataPrototype("std::string", "gnu_attribute_cleanup_function", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU attributes
+ InitializedName.setDataPrototype("std::string", "gnu_attribute_section_name", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for alignment specfication using gnu attributes (zero is used as the default to imply no alignment specification).
+ InitializedName.setDataPrototype("unsigned long int", "gnu_attribute_alignment", "= 0",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU attributes (reuse the enum declaration at the SgDeclarationModifier IR node).
+ InitializedName.setDataPrototype("SgDeclarationModifier::gnu_declaration_visability_enum", "gnu_attribute_visability","= SgDeclarationModifier::e_unknown_visibility",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
+
+
+
Name.setFunctionPrototype ( "HEADER_NAME", "../Grammar/Support.code");
#if 0
@@ -1013,7 +1044,7 @@
NO_CONSTRUCTOR_PARAMETER, BUILD_FLAG_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
File.setDataPrototype ( "bool", "sourceFileTypeIsUnknown", "= false",
NO_CONSTRUCTOR_PARAMETER, BUILD_FLAG_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
-
+
// DQ (10/13/2007): Add the binary file to the SgFile IR node so that we can hold both the source
// code AST and the binary AST together. This also permits the binary AST to be handled similarly
// the the source code AST (for traversals, file I/O, etc.).
@@ -1049,6 +1080,14 @@
File.setDataPrototype ( "bool", "read_instructions_only", "= false",
NO_CONSTRUCTOR_PARAMETER, BUILD_FLAG_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/10/2009): The C language ASM statements are providing significant trouble, they are
+ // frequently machine specific and we are compiling then on architectures for which they were
+ // not designed. This option allows then to be read, constructed in the AST to support analysis
+ // but not unparsed in the code given to the backend compiler, since this can fail. (See
+ // test2007_20.C from Linux Kernel for an example).
+ File.setDataPrototype ( "bool", "skip_unparse_asm_commands", "= false",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_FLAG_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
// DQ (8/26/2008): Adds support for more agressive disassembly of sections that are in
// executable segments but may be in non-executable segments. Segments are sets of sections
// and the OS marks pages based on segment settings, not sections settings, so sections
@@ -1310,6 +1349,13 @@
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
Project.setDataPrototype("SgStringList","includeDirectorySpecifierList", "",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
+ // DQ (1/13/2009): Added support for GNU -include (for pre inclusion of files) and -isystem
+ // (for preinclusion of directories to be searched) options.
+ Project.setDataPrototype("SgStringList","preincludeFileList", "",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ Project.setDataPrototype("SgStringList","preincludeDirectoryList", "",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_LIST_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
#endif
// DQ (2/12/2004): Added to support -c on compiler command line
@@ -1437,8 +1483,17 @@
AccessModifier.setDataPrototype("SgAccessModifier::access_modifier_enum", "modifier", "= SgAccessModifier::e_unknown",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // Note that more than one value can be set, so this implements a bit vector of flags to be used.
FunctionModifier.setDataPrototype("SgBitVector", "modifierVector", "",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for GNU constructor priority (added paramter "N" as in "void f __attribute__((constructor (N)));")
+ FunctionModifier.setDataPrototype("unsigned long int", "gnu_attribute_constructor_destructor_priority", "= 0",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ FunctionModifier.setDataPrototype("std::string", "gnu_attribute_named_weak_reference", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ FunctionModifier.setDataPrototype("std::string", "gnu_attribute_named_alias", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
SpecialFunctionModifier.setDataPrototype("SgBitVector","modifierVector", "",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
@@ -1462,6 +1517,11 @@
NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
DeclarationModifier.setDataPrototype("SgStorageModifier", "storageModifier", ".reset()",
NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ DeclarationModifier.setDataPrototype("std::string", "gnu_attribute_section_name", "=\"\"",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ DeclarationModifier.setDataPrototype("SgDeclarationModifier::gnu_declaration_visability_enum", "gnu_attribute_visability","= SgDeclarationModifier::e_unknown_visibility",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
TypeModifier.setDataPrototype("SgBitVector", "modifierVector", "",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
TypeModifier.setDataPrototype("SgUPC_AccessModifier", "upcModifier", ".reset()",
@@ -1475,6 +1535,16 @@
TypeModifier.setDataPrototype("SgTypeModifier::gnu_extension_machine_mode_enum", "gnu_extension_machine_mode", "= SgTypeModifier::e_gnu_extension_machine_mode_unspecified",
NO_CONSTRUCTOR_PARAMETER, NO_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+ // DQ (1/3/2009): Added support for alignment specfication using gnu attributes (zero is used as the default to imply no alignment specification).
+ TypeModifier.setDataPrototype("unsigned long int", "gnu_attribute_alignment", "= 0",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
+ // DQ (1/3/2009): This is used for funtion types only. I reserve values less than zero (-1 implies that
+ // this was not set, default value). Note that the standard might require this to be unsigned, but I
+ // would like to avoid the EDG tick of shifting the value by one to reserve zero to be the default.
+ TypeModifier.setDataPrototype("long", "gnu_attribute_sentinel", "= -1",
+ NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
+
ElaboratedTypeModifier.setDataPrototype("SgElaboratedTypeModifier::elaborated_type_modifier_enum", "modifier",
"= SgElaboratedTypeModifier::e_unknown",
NO_CONSTRUCTOR_PARAMETER, BUILD_ACCESS_FUNCTIONS, NO_TRAVERSAL, NO_DELETE);
Modified: branches/imperial/src/backend/asmUnparser/unparseX86Asm.C
===================================================================
--- branches/imperial/src/backend/asmUnparser/unparseX86Asm.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/asmUnparser/unparseX86Asm.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -150,6 +150,9 @@
if (i != 0) result += ", ";
result += unparseX86Expression(operands[i], (insn->get_kind() == x86_lea));
}
+ if (insn->get_comment()!="")
+ result+=" <"+insn->get_comment()+">";
+
return result;
}
Modified: branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_expressions.C
===================================================================
--- branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_expressions.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_expressions.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -655,7 +655,9 @@
/* aoc_mem_autoinc */ '>',
/* aoc_mem_autodec */ '<',
/* aoc_imm_int */ 'i',
- /* aoc_imm_number */ 'n',
+ // DQ (1/10/2009): The code 'n' is not understood by gnu, so use 'r'
+ // aoc_imm_number 'n',
+ /* aoc_imm_number */ 'r',
/* aoc_imm_symbol */ 's',
/* aoc_imm_float */ 'F',
/* aoc_reg_a */ 'a',
@@ -835,21 +837,48 @@
// Just call unparse on the statement.
SgAsmOp* asmOp = isSgAsmOp(expr);
ROSE_ASSERT(asmOp != NULL);
+
+ // printf ("In unparseAsmOp(): asmOp->get_recordRawAsmOperandDescriptions() = %s \n",asmOp->get_recordRawAsmOperandDescriptions() ? "true" : "false");
+
SgExpression* expression = asmOp->get_expression();
ROSE_ASSERT(expression != NULL);
- // curprint ( "asmOp: data = ";
- // curprint ( "( modifier= ";
- // curprint ( asmOp->get_modifiers();
+ if (asmOp->get_name().empty() == false)
+ {
+ // This is symbolic name indicated for this operand (using the "[ <identifier> ]" syntax, if present).
+ curprint ("[" + asmOp->get_name() + "] ");
+ }
+
curprint ( "\"");
- unparse_asm_operand_modifier(asmOp->get_modifiers());
- // curprint ( ")";
- // curprint ( "( constraint= ";
- // curprint ( asmOp->get_constraint();
- curprint ( unparse_operand_constraint(asmOp->get_constraint()));
- // curprint ( ")";
+ if (asmOp->get_recordRawAsmOperandDescriptions() == false)
+ {
+ // This is only set to non-invalid state when RECORD_RAW_ASM_OPERAND_DESCRIPTIONS == FALSE in EDG.
+ unparse_asm_operand_modifier(asmOp->get_modifiers());
+ curprint ( unparse_operand_constraint(asmOp->get_constraint()));
+ }
+ else
+ {
+ // The modifier is part of the constraint, and it is output in the constraintString when recordRawAsmOperandDescriptions() == true.
+ printf ("asmOp->get_constraintString() = %s \n",asmOp->get_constraintString().c_str());
+ curprint ( asmOp->get_constraintString() );
+ }
+
+#if 0
+ // DQ (1/8/2009): Added support for case of asm operand handling with EDG RECORD_RAW_ASM_OPERAND_DESCRIPTIONS == TRUE
+ // (this case uses the constraintString instead of a constrant code)
+ // curprint ( unparse_operand_constraint(asmOp->get_constraint()));
+ if (asmOp->get_recordRawAsmOperandDescriptions() == false)
+ {
+ curprint ( unparse_operand_constraint(asmOp->get_constraint()));
+ }
+ else
+ {
+ curprint ( asmOp->get_constraintString() );
+ }
+#endif
+
+ // This is usually a SgVarRefExp
curprint ( "\"");
- // curprint ( " expression= ";
curprint ( " (");
unparseExpression(expression,info);
curprint ( ")");
Modified: branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_statements.C
===================================================================
--- branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_statements.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/unparser/CxxCodeGeneration/unparseCxx_statements.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -495,6 +495,21 @@
#endif
#if 0
+ curprint ( string("\n/* Top of unparseLanguageSpecificStatement (Unparse_ExprStmt) " ) + stmt->class_name() + " */\n ");
+ ROSE_ASSERT(stmt->get_startOfConstruct() != NULL);
+ // ROSE_ASSERT(stmt->getAttachedPreprocessingInfo() != NULL);
+ int numberOfComments = -1;
+ if (stmt->getAttachedPreprocessingInfo() != NULL)
+ numberOfComments = stmt->getAttachedPreprocessingInfo()->size();
+ curprint ( string("/* startOfConstruct: file = " ) + stmt->get_startOfConstruct()->get_filenameString()
+ + " raw filename = " + stmt->get_startOfConstruct()->get_raw_filename()
+ + " raw line = " + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_line())
+ + " raw column = " + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_col())
+ + " #comments = " + StringUtility::numberToString(numberOfComments)
+ + " */\n ");
+#endif
+
+#if 0
// Debugging support
SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(stmt);
if (declarationStatement != NULL)
@@ -509,8 +524,11 @@
SgScopeStatement* savedScope = info.get_current_scope();
#endif
+ // DQ (12/16/2008): Added support for unparsing statements around C++ specific statements
+ // unparseAttachedPreprocessingInfo(stmt, info, PreprocessingInfo::before);
+
// DQ (12/26/2007): Moved from language independent handling to C/C++ specific handling
- // becasue we don't want it to appear in the Fortran code generation.
+ // because we don't want it to appear in the Fortran code generation.
// DQ (added comments) this is where the new lines are introduced before statements.
unp->cur.format(stmt, info, FORMAT_BEFORE_STMT);
@@ -656,6 +674,9 @@
}
}
+ // DQ (12/16/2008): Added support for unparsing statements around C++ specific statements
+ // unparseAttachedPreprocessingInfo(stmt, info, PreprocessingInfo::after);
+
#if 0
// This is done in: UnparseLanguageIndependentConstructs::unparseStatement()
// DQ (12/5/2007): Check if the call to unparse any construct changes the scope stored in info.
@@ -1880,7 +1901,8 @@
{
// DQ (12/13/2005): I don't like this implementation with the while loop...
- // printf ("Unparse if statement \n");
+ // printf ("Unparse if statement stmt = %p \n",stmt);
+
SgIfStmt* if_stmt = isSgIfStmt(stmt);
assert (if_stmt != NULL);
@@ -1893,18 +1915,26 @@
testInfo.set_inConditional();
// info.set_inConditional();
if ( (tmp_stmt = if_stmt->get_conditional()) )
- unparseStatement(tmp_stmt, testInfo);
+ {
+ // Unparse using base class function so we get any required comments and CPP directives.
+ // unparseStatement(tmp_stmt, testInfo);
+ UnparseLanguageIndependentConstructs::unparseStatement(tmp_stmt, testInfo);
+ }
testInfo.unset_inConditional();
curprint ( string(") "));
if ( (tmp_stmt = if_stmt->get_true_body()) )
{
// printf ("Unparse the if true body \n");
- // curprint ( string("\n/* Unparse the if true body */ \n";
+ // curprint ( string("\n/* Unparse the if true body */ \n") );
unp->cur.format(tmp_stmt, info, FORMAT_BEFORE_NESTED_STATEMENT);
- unparseStatement(tmp_stmt, info);
+
+ // Unparse using base class function so we get any required comments and CPP directives.
+ // unparseStatement(tmp_stmt, info);
+ UnparseLanguageIndependentConstructs::unparseStatement(tmp_stmt, info);
+
unp->cur.format(tmp_stmt, info, FORMAT_AFTER_NESTED_STATEMENT);
- // curprint ( string("\n/* DONE: Unparse the if true body */ \n";
+ // curprint ( string("\n/* DONE: Unparse the if true body */ \n") );
}
if ( (tmp_stmt = if_stmt->get_false_body()) )
@@ -1918,7 +1948,13 @@
if_stmt = isSgIfStmt(tmp_stmt);
if (if_stmt == NULL) {
unp->cur.format(tmp_stmt, info, FORMAT_BEFORE_NESTED_STATEMENT);
- unparseStatement(tmp_stmt, info);
+
+ // curprint ( string("\n/* Unparse the if false body */ \n") );
+ // Unparse using base class function so we get any required comments and CPP directives.
+ // unparseStatement(tmp_stmt, info);
+ UnparseLanguageIndependentConstructs::unparseStatement(tmp_stmt, info);
+ // curprint ( string("\n/* DONE: Unparse the if false body */ \n") );
+
unp->cur.format(tmp_stmt, info, FORMAT_AFTER_NESTED_STATEMENT);
}
}
@@ -1926,6 +1962,10 @@
{
if_stmt = NULL;
}
+
+ // DQ (12/16/2008): Need to process any associated CPP directives and comments
+ if (if_stmt != NULL)
+ unparseAttachedPreprocessingInfo(if_stmt, info, PreprocessingInfo::before);
}
}
@@ -4556,12 +4596,57 @@
if (!info.SkipSemiColon()) { curprint ( string(";")); }
}
-//never seen this function called yet
+static bool
+isOutputAsmOperand(SgAsmOp* asmOp)
+ {
+ // There are two way of evaluating if an SgAsmOp is an output operand,
+ // depending of if we are using the specific mechanism that knows
+ // records register details or the more general mechanism that records
+ // the registers as strings. The string based mechanism lack precision
+ // and would require parsing to retrive the instruction details, but it
+ // is instruction set independent. The more precise mechanism records
+ // the specific register codes and could in the future be interpreted
+ // to be a part of the binary analysis support in ROSE.
+
+ return (asmOp->get_recordRawAsmOperandDescriptions() == true) ? (asmOp->get_isOutputOperand() == true) : (asmOp->get_modifiers() & SgAsmOp::e_output);
+ }
+
+
+
void
Unparse_ExprStmt::unparseAsmStmt(SgStatement* stmt, SgUnparse_Info& info)
{
+ // This function is called as part of the handling of the C "asm"
+ // statement. The "asm" statement supports inline assembly in C.
+ // These sorts of statements are not common in most user code
+ // (except embedded code), but are common in many system header files.
+
SgAsmStmt* asm_stmt = isSgAsmStmt(stmt);
ROSE_ASSERT(asm_stmt != NULL);
+
+#define ASM_DEBUGGING 0
+
+ SgSourceFile* sourceFile = TransformationSupport::getSourceFile(stmt);
+ ROSE_ASSERT(sourceFile != NULL);
+
+ // DQ (1/10/2009): The C language ASM statements are providing significant trouble, they are
+ // frequently machine specific and we are compiling then on architectures for which they were
+ // not designed. This option allows then to be read, constructed in the AST to support analysis
+ // but not unparsed in the code given to the backend compiler, since this can fail. (See
+ // test2007_20.C from Linux Kernel for an example).
+ if (sourceFile->get_skip_unparse_asm_commands() == true)
+ {
+ // This is a case were we skip the unparsing of the C language ASM statements, because while
+ // we can read then into the AST to support analysis, we can not always output them correctly.
+ // This subject requires additional work.
+
+ printf ("Warning: Sorry, C language ASM statement skipped (parsed and built in AST, but not output by the code generation phase (unparser)) \n");
+
+ curprint ( "/* C language ASM statement skipped (in code generation phase) */ ");
+ return;
+ }
+
+ // Output the "asm" keyword.
curprint ( string("asm "));
// DQ (7/23/2006): Added support for volatile as modifier.
@@ -4580,63 +4665,124 @@
string asmTemplate = asm_stmt->get_assemblyCode();
curprint("\"" + escapeString(asmTemplate) + "\"");
- if (asm_stmt->get_useGnuExtendedFormat()) {
- size_t numOutputOperands = 0, numInputOperands = 0;
- for (SgExpressionPtrList::const_iterator i = asm_stmt->get_operands().begin(); i != asm_stmt->get_operands().end(); ++i) {
- SgAsmOp* asmOp = isSgAsmOp(*i);
- ROSE_ASSERT (asmOp);
- if (asmOp->get_modifiers() & SgAsmOp::e_output) {
- ++numOutputOperands;
- } else {
- ++numInputOperands;
- }
- }
- size_t numClobbers = asm_stmt->get_clobberRegisterList().size();
- bool first;
- if (numInputOperands == 0 && numOutputOperands == 0 && numClobbers == 0) {
- goto donePrintingConstraints;
- }
- curprint(" : "); // Start of output operands
- first = true;
- for (SgExpressionPtrList::const_iterator i = asm_stmt->get_operands().begin(); i != asm_stmt->get_operands().end(); ++i) {
- SgAsmOp* asmOp = isSgAsmOp(*i);
- ROSE_ASSERT (asmOp);
- if (asmOp->get_modifiers() & SgAsmOp::e_output) {
- if (!first) curprint(", ");
- first = false;
- unparseExpression(asmOp, info);
- }
- }
- if (numInputOperands == 0 && numClobbers == 0) {
- goto donePrintingConstraints;
- }
- curprint(" : "); // Start of input operands
- first = true;
- for (SgExpressionPtrList::const_iterator i = asm_stmt->get_operands().begin(); i != asm_stmt->get_operands().end(); ++i) {
- SgAsmOp* asmOp = isSgAsmOp(*i);
- ROSE_ASSERT (asmOp);
- if (!(asmOp->get_modifiers() & SgAsmOp::e_output)) {
- if (!first) curprint(", ");
- first = false;
- unparseExpression(asmOp, info);
- }
- }
- if (numClobbers == 0) goto donePrintingConstraints;
- curprint(" : "); // Start of clobbers
- first = true;
- for (SgAsmStmt::AsmRegisterNameList::const_iterator i = asm_stmt->get_clobberRegisterList().begin(); i != asm_stmt->get_clobberRegisterList().end(); ++i) {
- if (!first) curprint(", ");
- first = false;
- curprint("\"" + unparse_register_name(*i) + "\"");
- }
+ if (asm_stmt->get_useGnuExtendedFormat())
+ {
+ size_t numOutputOperands = 0;
+ size_t numInputOperands = 0;
+
+ // Count the number of input vs. output operands
+ for (SgExpressionPtrList::const_iterator i = asm_stmt->get_operands().begin(); i != asm_stmt->get_operands().end(); ++i)
+ {
+ SgAsmOp* asmOp = isSgAsmOp(*i);
+ ROSE_ASSERT (asmOp);
+#if ASM_DEBUGGING
+ printf ("asmOp->get_modifiers() = %d SgAsmOp::e_output = %d asmOp->get_isOutputOperand() = %s \n",(int)asmOp->get_modifiers(),(int)SgAsmOp::e_output,asmOp->get_isOutputOperand() ? "true" : "false");
+ printf ("asmOp->get_recordRawAsmOperandDescriptions() = %s \n",asmOp->get_recordRawAsmOperandDescriptions() ? "true" : "false");
+#endif
+ // if (asmOp->get_modifiers() & SgAsmOp::e_output)
+ // if ( (asmOp->get_modifiers() & SgAsmOp::e_output) || (asmOp->get_isOutputOperand() == true) )
+ if ( isOutputAsmOperand(asmOp) == true )
+ {
+ ++numOutputOperands;
+#if ASM_DEBUGGING
+ printf ("Marking as an output operand! \n");
+#endif
+ }
+ else
+ {
+ ++numInputOperands;
+#if ASM_DEBUGGING
+ printf ("Marking as an input operand! \n");
+#endif
+ }
+ }
+
+ size_t numClobbers = asm_stmt->get_clobberRegisterList().size();
+
+#if ASM_DEBUGGING
+ printf ("numOutputOperands = %zu numInputOperands = %zu numClobbers = %zu \n",numOutputOperands,numInputOperands,numClobbers);
+#endif
+
+ bool first;
+ if (numInputOperands == 0 && numOutputOperands == 0 && numClobbers == 0)
+ {
+ goto donePrintingConstraints;
+ }
+ curprint(" : "); // Start of output operands
+
+#if ASM_DEBUGGING
+ curprint(" /* asm output operands */ "); // Debugging output
+#endif
+
+ // Record if this is the first operand so that we can surpress the ","
+ first = true;
+ for (SgExpressionPtrList::const_iterator i = asm_stmt->get_operands().begin(); i != asm_stmt->get_operands().end(); ++i)
+ {
+ SgAsmOp* asmOp = isSgAsmOp(*i);
+ ROSE_ASSERT (asmOp != NULL);
+ // if (asmOp->get_modifiers() & SgAsmOp::e_output)
+ // if ( (asmOp->get_modifiers() & SgAsmOp::e_output) || (asmOp->get_isOutputOperand() == true) )
+ if ( isOutputAsmOperand(asmOp) == true )
+ {
+ if (!first)
+ curprint(", ");
+ first = false;
+ unparseExpression(asmOp, info);
+ }
+ }
+
+ if (numInputOperands == 0 && numClobbers == 0)
+ {
+ goto donePrintingConstraints;
+ }
+ curprint(" : "); // Start of input operands
+#if ASM_DEBUGGING
+ curprint(" /* asm input operands */ "); // Debugging output
+#endif
+ first = true;
+ for (SgExpressionPtrList::const_iterator i = asm_stmt->get_operands().begin(); i != asm_stmt->get_operands().end(); ++i)
+ {
+ SgAsmOp* asmOp = isSgAsmOp(*i);
+ ROSE_ASSERT (asmOp != NULL);
+ // if (!(asmOp->get_modifiers() & SgAsmOp::e_output))
+ if ( isOutputAsmOperand(asmOp) == false )
+ {
+ if (!first)
+ curprint(", ");
+ first = false;
+ unparseExpression(asmOp, info);
+ }
+ }
+
+ if (numClobbers == 0)
+ goto donePrintingConstraints;
+
+ curprint(" : "); // Start of clobbers
+
+#if ASM_DEBUGGING
+ curprint(" /* asm clobbers */ "); // Debugging output
+#endif
+ first = true;
+ for (SgAsmStmt::AsmRegisterNameList::const_iterator i = asm_stmt->get_clobberRegisterList().begin(); i != asm_stmt->get_clobberRegisterList().end(); ++i)
+ {
+ if (!first) curprint(", ");
+ first = false;
+ curprint("\"" + unparse_register_name(*i) + "\"");
+ }
+
donePrintingConstraints: {}
- }
+ }
+
curprint ( string(")"));
- if (!info.SkipSemiColon()) { curprint ( string(";")); }
+ if (!info.SkipSemiColon())
+ {
+ curprint ( string(";"));
+ }
}
+
#if 0
// DQ (8/13/2007): this function is not used!
Modified: branches/imperial/src/backend/unparser/FortranCodeGeneration/unparseFortran_statements.C
===================================================================
--- branches/imperial/src/backend/unparser/FortranCodeGeneration/unparseFortran_statements.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/unparser/FortranCodeGeneration/unparseFortran_statements.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -114,6 +114,14 @@
// This is a Fortran specific case (different from use of SgLabelStatement in C/C++).
// unparseStatementNumbersSupport(stmt->get_numeric_label(),info);
+ // DQ (11/29/2008): If this is a CPP directive then don't output statement
+ // number or the white space for then in fixed format mode.
+ if (isSgC_PreprocessorDirectiveStatement(stmt) != NULL)
+ {
+ printf ("This is a CPP directive, skip leading white space in unparsing. \n");
+ return;
+ }
+
// This fixes a formatting problem, an aspect fo which was reported by Liao 12/28/2007).
if ( isSgGlobal(stmt) != NULL || isSgBasicBlock(stmt) != NULL )
{
Modified: branches/imperial/src/backend/unparser/languageIndependenceSupport/name_qualification_support.C
===================================================================
--- branches/imperial/src/backend/unparser/languageIndependenceSupport/name_qualification_support.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/unparser/languageIndependenceSupport/name_qualification_support.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -551,9 +551,15 @@
printf ("***** This branch should output a %s name? \n",outputQualifiedName ? "QUALIFIED" : "NON-QUALIFIED");
#endif
+ // DQ (1/11/2009): Added support for __FUNCTION__ (see test2004_153.C) and __BASE_FILE__.
// DQ (6/9/2007): Make an exception for compiler generated variables (e.g."__PRETTY_FUNCTION__")
// if (initializedName->get_startOfConstruct()->isCompilerGenerated() == true)
- if ( (initializedName->get_startOfConstruct()->isCompilerGenerated() == true) && (initializedName->get_name() == "__PRETTY_FUNCTION__" || initializedName->get_name() == "__func__") )
+ // if ( (initializedName->get_startOfConstruct()->isCompilerGenerated() == true) && (initializedName->get_name() == "__PRETTY_FUNCTION__" || initializedName->get_name() == "__func__") )
+ if ( (initializedName->get_startOfConstruct()->isCompilerGenerated() == true) &&
+ ( (initializedName->get_name() == "__PRETTY_FUNCTION__") ||
+ (initializedName->get_name() == "__func__") ||
+ (initializedName->get_name() == "__FUNCTION__") ||
+ (initializedName->get_name() == "__BASE_FILE__") ) )
{
#if 0
printf ("initializedName = %p = %s is compiler generated so it should not be qualified \n",initializedName,initializedName->get_name().str());
Modified: branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.C
===================================================================
--- branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -132,8 +132,10 @@
#endif
}
- // printf ("statementInFile = %p = %s = %s = %s \n",stmt,stmt->class_name().c_str(),SageInterface::get_name(stmt).c_str(),(statementInFile == true) ? "true" : "false");
- // stmt->get_file_info()->display("debug why false");
+#if 0
+ printf ("statementInFile = %p = %s = %s = %s \n",stmt,stmt->class_name().c_str(),SageInterface::get_name(stmt).c_str(),(statementInFile == true) ? "true" : "false");
+ stmt->get_file_info()->display("debug why false");
+#endif
#if 0
// Debugging support
@@ -345,21 +347,32 @@
}
// ROSE_ASSERT(stmt->get_endOfConstruct() != NULL);
- curprint ( string("\n/* Top of unparseStatement " ) + string(stmt->sage_class_name()) + " */\n ");
+ curprint ( string("\n/* Top of unparseStatement (UnparseLanguageIndependentConstructs)" ) + string(stmt->sage_class_name()) + " */\n ");
ROSE_ASSERT(stmt->get_startOfConstruct() != NULL);
- curprint ( string("/* startOfConstruct: file = " ) + stmt->get_startOfConstruct()->get_filenameString()
- + " raw filename = " + stmt->get_startOfConstruct()->get_raw_filename()
- + " raw line = " + stmt->get_startOfConstruct()->get_raw_line()
- + " raw column = " + stmt->get_startOfConstruct()->get_raw_col()
+ // ROSE_ASSERT(stmt->getAttachedPreprocessingInfo() != NULL);
+ int numberOfComments = -1;
+ if (stmt->getAttachedPreprocessingInfo() != NULL)
+ numberOfComments = stmt->getAttachedPreprocessingInfo()->size();
+ curprint ( string("/* startOfConstruct: file = " ) + stmt->get_startOfConstruct()->get_filenameString()
+ + " raw filename = " + stmt->get_startOfConstruct()->get_raw_filename()
+ + " raw line = " + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_line())
+ + " raw column = " + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_col())
+ + " #comments = " + StringUtility::numberToString(numberOfComments)
+ " */\n ");
+
if (stmt->get_endOfConstruct() != NULL)
{
curprint ( string("/* endOfConstruct: file = " ) + stmt->get_endOfConstruct()->get_filenameString()
+ " raw filename = " + stmt->get_endOfConstruct()->get_raw_filename()
- + " raw line = " + stmt->get_endOfConstruct()->get_raw_line()
- + " raw column = " + stmt->get_endOfConstruct()->get_raw_col()
+ + " raw line = " + StringUtility::numberToString(stmt->get_endOfConstruct()->get_raw_line())
+ + " raw column = " + StringUtility::numberToString(stmt->get_endOfConstruct()->get_raw_col())
+ " */\n ");
}
+ else
+ {
+ curprint ( string("/* endOfConstruct == NULL */\n " ) );
+ }
+
// ROSE_ASSERT(stmt->get_endOfConstruct() != NULL);
SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(stmt);
@@ -371,8 +384,8 @@
{
curprint ( string("\n/* SgInitializedName = " ) + (*i)->get_name() + " in file: "
+ (*i)->get_file_info()->get_raw_filename() + " at line: "
- + (*i)->get_file_info()->get_raw_line() + " at column: "
- + (*i)->get_file_info()->get_raw_col() + " */\n ");
+ + StringUtility::numberToString((*i)->get_file_info()->get_raw_line()) + " at column: "
+ + StringUtility::numberToString((*i)->get_file_info()->get_raw_col()) + " */\n ");
i++;
}
}
@@ -534,6 +547,25 @@
case V_SgFunctionTypeTable: unparseFuncTblStmt (stmt, info); break;
case V_SgNullStatement: unparseNullStatement(stmt, info); break;
+ // DQ (11/29/2008): Added support for unparsing CPP directives now supported as IR nodes.
+ case V_SgIncludeDirectiveStatement: unparseIncludeDirectiveStatement (stmt, info); break;
+ case V_SgDefineDirectiveStatement: unparseDefineDirectiveStatement (stmt, info); break;
+ case V_SgUndefDirectiveStatement: unparseUndefDirectiveStatement (stmt, info); break;
+ case V_SgIfdefDirectiveStatement: unparseIfdefDirectiveStatement (stmt, info); break;
+ case V_SgIfndefDirectiveStatement: unparseIfndefDirectiveStatement (stmt, info); break;
+ case V_SgDeadIfDirectiveStatement: unparseDeadIfDirectiveStatement (stmt, info); break;
+ case V_SgIfDirectiveStatement: unparseIfDirectiveStatement (stmt, info); break;
+ case V_SgElseDirectiveStatement: unparseElseDirectiveStatement (stmt, info); break;
+ case V_SgElseifDirectiveStatement: unparseElseifDirectiveStatement (stmt, info); break;
+ case V_SgEndifDirectiveStatement: unparseEndifDirectiveStatement (stmt, info); break;
+ case V_SgLineDirectiveStatement: unparseLineDirectiveStatement (stmt, info); break;
+ case V_SgWarningDirectiveStatement: unparseWarningDirectiveStatement (stmt, info); break;
+ case V_SgErrorDirectiveStatement: unparseErrorDirectiveStatement (stmt, info); break;
+ case V_SgEmptyDirectiveStatement: unparseEmptyDirectiveStatement (stmt, info); break;
+ case V_SgIdentDirectiveStatement: unparseIdentDirectiveStatement (stmt, info); break;
+ case V_SgIncludeNextDirectiveStatement: unparseIncludeNextDirectiveStatement (stmt, info); break;
+ case V_SgLinemarkerDirectiveStatement: unparseLinemarkerDirectiveStatement (stmt, info); break;
+
default:
// DQ (11/4/2008): This is a bug for the case of a SgFortranDo statement, unclear what to do about this.
// Call the derived class implementation for C, C++, or Fortran specific language unparsing.
@@ -1259,7 +1291,7 @@
curprint ( (*i)->getString());
break;
- case PreprocessingInfo::CpreprocessorCompilerGenerateLineDeclaration:
+ case PreprocessingInfo::CpreprocessorCompilerGeneratedLinemarker:
curprint ( (*i)->getString());
break;
@@ -2558,3 +2590,161 @@
}
}
+
+void
+UnparseLanguageIndependentConstructs::unparseIncludeDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgIncludeDirectiveStatement* directive = isSgIncludeDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ // unp->u_sage->curprint_newline();
+ unp->cur.insert_newline(1);
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseDefineDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgDefineDirectiveStatement* directive = isSgDefineDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ // unp->u_sage->curprint_newline();
+ unp->cur.insert_newline(1);
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseUndefDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgUndefDirectiveStatement* directive = isSgUndefDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseIfdefDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgIfdefDirectiveStatement* directive = isSgIfdefDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseIfndefDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgIfndefDirectiveStatement* directive = isSgIfndefDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseDeadIfDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgDeadIfDirectiveStatement* directive = isSgDeadIfDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseIfDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgIfDirectiveStatement* directive = isSgIfDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseElseDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgElseDirectiveStatement* directive = isSgElseDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseElseifDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgElseifDirectiveStatement* directive = isSgElseifDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseEndifDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgEndifDirectiveStatement* directive = isSgEndifDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseLineDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgLineDirectiveStatement* directive = isSgLineDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseWarningDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgWarningDirectiveStatement* directive = isSgWarningDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseErrorDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgErrorDirectiveStatement* directive = isSgErrorDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseEmptyDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgEmptyDirectiveStatement* directive = isSgEmptyDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseIdentDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgIdentDirectiveStatement* directive = isSgIdentDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseIncludeNextDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgIncludeNextDirectiveStatement* directive = isSgIncludeNextDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+void
+UnparseLanguageIndependentConstructs::unparseLinemarkerDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info)
+ {
+ SgLinemarkerDirectiveStatement* directive = isSgLinemarkerDirectiveStatement(stmt);
+ ROSE_ASSERT(directive != NULL);
+ curprint(directive->get_directiveString());
+ unp->u_sage->curprint_newline();
+ }
+
+
+
Modified: branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.h
===================================================================
--- branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/backend/unparser/languageIndependenceSupport/unparseLanugageIndependentConstructs.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -282,6 +282,25 @@
// virtual void unparseTemplateDeclStmt (SgStatement* stmt, SgUnparse_Info& info);
virtual void unparseNullStatement (SgStatement* stmt, SgUnparse_Info& info);
+
+ virtual void unparseIncludeDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseDefineDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseUndefDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseIfdefDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseIfndefDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseDeadIfDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseIfDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseElseDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseElseifDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseEndifDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseLineDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseWarningDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseErrorDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseEmptyDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseIdentDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseIncludeNextDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+ virtual void unparseLinemarkerDirectiveStatement (SgStatement* stmt, SgUnparse_Info& info);
+
#if 0
// DQ (7/21/2006): Added support for GNU statement expression extension.
virtual void unparseStatementExpression (SgExpression* expr, SgUnparse_Info& info);
Modified: branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnum.h
===================================================================
--- branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnum.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnum.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -417,6 +417,10 @@
x86_prefetcht2,
x86_prefetchw,
x86_psadbw,
+
+// DQ (12/4/2008): Added entry, is this an automatically generated file?
+ x86_pshufb,
+
x86_pshufd,
x86_pshufhw,
x86_pshuflw,
Modified: branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnumPrinter.C
===================================================================
--- branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnumPrinter.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/BinaryDisassembly/x86InstructionEnumPrinter.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -414,6 +414,10 @@
"x86_prefetcht2",
"x86_prefetchw",
"x86_psadbw",
+"",
+"// DQ (12/4/2008): Added entry is this an automatically generated file?",
+"x86_pshufb",
+"",
"x86_pshufd",
"x86_pshufhw",
"x86_pshuflw",
Modified: branches/imperial/src/frontend/CxxFrontend/Makefile.am
===================================================================
--- branches/imperial/src/frontend/CxxFrontend/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/CxxFrontend/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -20,4 +20,4 @@
clean-local:
-rm -rf .libs/
-EXTRA_DIST = roseBinaryEDG-i686-apple-darwin-40d96a32f4107da10f3e9700d061aec6.tar.gz roseBinaryEDG-i686-pc-linux-gnu-40d96a32f4107da10f3e9700d061aec6.tar.gz roseBinaryEDG-x86_64-pc-linux-gnu-40d96a32f4107da10f3e9700d061aec6.tar.gz
+EXTRA_DIST = roseBinaryEDG-i686-apple-darwin-4e0991cce7811e46159c1b66bb26a0ce.tar.gz roseBinaryEDG-i686-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz roseBinaryEDG-x86_64-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz
Modified: branches/imperial/src/frontend/CxxFrontend/README
===================================================================
--- branches/imperial/src/frontend/CxxFrontend/README 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/CxxFrontend/README 2009-01-14 15:08:15 UTC (rev 189)
@@ -11,3 +11,19 @@
We need a more complete list, some of what has been modified in 3.3 is no longer required
in versions after 3.7.
+
+
+Notes:
+
+1) To run the EDG unparser:
+ $(ROSE_BUILD_TREE)/src/frontend/CxxFrontend/EDG_3.10/src/cp_gen_be --edg_base=$(ROSE_BUILD_TREE)/src/frontend/CxxFrontend/EDG_3.10/lib $(SOURCE_FILES)
+
+ The --edg_base directory can also be set through the EDG_BASE environment variable.
+ The output goes into <source-file-base-name>.int.c (even for C++).
+
+2) New work in ROSE introduces a new connection between EDG and SageIII, the
+ new connection required a configure option ""
+ and also switches ROSe to use the EDG version 3.10 frontend. This
+ work is currently experimental and will evolve with time.
+
+
Deleted: branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-apple-darwin-40d96a32f4107da10f3e9700d061aec6.tar.gz
===================================================================
(Binary files differ)
Copied: branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-apple-darwin-4e0991cce7811e46159c1b66bb26a0ce.tar.gz (from rev 188, trunk/src/frontend/CxxFrontend/roseBinaryEDG-i686-apple-darwin-4e0991cce7811e46159c1b66bb26a0ce.tar.gz)
===================================================================
(Binary files differ)
Deleted: branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-pc-linux-gnu-40d96a32f4107da10f3e9700d061aec6.tar.gz
===================================================================
(Binary files differ)
Copied: branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-i686-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz (from rev 188, trunk/src/frontend/CxxFrontend/roseBinaryEDG-i686-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz)
===================================================================
(Binary files differ)
Deleted: branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-x86_64-pc-linux-gnu-40d96a32f4107da10f3e9700d061aec6.tar.gz
===================================================================
(Binary files differ)
Copied: branches/imperial/src/frontend/CxxFrontend/roseBinaryEDG-x86_64-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz (from rev 188, trunk/src/frontend/CxxFrontend/roseBinaryEDG-x86_64-pc-linux-gnu-4e0991cce7811e46159c1b66bb26a0ce.tar.gz)
===================================================================
(Binary files differ)
Modified: branches/imperial/src/frontend/Disassemblers/x86Disassembler.C
===================================================================
--- branches/imperial/src/frontend/Disassemblers/x86Disassembler.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/Disassemblers/x86Disassembler.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -29,6 +29,20 @@
#define V2QWORDT (SgAsmTypeVector::createType(2, QWORDT))
#define V2DOUBLET (SgAsmTypeVector::createType(2, DOUBLET))
+
+// Work left to do:
+// 1) Fix existing FIXMEs and ASSERT's within the current implementation.
+// 2) We need SgAsmTypes in the IR for more data types: Far Pointers,
+// FPU environment (m14/28 byte, 14 bytes for 16 bit mode and 28 bytes for 32 bit mode),
+// FPU State (m94/108 byte see section about "fsave" page 3-372)
+// ..., also m16&16 (16bit pair of operands for bounds checking: "bound"),
+// also versions for 32bit and 64bit. (See section 3.1.1.2).
+//
+
+
+// See section 9.11 in Volume 3A of Intel for details of how to store new microcode into the processor.
+
+
namespace X86Disassembler {
enum RepeatPrefix {rpNone, rpRepne, rpRepe};
@@ -310,12 +324,18 @@
}
void getModRegRM(RegisterMode regMode, RegisterMode rmMode, SgAsmType* t, SgAsmType* tForReg = NULL) {
+
+ // "RM" stands for Register or Memory and "Mod" is mode).
+ // First parameter is the register kind for the reg field of the modregrm byte.
+ // Second parameter is the register kind for the RM field when the mod refers to a register.
+
if (!tForReg) {tForReg = t;}
getByte(modregrmByte);
modregrmByteSet = true;
modeField = modregrmByte >> 6;
regField = (modregrmByte & 070) >> 3;
rmField = modregrmByte & 7;
+
reg = makeModrmRegister(regMode, tForReg);
modrm = makeModrmNormal(rmMode, t);
}
@@ -541,6 +561,10 @@
}
SgAsmx86Instruction* decodeOpcode0F();
+
+ // DQ (12/3/2008): Added initial support for SSSE3
+ SgAsmx86Instruction* decodeOpcode0F38();
+
SgAsmx86Instruction* decodeX87InstructionD8();
SgAsmx86Instruction* decodeX87InstructionD9();
SgAsmx86Instruction* decodeX87InstructionDA();
@@ -693,6 +717,20 @@
}
SgAsmx86Instruction* SingleInstructionDisassembler::disassemble() {
+
+ // Subsets of the x86 instruction set left to be implements (not implemented).
+ // 1) SSE 4 (4a, 4b, 4.1) To generate binary that uses these instructions use a modern version of the Intel compiler.
+ // 2) AVX (Intel instructions, these are new and not available in any software yet (Dec,2008))
+ // 3) SSE 5 (AMD instructions, these instructions are not available in any software yet (Dec,2008))
+ // 4) SSSE 3 (Supplemental SSE 3) To generate binary that uses these instructions use a modern version of the Intel compiler.
+
+ // Note that prefix handling is supported by state that is set and used in the parsing of the instrcution op codes.
+ // This state is fully contained in the SingleInstructionDisassembler class.
+
+ // Note that this function is called recursively to handle REX and Legacy prefixs
+ // (see appendix B of volume 2B of Intel 64 and IA-32 Architecute Software Developers Manual).
+ // Also, the order of the prefix is not inforced by this design. See section 2.1.1 of volume 2A.
+
uint8_t opcode;
getByte(opcode);
SgAsmx86Instruction* insn = 0;
@@ -701,6 +739,9 @@
case 0x01: {getModRegRM(effectiveOperandMode(), effectiveOperandMode(), effectiveOperandType()); insn = MAKE_INSN2(add, add, modrm, reg); goto done;}
case 0x02: {getModRegRM(rmLegacyByte, rmLegacyByte, BYTET); insn = MAKE_INSN2(add, add, reg, modrm); goto done;}
case 0x03: {getModRegRM(effectiveOperandMode(), effectiveOperandMode(), effectiveOperandType()); insn = MAKE_INSN2(add, add, reg, modrm); goto done;}
+
+ // Immediate values are read as required and acts as a recursive decent parser.
+ // Function names are taken from the manual (Intel x86 Instruction Set Reference: Appendix A: Opcode Map)
case 0x04: {SgAsmExpression* imm = getImmByteAsIv(); insn = MAKE_INSN2(add, add, makeRegister(0, rmLegacyByte), imm); goto done;}
case 0x05: {SgAsmExpression* imm = getImmIzAsIv(); insn = MAKE_INSN2(add, add, makeRegisterEffective(0), imm); goto done;}
case 0x06: {not64(); insn = MAKE_INSN1(push, push, makeRegister(0, rmSegment)); goto done;}
@@ -743,6 +784,8 @@
case 0x2B: {getModRegRM(effectiveOperandMode(), effectiveOperandMode(), effectiveOperandType()); insn = MAKE_INSN2(sub, sub, reg, modrm); goto done;}
case 0x2C: {SgAsmExpression* imm = getImmByteAsIv(); insn = MAKE_INSN2(sub, sub, makeRegister(0, rmLegacyByte), imm); goto done;}
case 0x2D: {SgAsmExpression* imm = getImmIzAsIv(); insn = MAKE_INSN2(sub, sub, makeRegisterEffective(0), imm); goto done;}
+
+ // Example of recursive use of disassemble()
case 0x2E: {segOverride = x86_segreg_cs; branchPrediction = x86_branch_prediction_not_taken; insn = disassemble(); goto done;}
case 0x2F: {not64(); insn = MAKE_INSN0(das, das); goto done;}
case 0x30: {getModRegRM(rmLegacyByte, rmLegacyByte, BYTET); insn = MAKE_INSN2(xor, xor, modrm, reg); goto done;}
@@ -871,7 +914,12 @@
case 0x7D: {SgAsmExpression* imm = getImmJb(); branchPredictionEnabled = true; insn = MAKE_INSN1(jge, jge, imm); goto done;}
case 0x7E: {SgAsmExpression* imm = getImmJb(); branchPredictionEnabled = true; insn = MAKE_INSN1(jle, jle, imm); goto done;}
case 0x7F: {SgAsmExpression* imm = getImmJb(); branchPredictionEnabled = true; insn = MAKE_INSN1(jg , jg , imm); goto done;}
+
+ // The names for groups will make more sense relative to the AMD manual.
case 0x80: {getModRegRM(rmReturnNull, rmLegacyByte, BYTET); SgAsmExpression* imm = getImmByte(); insn = decodeGroup1(imm); goto done;}
+
+ // effectiveOperandMode() returns register mode for the effective operand size (16bit, 32, bit, 64bit)
+ // effectiveOperandType() does the same thing but returne a SgAsmType.
case 0x81: {getModRegRM(rmReturnNull, effectiveOperandMode(), effectiveOperandType()); SgAsmExpression* imm = getImmIzAsIv(); insn = decodeGroup1(imm); goto done;}
case 0x82: {not64(); getModRegRM(rmReturnNull, rmLegacyByte, BYTET); SgAsmExpression* imm = getImmByte(); insn = decodeGroup1(imm); goto done;}
case 0x83: {getModRegRM(rmReturnNull, effectiveOperandMode(), effectiveOperandType()); SgAsmExpression* imm = getImmByteAsIv(); insn = decodeGroup1(imm); goto done;}
@@ -1523,7 +1571,7 @@
case 0x0C: throw BadInstruction();
case 0x0D: return decodeGroupP();
case 0x0E: return MAKE_INSN0(femms, femms);
- case 0x0F: { // 3DNow!
+ case 0x0F: { // 3DNow! (AMD Specific)
getModRegRM(rmReturnNull, rmReturnNull, NULL);
uint8_t thirdOpcodeByte;
getByte(thirdOpcodeByte);
@@ -1655,6 +1703,11 @@
case 0x1D: getModRegRM(rmReturnNull, rmReturnNull, NULL); return MAKE_INSN0(nop, nop);
case 0x1E: getModRegRM(rmReturnNull, rmReturnNull, NULL); return MAKE_INSN0(nop, nop);
case 0x1F: getModRegRM(rmReturnNull, rmReturnNull, NULL); return MAKE_INSN0(nop, nop);
+
+ // BUG: The mode and type fields should forced to the current processor number of bits
+ // instead of the size determied by the operand size flag. See documentation for move
+ // to control register ("lock mov cr0, *"). This may be an AMD specific issue, but the
+ // operand size issues is a bug everywhere.
case 0x20: getModRegRM(rmControl, effectiveOperandMode(), effectiveOperandType()); if (modeField == 3) return MAKE_INSN2(mov, mov, modrm, reg); else throw BadInstruction();
case 0x21: getModRegRM(rmDebug, effectiveOperandMode(), effectiveOperandType()); if (modeField == 3) return MAKE_INSN2(mov, mov, modrm, reg); else throw BadInstruction();
case 0x22: getModRegRM(rmControl, effectiveOperandMode(), effectiveOperandType()); if (modeField == 3) return MAKE_INSN2(mov, mov, reg, modrm); else throw BadInstruction();
@@ -1736,7 +1789,11 @@
case 0x35: not64(); return MAKE_INSN0(sysexit, sysexit);
case 0x36: throw BadInstruction();
case 0x37: return MAKE_INSN0(getsec, getsec);
- case 0x38: ROSE_ASSERT (!"0F38");
+
+ // DQ (12/3/2008): Adding instruction support for SSSE3.
+ // case 0x38: ROSE_ASSERT (!"0F38");
+ case 0x38: decodeOpcode0F38();
+
case 0x39: throw BadInstruction();
case 0x3A: ROSE_ASSERT (!"0F3A");
case 0x3B: throw BadInstruction();
@@ -2298,6 +2355,8 @@
case 0xB7: getModRegRM(effectiveOperandMode(), rmWord, WORDT); return MAKE_INSN2(movzx, movzx, reg, modrm);
case 0xB8: {
getModRegRM(effectiveOperandMode(), effectiveOperandMode(), effectiveOperandType());
+
+ // Here is an example of the existence of a prefix leading to two very different instructions.
switch (mmPrefix()) {
case mmNone: isUnconditionalJump = true; return MAKE_INSN1(jmpe, jmpe, modrm);
case mmF3: return MAKE_INSN2(popcnt, popcnt, reg, modrm);
@@ -2795,6 +2854,32 @@
}
}
+// DQ (12/3/2008): Added initial support for SSSE3
+SgAsmx86Instruction* SingleInstructionDisassembler::decodeOpcode0F38()
+ {
+ // Support for SSSE 3 (opcode 0F38)
+ uint8_t opcode;
+
+ // Get the third byte of the opcode (the first two were read by the caller (decodeOpcode0F())
+ getByte(opcode);
+ switch (opcode) {
+ case 0x00: {
+ switch (mmPrefix()) {
+ // The pshufb name is used twice because one is for the generated enum name and other is for the instruction name.
+ // Note that getModRegRM sets the states reg and modrm.
+ // Also, standard prefixed used in the manual, "mm" refers to "mmx" registers and "xmm" refers to "sse" registers.
+ case mmNone: getModRegRM(rmMM, rmMM, V2DWORDT); return MAKE_INSN2(pshufb, pshufb, reg, modrm);
+ case mmF3: throw BadInstruction();
+ case mm66: getModRegRM(rmXMM, rmXMM, V4DWORDT); return MAKE_INSN2(pshufb, pshufb, reg, modrm);
+ case mmF2: throw BadInstruction();
+ }
+ }
+
+ default: throw BadInstruction();
+ }
+ }
+
+
SgAsmx86Instruction* SingleInstructionDisassembler::decodeGroup1(SgAsmExpression* imm) {
switch (regField) {
case 0: return MAKE_INSN2(add, add, modrm, imm);
Modified: branches/imperial/src/frontend/ExecFormats/ROSE_ExecELF.C
===================================================================
--- branches/imperial/src/frontend/ExecFormats/ROSE_ExecELF.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/ExecFormats/ROSE_ExecELF.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -71,6 +71,58 @@
return retval;
}
+/** Convert ELF "machine" identifier to generic instruction set architecture value. */
+SgAsmExecutableFileFormat::InsSetArchitecture
+SgAsmElfFileHeader::machine_to_isa(unsigned machine) const
+{
+ switch (p_e_machine) { /* These come from the Portable Formats Specification v1.1 */
+ case 0: return ISA_UNSPECIFIED;
+ case 1: return ISA_ATT_WE_32100;
+ case 2: return ISA_SPARC_Family;
+ case 3: return ISA_IA32_386;
+ case 4: return ISA_M68K_Family;
+ case 5: return ISA_M88K_Family;
+ case 7: return ISA_I860_Family;
+ case 8: return ISA_MIPS_Family;
+ case 20:
+ // Note that PowerPC has: p_e_machine = 20 = 0x14, using both gcc on BGL and xlc on BGL.
+ // However, these don't seem like correct values for PowerPC.
+ return ISA_PowerPC;
+ case 40: return ISA_ARM_Family;
+ case 62: return ISA_X8664_Family;
+ default:
+ /*FIXME: There's a whole lot more. See Dan's Elf reader. */
+ // DQ (10/12/2008): Need more information to address PowerPC support.
+ fprintf(stderr, "Warning: SgAsmElfFileHeader::parse::p_e_machine = 0x%lx (%lu)\n", p_e_machine, p_e_machine);
+ return ISA_OTHER;
+ }
+}
+
+/** Convert architecture value to an ELF "machine" value. */
+unsigned
+SgAsmElfFileHeader::isa_to_machine(SgAsmExecutableFileFormat::InsSetArchitecture isa) const
+{
+ switch (isa) {
+ case ISA_UNSPECIFIED:
+ case ISA_OTHER: return p_e_machine;
+ case ISA_ATT_WE_32100: return 1;
+ case ISA_IA32_386: return 3;
+ case ISA_PowerPC: return 20; /*see note in machine_to_isa()*/
+ default:
+ switch (isa & ISA_FAMILY_MASK) {
+ case ISA_SPARC_Family: return 2;
+ case ISA_M68K_Family: return 4;
+ case ISA_M88K_Family: return 5;
+ case ISA_I860_Family: return 7;
+ case ISA_MIPS_Family: return 8;
+ case ISA_ARM_Family: return 40;
+ case ISA_X8664_Family: return 62;
+ default:
+ return p_e_machine;
+ }
+ }
+}
+
/** Initialize this header with information parsed from the file and construct and parse everything that's reachable from the
* header. Since the size of the ELF File Header is determined by the contents of the ELF File Header as stored in the file,
* the size of the ELF File Header will be adjusted upward if necessary. The ELF File Header should have been constructed
@@ -242,53 +294,8 @@
p_exec_format->set_abi_version(0);
/* Target architecture */
- switch (p_e_machine) { /* These come from the Portable Formats Specification v1.1 */
- case 0:
- set_isa(ISA_UNSPECIFIED);
- break;
- case 1:
- set_isa(ISA_ATT_WE_32100);
- break;
- case 2:
- set_isa(ISA_SPARC_Family);
- break;
- case 3:
- set_isa(ISA_IA32_386);
- break;
- case 4:
- set_isa(ISA_M68K_Family);
- break;
- case 5:
- set_isa(ISA_M88K_Family);
- break;
- case 7:
- set_isa(ISA_I860_Family);
- break;
- case 8:
- set_isa(ISA_MIPS_Family);
- break;
- case 20:
- // Note that PowerPC has: p_e_machine = 20 = 0x14, using both gcc on BGL and xlc on BGL.
- // However, these don't seem like correct values for PowerPC.
- set_isa(ISA_PowerPC);
- break;
- case 40:
- set_isa(ISA_ARM_Family);
- break;
- case 62:
- set_isa(ISA_X8664_Family);
- break;
- default:
- /*FIXME: There's a whole lot more. See Dan's Elf reader. */
- // DQ (10/12/2008): Need more information to address PowerPC support.
- fprintf(stderr, "Warning: SgAsmElfFileHeader::parse::p_e_machine = 0x%lx (%lu)\n", p_e_machine, p_e_machine);
- set_isa(ISA_OTHER);
- break;
- }
+ set_isa(machine_to_isa(p_e_machine));
- /* Target architecture */
- /*FIXME*/
-
/* Read the optional section and segment tables and the sections to which they point. An empty section or segment table is
* treated as if it doesn't exist. This seems to be compatible with the loader since the 45-bit "tiny" ELF executable
* stores a zero in the e_shnum member and a completely invalid value in the e_shoff member. */
@@ -369,42 +376,16 @@
ROSE_ASSERT(p_magic.size() == NELMTS(disk->e_ident_magic));
for (size_t i=0; i<NELMTS(disk->e_ident_magic); i++)
disk->e_ident_magic[i] = p_magic[i];
-
- unsigned ident_file_class=1;
- switch(get_word_size()) {
- case 4:
- ident_file_class = 1;
- break;
- case 8:
- ident_file_class = 2;
- break;
- default:
- ROSE_ASSERT(!"invalid word size");
- break;
- }
- host_to_disk(sex, ident_file_class, &(disk->e_ident_file_class));
-
- /* Byte order. According to the spec, valid values are 1 (little-endian) and 2 (big-endian). However, we've seen cases
- * where a value of zero is used to indicate "native" order (loader assumes words are in the order of the machine on which
- * the loader is running, and the ROSE ELF parser determines the order by looking at other fields in the header). Any
- * original value other than 1 or 2 will be written to the new output; otherwise we choose 1 or 2 based on the currently
- * defined byte order. */
- unsigned data_encoding;
- if (p_e_ident_data_encoding==1 || p_e_ident_data_encoding==2) {
- data_encoding = ORDER_LSB==get_sex() ? 1 : 2;
- } else {
- data_encoding = p_e_ident_data_encoding;
- }
- host_to_disk(sex, data_encoding, &(disk->e_ident_data_encoding));
-
- host_to_disk(sex, p_e_ident_file_version, &(disk->e_ident_file_version));
+ host_to_disk(sex, p_e_ident_file_class, &(disk->e_ident_file_class));
+ host_to_disk(sex, p_e_ident_data_encoding, &(disk->e_ident_data_encoding));
+ host_to_disk(sex, p_e_ident_file_version, &(disk->e_ident_file_version));
ROSE_ASSERT(p_e_ident_padding.size() == NELMTS(disk->e_ident_padding));
for (size_t i=0; i<NELMTS(disk->e_ident_padding); i++)
disk->e_ident_padding[i] = p_e_ident_padding[i];
- host_to_disk(sex, p_e_type, &(disk->e_type));
- host_to_disk(sex, p_e_machine, &(disk->e_machine));
+ host_to_disk(sex, p_e_type, &(disk->e_type));
+ host_to_disk(sex, p_e_machine, &(disk->e_machine));
host_to_disk(sex, p_exec_format->get_version(), &(disk->e_version));
- host_to_disk(sex, get_entry_rva(), &(disk->e_entry));
+ host_to_disk(sex, get_entry_rva(), &(disk->e_entry));
if (get_segment_table()) {
host_to_disk(sex, get_segment_table()->get_offset(), &(disk->e_phoff));
} else {
@@ -440,29 +421,14 @@
ROSE_ASSERT(p_magic.size() == NELMTS(disk->e_ident_magic));
for (size_t i=0; i < NELMTS(disk->e_ident_magic); i++)
disk->e_ident_magic[i] = p_magic[i];
-
- unsigned ident_file_class=1;
- switch(get_word_size()) {
- case 4:
- ident_file_class = 1;
- break;
- case 8:
- ident_file_class = 2;
- break;
- default:
- ROSE_ASSERT(!"invalid word size");
- break;
- }
- host_to_disk(sex, ident_file_class, &(disk->e_ident_file_class));
-
- unsigned data_encoding = ORDER_LSB==get_sex() ? 1 : 2;
- host_to_disk(sex, data_encoding, &(disk->e_ident_data_encoding));
- host_to_disk(sex, p_e_ident_file_version, &(disk->e_ident_file_version));
+ host_to_disk(sex, p_e_ident_file_class, &(disk->e_ident_file_class));
+ host_to_disk(sex, p_e_ident_data_encoding, &(disk->e_ident_data_encoding));
+ host_to_disk(sex, p_e_ident_file_version,&(disk->e_ident_file_version));
ROSE_ASSERT(p_e_ident_padding.size() == NELMTS(disk->e_ident_padding));
for (size_t i=0; i<NELMTS(disk->e_ident_padding); i++)
disk->e_ident_padding[i] = p_e_ident_padding[i];
- host_to_disk(sex, p_e_type, &(disk->e_type));
- host_to_disk(sex, p_e_machine, &(disk->e_machine));
+ host_to_disk(sex, p_e_type, &(disk->e_type));
+ host_to_disk(sex, p_e_machine, &(disk->e_machine));
host_to_disk(sex, p_exec_format->get_version(), &(disk->e_version));
host_to_disk(sex, get_entry_rva(), &(disk->e_entry));
if (get_segment_table()) {
@@ -486,11 +452,10 @@
return disk;
}
-/* Update prior to parsing */
+/* Update prior to unparsing */
bool
SgAsmElfFileHeader::reallocate()
{
-
/* Reallocate superclass. This also calls reallocate() for all the sections associated with this ELF File Header. */
bool reallocated = SgAsmGenericHeader::reallocate();
@@ -515,6 +480,56 @@
reallocated = true;
}
+ /* Update ELF-specific file class data member from generic data. */
+ switch(get_word_size()) {
+ case 4:
+ p_e_ident_file_class = 1;
+ break;
+ case 8:
+ p_e_ident_file_class = 2;
+ break;
+ default:
+ ROSE_ASSERT(!"invalid word size");
+ break;
+ }
+
+ /* Byte order. According to the spec, valid values are 1 (little-endian) and 2 (big-endian). However, we've seen cases
+ * where a value of zero is used to indicate "native" order (loader assumes words are in the order of the machine on which
+ * the loader is running, and the ROSE ELF parser determines the order by looking at other fields in the header). Any
+ * original value other than 1 or 2 will be written to the new output; otherwise we choose 1 or 2 based on the currently
+ * defined byte order. */
+ if (p_e_ident_data_encoding==1 || p_e_ident_data_encoding==2) {
+ p_e_ident_data_encoding = ORDER_LSB==get_sex() ? 1 : 2;
+ }
+
+ /* Update ELF-specific file type from generic data. */
+ switch (p_exec_format->get_purpose()) {
+ case PURPOSE_UNSPECIFIED:
+ case PURPOSE_PROC_SPECIFIC:
+ case PURPOSE_OS_SPECIFIC:
+ case PURPOSE_OTHER:
+ /* keep as is */
+ break;
+ case PURPOSE_LIBRARY:
+ if (p_e_type==1 || p_e_type==3) {
+ /* keep as is */
+ } else {
+ p_e_type = 1;
+ }
+ break;
+ case PURPOSE_EXECUTABLE:
+ p_e_type = 2;
+ break;
+ case PURPOSE_CORE_DUMP:
+ p_e_type = 4;
+ }
+
+ /* Update ELF machine type. */
+ p_e_machine = isa_to_machine(get_isa());
+
+ /* The ELF header stores its own size */
+ p_e_ehsize = get_size();
+
return reallocated;
}
@@ -1382,7 +1397,7 @@
if (!try_again)
break;
}
-
+
#if 1 /*This will be going away shortly [RPM 2008-12-12]*/
/* Initialize links between sections */
for (size_t i = 0; i < entries.size(); i++) {
@@ -1394,20 +1409,11 @@
}
}
#endif
-#if 1 /*Above code will be replaced with something along these lines, but more generic. [RPM 2008-12-12]*/
- for (size_t i=0; i<is_parsed.size(); i++) {
- SgAsmElfSymbolSection *symbols = dynamic_cast<SgAsmElfSymbolSection*>(is_parsed[i]);
- if (symbols)
- symbols->finish_parsing();
+ /* Finish parsing sections now that we have basic info for all the sections. */
+ for (size_t i=0; i<is_parsed.size(); i++)
+ is_parsed[i]->finish_parsing();
- SgAsmElfDynamicSection *dynamic = dynamic_cast<SgAsmElfDynamicSection*>(is_parsed[i]);
- if (dynamic)
- dynamic->finish_parsing();
-
- }
-#endif
-
return this;
}
@@ -1436,14 +1442,20 @@
}
/* If the supplied section is a string table and the ELF Section Table doesn't have a string table associated with it yet,
- * then use the supplied section as the string table to hold the names of the sections. */
+ * then use the supplied section as the string table to hold the names of the sections. When this happens, all sections
+ * that are already defined in the ELF Section Table should have their names moved into the new string table. */
SgAsmElfStringSection *strsec = NULL;
if (fhdr->get_e_shstrndx()==0) {
strsec = dynamic_cast<SgAsmElfStringSection*>(section);
if (strsec) {
fhdr->set_e_shstrndx(section->get_id());
- } else {
- throw FormatError("ELF Section Table must have an ELF String Section to store section names");
+ SgAsmGenericSectionList *all = fhdr->get_sections();
+ for (size_t i=0; i<all->get_sections().size(); i++) {
+ SgAsmElfSection *s = dynamic_cast<SgAsmElfSection*>(all->get_sections()[i]);
+ if (s && s->get_id()>=0 && s->get_section_entry()!=NULL) {
+ s->allocate_name_to_storage(strsec);
+ }
+ }
}
} else {
strsec = dynamic_cast<SgAsmElfStringSection*>(fhdr->get_section_by_id(fhdr->get_e_shstrndx()));
@@ -1451,14 +1463,8 @@
}
/* Make sure the name is in the correct string table */
- std::string name;
- if (section->get_name()) {
- name = section->get_name()->get_string();
- section->get_name()->set_string(""); /*frees old string if stored*/
- }
- SgAsmStoredString *stored_name = new SgAsmStoredString(strsec->get_strtab(), 0);
- stored_name->set_string(name);
- section->set_name(stored_name);
+ if (strsec)
+ section->allocate_name_to_storage(strsec);
/* Create a new section table entry. */
SgAsmElfSectionTableEntry *shdr = new SgAsmElfSectionTableEntry;
@@ -1466,6 +1472,22 @@
section->set_section_entry(shdr);
}
+/** Make this section's name to be stored in the specified string table. */
+void
+SgAsmElfSection::allocate_name_to_storage(SgAsmElfStringSection *strsec)
+{
+ if (get_name()) {
+ SgAsmStoredString *old_stored = dynamic_cast<SgAsmStoredString*>(get_name());
+ if (!old_stored || old_stored->get_strtab()!=strsec->get_strtab()) {
+ /* Reallocate string to new string table */
+ SgAsmStoredString *new_stored = new SgAsmStoredString(strsec->get_strtab(), 0);
+ new_stored->set_string(get_name()->get_string());
+ get_name()->set_string(""); /*free old string*/
+ set_name(new_stored);
+ }
+ }
+}
+
/* Returns info about the size of the entries based on information already available. Any or all arguments may be null
* pointers if the caller is not interested in the value. */
rose_addr_t
@@ -1525,7 +1547,11 @@
void
SgAsmElfSectionTableEntry::update_from_section(SgAsmElfSection *section)
{
- p_sh_name = dynamic_cast<SgAsmStoredString*>(section->get_name())->get_offset();
+ if (section->get_name()->get_offset()==SgAsmGenericString::unallocated) {
+ p_sh_name = 0; /*not a stored string after all*/
+ } else {
+ p_sh_name = section->get_name()->get_offset();
+ }
set_sh_offset(section->get_offset());
if (get_sh_type()==SHT_NOBITS && section->is_mapped()) {
@@ -1536,6 +1562,7 @@
if (section->is_mapped()) {
set_sh_addr(section->get_mapped_rva());
+ set_sh_addralign(section->get_mapped_alignment());
if (section->get_mapped_wperm()) {
p_sh_flags |= 0x01;
} else {
Modified: branches/imperial/src/frontend/ExecFormats/ROSE_ExecGeneric.C
===================================================================
--- branches/imperial/src/frontend/ExecFormats/ROSE_ExecGeneric.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/ExecFormats/ROSE_ExecGeneric.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1853,6 +1853,13 @@
/* Delete children */
/*not a child*/; p_file = NULL;
delete p_name; p_name = NULL;
+
+ /* If the section has allocated its own local pool for the p_data member (rather than pointing into the SgAsmGenericFile)
+ * then free that now. */
+ if (local_data_pool!=NULL) {
+ free(local_data_pool);
+ local_data_pool = NULL;
+ }
}
/** Saves a reference to the original file data for a section based on the sections current offset and size. Once we do this,
@@ -1873,6 +1880,21 @@
}
}
+/** Sections typically point into the memory mapped, read-only file stored in the SgAsmGenericFile parent initialized by
+ * calling grab_content() (or indirectly by calling parse()). This is also the same data which is, by default, written back
+ * out to the new file during unparse(). Programs modify section content by either overriding the unparse() method or by
+ * modifying the p_data values. But in order to modify p_data we have to make sure that it's pointing to a read/write memory
+ * pool. This function replaces the read-only memory pool with a new one containing @p nbytes bytes of zeros. */
+unsigned char *
+SgAsmGenericSection::local_content(size_t nbytes)
+{
+ if (local_data_pool!=NULL)
+ free(local_data_pool);
+ local_data_pool = (unsigned char*)calloc(nbytes, 1);
+ p_data = SgSharedVector<unsigned char>(local_data_pool, nbytes);
+ return &(p_data[0]);
+}
+
/* Accessors for section name. Setting the section name makes the SgAsmGenericString node a child of the section. */
SgAsmGenericString *
SgAsmGenericSection::get_name() const
@@ -2151,6 +2173,9 @@
sprintf(mesg, "non-zero value truncated: buf[0x%zx]=0x%02x", i, ((const unsigned char*)buf)[i]);
#if 1
fprintf(stderr, "ROBB: SgAsmGenericSection::write(): %s\n", mesg);
+ fprintf(stderr, "in [%d] \"%s\"\n", get_id(), get_name()->c_str());
+ fprintf(stderr, "section is at file offset 0x%08"PRIx64" (%"PRIu64"), size 0x%"PRIx64" (%"PRIu64") bytes\n",
+ get_offset(), get_offset(), get_size(), get_size());
hexdump(stderr, get_offset()+offset, " ", (const unsigned char*)buf, bufsize);
abort(); /*DEBUGGING*/
#endif
@@ -2975,7 +3000,7 @@
ROSE_ASSERT(p_exec_format != NULL);
p_exec_format->dump(f, p, -1);
- fprintf(f, "%s%-*s = %s\n", p, w, "target", "<FIXME>");
+ fprintf(f, "%s%-*s = 0x%x\n", p, w, "ins_arch", p_isa);
fprintf(f, "%s%-*s = \"", p, w, "magic");
for (size_t i = 0; i < p_magic.size(); i++) {
Modified: branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/FortranParserActionROSE.C
===================================================================
--- branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/FortranParserActionROSE.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/FortranParserActionROSE.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -7297,7 +7297,7 @@
if (definedUnaryOp != NULL)
{
-#if 1
+#if 0
// Output debugging information about saved state (stack) information.
outputState("At TOP of R702 c_action_level_1_expr()");
#endif
@@ -7315,7 +7315,7 @@
// ROSE_ASSERT(false);
}
-#if 1
+#if 0
// Output debugging information about saved state (stack) information.
outputState("At BOTTOM of R702 c_action_level_1_expr()");
#endif
@@ -7341,7 +7341,7 @@
if (definedOp != NULL)
{
-#if 1
+#if 0
// Output debugging information about saved state (stack) information.
outputState("At TOP of R703 c_action_defined_unary_op()");
#endif
@@ -7360,7 +7360,7 @@
}
#endif
-#if 1
+#if 0
// Output debugging information about saved state (stack) information.
outputState("At BOTTOM of R703 c_action_defined_unary_op()");
#endif
@@ -8044,7 +8044,7 @@
if ( SgProject::get_verbose() > DEBUG_RULE_COMMENT_LEVEL )
printf ("In c_action_level_5_expr(): numDefinedBinaryOps = %d \n",numDefinedBinaryOps);
-#if 1
+#if 0
// Output debugging information about saved state (stack) information.
outputState("At BOTTOM of R717 c_action_level_5_expr()");
#endif
@@ -8187,7 +8187,7 @@
// DQ (12/14/2007): This should have been set by now! See test2007_114.f03
// build_implicit_program_statement_if_required();
-#if 1
+#if 0
// Output debugging information about saved state (stack) information.
outputState("At BOTTOM of R722 c_action_expr()");
#endif
@@ -13604,9 +13604,14 @@
else
{
// These will be marked as isSourcePositionUnavailableInFrontend = true and isOutputInCodeGeneration = true
- setSourcePosition(programDeclaration->get_parameterList());
- setSourcePosition(programDeclaration);
+ // setSourcePosition(programDeclaration->get_parameterList());
+ // setSourcePosition(programDeclaration);
+ // DQ (12/18/2008): These need to make marked with a valid file id (not NULL_FILE, internally),
+ // so that any attached comments and CPP directives will be properly attached.
+ setSourcePosition(programDeclaration->get_parameterList(),tokenList);
+ setSourcePosition(programDeclaration,tokenList);
+
// programDeclaration->get_startOfConstruct()->display("In c_action_program_stmt()");
// Mark these as compiler generated
Modified: branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/fortran_support.C
===================================================================
--- branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/fortran_support.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/OpenFortranParser_SAGE_Connection/fortran_support.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -3,103 +3,14 @@
#include "fortran_support.h"
//FMZ
+// Location of global variables
#include "FortranParserState.h"
SgSourceFile* OpenFortranParser_globalFilePointer = NULL;
using namespace std;
-#if 0 //FMZ: using decls/defs from "FortranParserState"
-// Global stack of scopes
-std::list<SgScopeStatement*> astScopeStack;
-
-// Global stack of expressions (not used in this program yet,
-// will be required for handling of expressions).
-std::list<SgExpression*> astExpressionStack;
-
-// Global stack of IR nodes
-// std::vector<SgNode*> astNodeStack;
-std::list<SgNode*> astNodeStack;
-
-// Global stack of lists of SgInitializedName containers nodes
-// std::list<SgInitializedNamePtrListPtr> astInitializedNameListStack;
-// std::list< std::list< std::string > > astNameListStack;
-// AstNameListStackType astNameListStack;
-
-// Global name stack (for tokens)
-AstNameListType astNameStack;
-
-// Global stack of SgDeclarationStatement IR nodes
-// std::vector<SgDeclarationStatement*> astDeclarationStatementStack;
-// std::list<SgDeclarationStatement*> astDeclarationStatementStack;
-
-// Global stack of SgType IR nodes
-std::list<SgType*> astTypeStack;
-
-// DQ (12/8/2007): Global stack of SgType IR nodes used to hold the base type seperately from the
-// the constructed types build from the base type. This is designed to handle the case of
-// "integer i(5),j" and "character*100 k,l" (see test2007_148.f)
-std::list<SgType*> astBaseTypeStack;
-
-// Intend stack used to holding intend specifiers
-std::list<int> astIntentSpecStack;
-
-// Array spec stack for holding the array specific specifiers
-std::list<int> astArraySpecStack;
-
-// Attribute spec for holding attributes
-std::list<int> astAttributeSpecStack;
-
-// DQ (4/4/2008): I think that type initialization shows that we can't have a separate astInitializerStack
-// since scalar initializers are placed onto the astExpressionStack and there is no rule to move them. So
-// we need a single stack for expressions and initializers to avoid loosing the order of their use.
-// See test2008_24.f90, which makes this point clear.
-// Global stack of expressions used for initialization of variables in declarations.
-// std::list<SgExpression*> astInitializerStack;
-
-// DQ (11/30/2007): Function attributes are held as tokens and not not defined as integer value codes (like other attributes)
-AstNameListType astFunctionAttributeStack;
-
-// Global stack for type kind expressions (should generally only be depth == 1)
-std::list<SgExpression*> astTypeKindStack;
-
-// Global stack for type parameters (should generally only be depth == 1)
-std::list<SgExpression*> astTypeParameterStack;
-
-// Global stack for label symbols
-std::list<SgLabelSymbol*> astLabelSymbolStack;
-
-// Global stack for SgIfStmt objects (allows scopes pushed onto stack to be clean off back to the initial SgIfStmt)
-std::list<SgIfStmt*> astIfStatementStack;
-
-// DQ (11/30/2007): Actual arguments have associated names which have to be recorded on to a separate stack.
-// test2007_162.h demonstrates this problems (and test2007_184.f)
-AstNameListType astActualArgumentNameStack;
-
-// DQ (10/1/2008): To simplify the handling of interfaces and the many functions
-// and function prototypes of function not defined in the interface we need attach
-// declarations and names to the SgInterfaceStatement as they are seen. Since this
-// is nt always just the last statement, it is easier to support this using a stack.
-
-// DQ (2/18/2008): This is the support for the Fortran include stack.
-// This is specific to the Fortran include mechanism, not the CPP include
-// mechanism. Though at some point a unified approach might be required.
-std::vector<std::string> astIncludeStack;
-
-#if 0
-// Global state used to accumulate the IO control spec for R913 list
-IO_Control_Spec* current_IO_Control_Spec = NULL;
-#endif
-
-// I am unclear if I need to keep the token stack...
-// This is the token list stack (for when we don't know how to build
-// any IR node and we are forced to defer the evaluation).
-// TokenListType globalTokenList;
-
-// SgFile* OpenFortranParser_globalFilePointer = NULL;
-#endif
-
std::list<SgInterfaceStatement*> astInterfaceStack;
#include "token.h"
@@ -112,11 +23,11 @@
tmp_token->line = line;
tmp_token->col = col;
tmp_token->type = type;
- /* Make a copy of our own to make sure it isn't freed on us. */
- if(text != NULL)
- tmp_token->text = strdup(text);
- else
- tmp_token->text = NULL;
+ /* Make a copy of our own to make sure it isn't freed on us. */
+ if (text != NULL)
+ tmp_token->text = strdup(text);
+ else
+ tmp_token->text = NULL;
return tmp_token;
}
@@ -125,6 +36,9 @@
string
getCurrentFilename()
{
+ // DQ (12/18/2008): Added comment: This function supports the Fortran "include"
+ // mechanism and is independent of the CPP specific "#include" mechanism.
+
#if 0
// Old code before implementation of Fortran include mechanism.
string filename = OpenFortranParser_globalFilePointer->get_sourceFileNameWithPath();
@@ -136,6 +50,14 @@
{
// Note that the original source file in OFP does not have to use an absolute file name so use the one from ROSE.
filename = OpenFortranParser_globalFilePointer->get_sourceFileNameWithPath();
+
+ if (OpenFortranParser_globalFilePointer->get_requires_C_preprocessor() == true)
+ {
+ // This source file requires CPP processing, so this would be the generated file with the "_preprocessed.f*" suffix.
+ filename = OpenFortranParser_globalFilePointer->generate_C_preprocessor_intermediate_filename(filename);
+
+ printf ("##### Using filename = %s for the name in the file_info for a CPP generated file \n",filename.c_str());
+ }
}
else
{
@@ -245,6 +167,7 @@
ROSE_ASSERT(lastToken->line > 0);
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -298,6 +221,7 @@
ROSE_ASSERT(token->line > 0);
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -346,6 +270,7 @@
ROSE_ASSERT(locatedNode->get_endOfConstruct() == NULL);
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -417,6 +342,7 @@
ROSE_ASSERT(lastToken->line > 0);
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -450,6 +376,7 @@
ROSE_ASSERT(token->line > 0);
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -496,6 +423,7 @@
ROSE_ASSERT(lastToken->line > 0);
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -546,6 +474,7 @@
delete targetLocatedNode->get_endOfConstruct();
#if 1
+ // This is required to handle both the Fortran specific "include" files and the CPP specific "#include" files.
string filename = getCurrentFilename();
#else
ROSE_ASSERT(OpenFortranParser_globalFilePointer != NULL);
@@ -586,7 +515,6 @@
}
}
-
ROSE_ASSERT(result != NULL);
return result;
}
Modified: branches/imperial/src/frontend/SageIII/Makefile.am
===================================================================
--- branches/imperial/src/frontend/SageIII/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -67,8 +67,8 @@
libsage3Sources = \
rose_attributes_list.C \
- attach_all_info.C \
attachPreprocessingInfo.C \
+ attachPreprocessingInfoTraversal.C \
attributeListMap.C \
manglingSupport.C \
sageSupport.C \
@@ -89,6 +89,9 @@
# stripWrapper.C
# grammarBaseClass.C
+# DQ (12/16/2008): Removed as part of rewrite of CPP and comment handling.
+# attach_all_info.C
+
noinst_LTLIBRARIES = libsage3.la
libsage3_la_SOURCES = $(libsage3Sources) preproc.ll rose_paths.h
@@ -128,6 +131,7 @@
include_HEADERS = \
sage3.h rose_attributes_list.h \
attachPreprocessingInfo.h \
+ attachPreprocessingInfoTraversal.h \
attach_all_info.h manglingSupport.h C++_include_files.h \
fixupCopy.h \
general_token_defs.h rose_paths.h rtiHelpers.h \
Modified: branches/imperial/src/frontend/SageIII/astMerge/collectAssociateNodes.C
===================================================================
--- branches/imperial/src/frontend/SageIII/astMerge/collectAssociateNodes.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/astMerge/collectAssociateNodes.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -205,7 +205,9 @@
case V_SgQualifiedNameType:
case V_SgTemplateType:
+#ifndef ROSE_USE_NEW_EDG_INTERFACE
case V_SgPartialFunctionType:
+#endif
case V_SgPartialFunctionModifierType:
// case V_SgUnknownMemberFunctionType:
{
@@ -215,6 +217,9 @@
break;
}
+ // DQ (1/6/2009): Added support for SgTypeSignedLongLong (only an error on 32 bit systems, not 64 bit systems).
+ case V_SgTypeSignedLongLong:
+
// These don't have types hidden internally (but they do have declarations)
// case V_SgClassType:
// case V_SgEnumType:
@@ -247,6 +252,10 @@
case V_SgTypeUnsignedShort:
case V_SgTypeVoid:
case V_SgTypeWchar:
+#ifdef ROSE_USE_NEW_EDG_INTERFACE
+ // Allow this as an IR node into the AST.
+ case V_SgPartialFunctionType:
+#endif
{
// Ignore these cases (they contain no base types)...
nodeList.insert(type);
@@ -424,11 +433,11 @@
if (functionTypeSymbol == NULL)
{
printf ("Note: no function type was found for functionDeclaration = %p = %s = %s \n",functionDeclaration,functionDeclaration->class_name().c_str(),SageInterface::get_name(functionDeclaration).c_str());
-#if 0
+#if 1
printf ("Error: functionType->get_mangled() = %s not found in symbol table \n",functionType->get_mangled().str());
printf ("functionDeclaration = %p = %s \n",functionDeclaration,functionDeclaration->get_name().str());
printf ("Location of problem function declaration: \n");
- // functionDeclaration->get_startOfConstruct()->display("Location of problem function declaration: debug");
+ functionDeclaration->get_startOfConstruct()->display("Location of problem function declaration: debug");
#endif
ROSE_ASSERT(functionDeclaration->get_startOfConstruct()->isCompilerGenerated() == true);
}
@@ -1796,6 +1805,7 @@
// case V_SgFile:
case V_SgSourceFile:
case V_SgBinaryFile:
+ case V_SgUnknownFile:
case V_SgSymbolTable:
case V_SgFunctionTypeTable:
{
@@ -1859,10 +1869,14 @@
case V_SgIfDirectiveStatement:
case V_SgElseDirectiveStatement:
case V_SgElseifDirectiveStatement:
+ case V_SgEndifDirectiveStatement:
case V_SgLineDirectiveStatement:
case V_SgWarningDirectiveStatement:
case V_SgErrorDirectiveStatement:
case V_SgEmptyDirectiveStatement:
+ case V_SgIdentDirectiveStatement:
+ case V_SgIncludeNextDirectiveStatement:
+ case V_SgLinemarkerDirectiveStatement:
{
printf ("Handling a CPP directive in AST merge... node = %s \n",node->class_name().c_str());
break;
Modified: branches/imperial/src/frontend/SageIII/astMerge/merge.C
===================================================================
--- branches/imperial/src/frontend/SageIII/astMerge/merge.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/astMerge/merge.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -629,7 +629,7 @@
int nextErrorCode = 0;
#if 1
- int fileIndex = 0;
+ // int fileIndex = 0;
SgFile* newFile = determineFileType( vector<string>(argv, argv+argc), nextErrorCode, project );
ROSE_ASSERT (newFile != NULL);
Modified: branches/imperial/src/frontend/SageIII/astPostProcessing/astPostProcessing.C
===================================================================
--- branches/imperial/src/frontend/SageIII/astPostProcessing/astPostProcessing.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/astPostProcessing/astPostProcessing.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -82,10 +82,40 @@
// interface is being used (it should produce correct, complete ASTs on its
// own and do its own fixups)
#ifdef ROSE_USE_NEW_EDG_INTERFACE
- bool doPostprocessing =
- (SageInterface::is_Fortran_language() == true) ||
- (SageInterface::is_PHP_language() == true);
- if (!doPostprocessing) {return;}
+
+ // Only do AST post-processing for C/C++
+ bool doPostprocessing = (SageInterface::is_Fortran_language() == true) || (SageInterface::is_PHP_language() == true);
+
+ // If this is C or C++ then we are using the new EDG translation and althrough fewer
+ // fixups should be required, some are still required.
+ if (doPostprocessing == false)
+ {
+ printf ("Postprocessing AST build using new EDG/Sage Translation Interface. \n");
+
+ // Reset and test and parent pointers so that it matches our definition
+ // of the AST (as defined by the AST traversal mechanism).
+ topLevelResetParentPointer (node);
+
+ // Another 2nd step to make sure that parents of even IR nodes not traversed
+ // can be set properly.
+ resetParentPointersInMemoryPool();
+
+ // Fixup the symbol tables (in each scope) and the global function type
+ // symbol table. This is less important for C, but required for C++.
+ // But since the new EDG interface has to handle C and C++ we don't
+ // setup the global function type table there to be uniform.
+ fixupAstSymbolTables(node);
+
+ // This resets the isModified flag on each IR node so that we can record
+ // where transformations are done in the AST. If any transformations on
+ // the AST are done, even just building it, this step should be the final
+ // step.
+ checkIsModifiedFlag(node);
+
+ printf ("DONE: Postprocessing AST build using new EDG/Sage Translation Interface. \n");
+
+ return;
+ }
#endif // ROSE_USE_NEW_EDG_INTERFACE -- do postprocessing unconditionally when the old EDG interface is used
// DQ (7/7/2005): Introduce tracking of performance of ROSE.
@@ -106,7 +136,7 @@
fixupNullPointersInAST(node);
// DQ (8/9/2005): Some function definitions in Boost are build without
- // a body (example in test2005_102.C, but it apears to work fine).
+ // a body (example in test2005_102.C, but it appears to work fine).
fixupFunctionDefinitions(node);
// DQ (8/10/2005): correct any template declarations mistakenly marked as compiler-generated
Modified: branches/imperial/src/frontend/SageIII/astPostProcessing/resetParentPointers.C
===================================================================
--- branches/imperial/src/frontend/SageIII/astPostProcessing/resetParentPointers.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/astPostProcessing/resetParentPointers.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1590,6 +1590,7 @@
// case V_SgFile:
case V_SgSourceFile:
case V_SgBinaryFile:
+ case V_SgUnknownFile:
{
ROSE_ASSERT(support->get_file_info() != NULL);
ROSE_ASSERT(support->get_file_info()->get_parent() != NULL);
Modified: branches/imperial/src/frontend/SageIII/astVisualization/wholeAST.C
===================================================================
--- branches/imperial/src/frontend/SageIII/astVisualization/wholeAST.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/astVisualization/wholeAST.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1179,7 +1179,7 @@
{
if (valueExp->get_parent() == NULL)
{
- printf ("Error: valueExp = %p valueExp->get_parent() == NULL \n",valueExp);
+ printf ("Error: valueExp = %p = %s valueExp->get_parent() == NULL \n",valueExp,valueExp->class_name().c_str());
valueExp->get_file_info()->display("Error: valueExp->get_parent() == NULL");
// In the case of a SgIntVal, we can try to output a little more information
@@ -1188,6 +1188,11 @@
{
printf ("Error: intVal = %d \n",intVal->get_value());
}
+ SgUnsignedLongVal* unsignedLongVal = isSgUnsignedLongVal(valueExp);
+ if (unsignedLongVal != NULL)
+ {
+ printf ("Error: unsignedLongVal = %lu \n",unsignedLongVal->get_value());
+ }
}
ROSE_ASSERT(valueExp->get_parent() != NULL);
// labelWithSourceCode = "\\n value = " + valueExp->unparseToString() + "\\n" + StringUtility::numberToString(node) + " ";
Modified: branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.C
===================================================================
--- branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,1132 +1,16 @@
-/****************************************************************************
-
-Remarks on Unparsing and on attaching preprocessing information to AST nodes
-----------------------------------------------------------------------------
-Markus Kowarschik, 10/2002
-
-There is a macro defined in sage3.h:
-#define USE_OLD_MECHANISM_OF_HANDLING_PREPROCESSING_INFO {1|0}
-
-If this macro is set to 1, then the *OLD* mechanism of unparsing
-preprocessing information is used: in the beginning of unparsing the
-AST, the function
-ROSEAttributesList *getPreprocessorDirectives(char *fileName);
-is called to build a list of preprocessor directives. This list is
-being searched for directives to be unparsed in the course of unparsing
-the AST.
-
-If this macro is set to 0, the *NEW* unparsing mechmism is used.
-
-The SgFile (always) constructor calls the function
-void attachPreprocessingInfo(SgFile *sageFilePtr);
-which in turn calls getPreprocessorDirectives (see above) and then
-invokes a tree traversal in order to attach the preprocessor directives
-(i.e., the preprocessingInfo objects) to located nodes in the AST.
-(Currently, we only attach preprocessingInfo objects to SgStatement
-objects.)
-
-For this purpose, I added a new data member
-attachedPreprocessingInfoType* attachedPreprocessingInfoPtr;
-to the SgLocatedNode class. This is done in ROSETTA/src/node.C.
-
-Furthermore, I added the corresponding access functions:
-void addToAttachedPreprocessingInfo(preprocessingInfo *prepInfoPtr);
-attachedPreprocessingInfoType* getAttachedPreprocessingInfo(void);
-to the SgLocatedNode class. This is done in ROSETTA/Grammar/LocatedNode.code.
-
-The tree traversal works as follows: whenever it hits a located node
-(currently: a statement), it checks if there is preprocessing info the
-line number of which is less or equal than the line number of the current
-located node (currently: of the current statement). If this is the case,
-the corresponding preprocessing info is attached to the current
-located node (currently: before the current statement), unparse flag: "before".
-All this is done in the evaluateInheritedAttribute member function of the
-derived tree traversal class.
-
-The evaluateSynthesizedAttribute member function deletes the list of
-preprocessingInfo objects as soon as the traversal returns to a SgFile
-object and attaches trailing preprocessing information to the last located
-node (currently to the last statement) that has been visited in
-the file (unparse flag: "after").
-
-Node that the preprocessingInfo objects are always attached to AST nodes.
-By switching the USE_OLD_MECHANISM_OF_HANDLING_PREPROCESSING_INFO flag,
-you only change the mechanism which the unparser is based on!
-If USE_OLD_MECHANISM_OF_HANDLING_PREPROCESSING_INFO is set to 1, then
-the unparser simply ignores the preprocessingInfo objects that have
-been attached to the AST nodes.
-
-Problems with the handling of preprocessing information can be
-found in the directory ROSE/TESTS/KnownBugs/AttachPreprocessingInfo.
-
-****************************************************************************/
-
-// This file implements the extraction of the attributes (comments and
-// preprocessor directives) from the original source file and their insertion
-// into the AST data structure.
-// The idea is to re-introduce them (as correctly as possible) when the
-// transformed AST is unparsed later on.
-
-// #include "attachPreprocessingInfo.h"
-// #include "sage3.h"
#include "rose.h"
// DQ (12/31/2005): This is OK if not declared in a header file
using namespace std;
-typedef boost::wave::cpplexer::lex_token<> token_type;
-typedef std::vector<token_type> token_container;
-typedef std::list<token_type> token_list_container;
-typedef std::vector<std::list<token_type> > token_container_container;
+// Local typedefs used in this file only...
+typedef boost::wave::cpplexer::lex_token<> token_type;
+typedef std::vector<token_type> token_container;
+typedef std::list<token_type> token_list_container;
+typedef std::vector<std::list<token_type> > token_container_container;
-// Debug flag
-#define DEBUG_ATTACH_PREPROCESSING_INFO 0
-// DQ (9/24/2007): Moved function definition to source file from header file.
-// AS(011306) Constructor for use of Wave Preprocessor
-AttachPreprocessingInfoTreeTrav::AttachPreprocessingInfoTreeTrav( std::map<std::string,ROSEAttributesList*>* attrMap)
- {
- previousLocNodePtr = NULL;
- currentListOfAttributes = NULL;
- sizeOfCurrentListOfAttributes = 0;
- // currentFileName = NULL;
- currentFileNameId = -1;
- ROSE_ASSERT(attrMap != NULL);
- currentMapOfAttributes = attrMap;
- use_Wave = true;
- start_index = 0;
- }
-
-// DQ (9/24/2007): Moved function definition to source file from header file.
-// Constructor
-AttachPreprocessingInfoTreeTrav::AttachPreprocessingInfoTreeTrav()
- {
- previousLocNodePtr = NULL;
- currentListOfAttributes = NULL;
- sizeOfCurrentListOfAttributes = 0;
- // currentFileName = NULL;
- currentMapOfAttributes = NULL;
- use_Wave = false;
- start_index = 0;
- }
-
-void
-AttachPreprocessingInfoTreeTrav::iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( SgLocatedNode* locatedNode, int lineNumber, PreprocessingInfo::RelativePositionType location, bool reset_start_index )
- {
- // DQ (11/23/2008): Added comment.
- // This is the main function called to insert all PreprocessingInfo objects into IR nodes. This function currently
- // adds the PreprocessingInfo objects as attributes, but will be modified to insert the CPP directive specific
- // PreprocessingInfo objects as separate IR nodes and leave PreprocessingInfo objects that are comments inserts
- // as attributes. Note that attributes imply PreprocessingInfo specific atributes and not the more general
- // mechanism available in ROSE for user defined attributes to be saved into the AST.
-
-#if 0
- // Debugging information...
- printf ("In iterateOverListAndInsertPrev... locatedNode = %s lineNumber = %d location = %d \n",locatedNode->sage_class_name(),lineNumber,(int)location);
- if ( dynamic_cast<SgLocatedNode*>(locatedNode) != NULL )
- {
- printf ("starting line number = %d \n",locatedNode->get_startOfConstruct()->get_line());
- if (locatedNode->get_endOfConstruct() != NULL)
- printf ("ending line number = %d \n",locatedNode->get_endOfConstruct()->get_line());
- }
- else
- {
- printf ("locatedNode is not a SgLocatedNode object \n");
- }
-#endif
-
-#if DEBUG_ATTACH_PREPROCESSING_INFO
- // Debugging information...
- {
- int line = locatedNode->get_startOfConstruct()->get_line();
- int col = locatedNode->get_startOfConstruct()->get_col();
- cout << "Visiting SgStatement node: " << line << ", " << col << " -> ";
- cout << getVariantName(locatedNode->variantT()) << endl;
- }
-#if 0
- printf("-----> Address: %p\n", locatedNode);
- cout << "-----> Filename: " << locatedNode->get_file_info()->get_filename() << endl;
- if (locatedNode->getAttachedPreprocessingInfo() == NULL)
- cout << "-----> No PreprocessingInfo objects attached yet" << endl;
- else
- cout << "-----> There are already PreprocessingInfo objects attached to this AST node" << endl;
-#endif
- cout << "Traversing current list of attributes of length " << sizeOfCurrentListOfAttributes << endl;
-#endif
-
- // for ( int i = 0; i < sizeOfCurrentListOfAttributes; i++ )
- // AS(09/21/07) Because the AttachAllPreprocessingInfoTreeTrav can call the evaluateInheritedAttribute(..)
- // which calls this function the start_index can not be static for this function. Instead it is made
- // a class member variable for AttachPreprocessingInfoTreeTrav so that it can be reset by AttachAllPreprocessingInfoTreeTrav
- // when processing a new file.
-
- // static int start_index = 0;
- for ( int i = start_index; i < sizeOfCurrentListOfAttributes; i++ )
- {
- PreprocessingInfo *currentPreprocessingInfoPtr = (*currentListOfAttributes)[i];
-#if 0
- if ( currentPreprocessingInfoPtr != NULL )
- printf ("currentPreprocessingInfoPtr->getLineNumber() = %d lineNumber = %d \n",currentPreprocessingInfoPtr->getLineNumber(),lineNumber);
-#endif
-#if 0
- printf ("currentPreprocessingInfoPtr->getLineNumber() = %d lineNumber = %d internalString = %s \n",currentPreprocessingInfoPtr->getLineNumber(),lineNumber,currentPreprocessingInfoPtr->getString().c_str());
-#endif
-
- bool attachCommentOrDirective = (currentPreprocessingInfoPtr != NULL) && (currentPreprocessingInfoPtr->getLineNumber() <= lineNumber);
-
- if ( attachCommentOrDirective == true )
- {
-#if 0
- printf ("Attaching \"%s\" (from line# %d) to %s locatedNode = %p = %s = %s at line %d \n",
- currentPreprocessingInfoPtr->getString().c_str(),
- currentPreprocessingInfoPtr->getLineNumber(),
- (locatedNode->get_file_info()->isCompilerGenerated() == true) ? "compiler-generated" : "non-compiler-generated",
- locatedNode,
- locatedNode->class_name().c_str(),SageInterface::get_name(locatedNode).c_str(),
- (locatedNode->get_file_info()->isCompilerGenerated() == true) ? -1 : locatedNode->get_file_info()->get_line());
- // printf ("locatedNode->unparseToString() = %s \n",locatedNode->unparseToString().c_str());
-#endif
-
- // Mark this PreprocessingInfo object as having been placed into the AST
- // It might make more sense to remove it from the list so it doesn't have
- // to be traversed next time.
- // currentPreprocessingInfoPtr->setHasBeenCopied();
- currentListOfAttributes->getList()[i] = NULL;
-
- // DQ (4/13/2007): If we are going to invalidate the list of accumulated attributes then we can start
- // next time at the next index (at least). This removes the order n^2 complexity of traversing over the whole loop.
- start_index = i+1;
-
- // Mark the location relative to the current node where the PreprocessingInfo
- // object should be unparsed (before or after) relative to the current locatedNode
- currentPreprocessingInfoPtr->setRelativePosition(location);
-#if 1
- locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
-#else
- // If this is a CPP directive then add it as an IR nodes so that we can position
- // CPP directives in the AST as new IR nodes instead of as comment.
-
- // I don't think we want to call get scope since we want the structural scope of the
- // statement in the file (get_parent()) and not the languages concept of scope (get_scope()).
- // SgScopeStatement* localScope = isSgScopeStatement(locatedNode->get_parent());
- // if (localScope != NULL)
-
- PreprocessingInfo::DirectiveType directive = currentPreprocessingInfoPtr->getTypeOfDirective();
- switch (directive)
- {
- // Trap this case out as an error...
- case PreprocessingInfo::CpreprocessorUnknownDeclaration:
- {
- // I think this is an error...
- // locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
- printf ("Error: directive == PreprocessingInfo::CpreprocessorUnknownDeclaration \n");
- ROSE_ASSERT(false);
- break;
- }
-
- // These are things that we don't have to worry about in Fortran CPP handling.
- case PreprocessingInfo::C_StyleComment:
- case PreprocessingInfo::CplusplusStyleComment:
- case PreprocessingInfo::FortranStyleComment:
- case PreprocessingInfo::CpreprocessorBlankLine:
- case PreprocessingInfo::ClinkageSpecificationStart:
- case PreprocessingInfo::ClinkageSpecificationEnd:
- {
- locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
- break;
- }
-
- // These are the CPP directives that I want to focus on support for in Fortran (and C/C++).
- case PreprocessingInfo::CpreprocessorIncludeDeclaration:
- case PreprocessingInfo::CpreprocessorIncludeNextDeclaration:
- case PreprocessingInfo::CpreprocessorDefineDeclaration:
- case PreprocessingInfo::CpreprocessorUndefDeclaration:
- case PreprocessingInfo::CpreprocessorIfdefDeclaration:
- case PreprocessingInfo::CpreprocessorIfndefDeclaration:
- case PreprocessingInfo::CpreprocessorIfDeclaration:
- case PreprocessingInfo::CpreprocessorDeadIfDeclaration:
- case PreprocessingInfo::CpreprocessorElseDeclaration:
- case PreprocessingInfo::CpreprocessorElifDeclaration:
- case PreprocessingInfo::CpreprocessorEndifDeclaration:
- case PreprocessingInfo::CpreprocessorLineDeclaration:
- case PreprocessingInfo::CpreprocessorErrorDeclaration:
- case PreprocessingInfo::CpreprocessorWarningDeclaration:
- case PreprocessingInfo::CpreprocessorEmptyDeclaration:
- case PreprocessingInfo::CpreprocessorIdentDeclaration:
- case PreprocessingInfo::CpreprocessorCompilerGenerateLineDeclaration:
- {
- // These are CPP directives that we want to have generate IR nodes into the AST.
- SgC_PreprocessorDirectiveStatement* cppDirective = SgC_PreprocessorDirectiveStatement::createDirective(currentPreprocessingInfoPtr);
- ROSE_ASSERT(cppDirective != NULL);
-
- ROSE_ASSERT(cppDirective->get_startOfConstruct() != NULL);
- ROSE_ASSERT(cppDirective->get_endOfConstruct() != NULL);
-
- SgScopeStatement* localScope = isSgScopeStatement(locatedNode);
- if (localScope != NULL)
- {
- printf ("Calling SageInterface::prependStatement(cppDirective = %s,localScope = %s) \n",cppDirective->class_name().c_str(),localScope->class_name().c_str());
- SageInterface::prependStatement(cppDirective,localScope);
- }
- else
- {
- // Note that the AST traversal will not see this as the next statement since it
- // traverses a copy of the list of statements to avoid such side-effects.
- SgStatement* currentStatement = isSgStatement(locatedNode);
- if (currentStatement != NULL)
- {
- printf ("Calling SageInterface::insertStatementAfter(currentStatement = %s,cppDirective = %s) \n",currentStatement->class_name().c_str(),cppDirective->class_name().c_str());
- SageInterface::insertStatementAfter(currentStatement,cppDirective);
- }
- else
- {
- printf ("Error: locatedNode is not a statement (locatedNode = %s) \n",locatedNode->class_name().c_str());
- ROSE_ASSERT(false);
- }
- }
-
- break;
- }
-
- case PreprocessingInfo::LineReplacement:
- {
- printf ("I am unclear where this PreprocessingInfo::LineReplacement is used! \n");
- locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
- break;
- }
-
- // I think these are Wave specific so handle them as though this was C/C++ code.
- case PreprocessingInfo::CSkippedToken:
- case PreprocessingInfo::CMacroCall:
- case PreprocessingInfo::CMacroCallStatement:
- {
- printf ("I think these are WAVE specific! directiveTypeName = %s \n",PreprocessingInfo::directiveTypeName(directive).c_str());
- locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
- break;
- }
-
- // The default should be an error...
- default:
- {
- printf ("Error: directive not handled directiveTypeName = %s \n",PreprocessingInfo::directiveTypeName(directive).c_str());
- ROSE_ASSERT(false);
- }
- }
-#endif
-
- // delete currentPreprocessingInfoPtr;
- // currentPreprocessingInfoPtr = NULL;
-
- // debugging info
- // printOutComments(locatedNode);
- }
- }
-
- // DQ (4/13/2007): The evaluation of the synthesized attribute for a SgFile will trigger the reset of the start index to 0.
- if (reset_start_index == true)
- start_index = 0;
- }
-
-
-// DQ (11/23/2008): This is a static function
-SgC_PreprocessorDirectiveStatement* SgC_PreprocessorDirectiveStatement::createDirective ( PreprocessingInfo* currentPreprocessingInfo )
- {
- // This is the new factory interface to build CPP directives as IR nodes.
- PreprocessingInfo::DirectiveType directive = currentPreprocessingInfo->getTypeOfDirective();
-
- SgC_PreprocessorDirectiveStatement* cppDirective = new SgEmptyDirectiveStatement();
- switch(directive)
- {
- case PreprocessingInfo::CpreprocessorUnknownDeclaration:
- {
- // I think this is an error...
- // locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
- printf ("Error: directive == PreprocessingInfo::CpreprocessorUnknownDeclaration \n");
- ROSE_ASSERT(false);
- break;
- }
-
- case PreprocessingInfo::C_StyleComment:
- case PreprocessingInfo::CplusplusStyleComment:
- case PreprocessingInfo::FortranStyleComment:
- case PreprocessingInfo::CpreprocessorBlankLine:
- case PreprocessingInfo::ClinkageSpecificationStart:
- case PreprocessingInfo::ClinkageSpecificationEnd:
- case PreprocessingInfo::CpreprocessorIncludeDeclaration:
- case PreprocessingInfo::CpreprocessorIncludeNextDeclaration:
- case PreprocessingInfo::CpreprocessorDefineDeclaration:
- case PreprocessingInfo::CpreprocessorUndefDeclaration:
- case PreprocessingInfo::CpreprocessorIfdefDeclaration:
- case PreprocessingInfo::CpreprocessorIfndefDeclaration:
- case PreprocessingInfo::CpreprocessorIfDeclaration:
- case PreprocessingInfo::CpreprocessorDeadIfDeclaration:
- case PreprocessingInfo::CpreprocessorElseDeclaration:
- case PreprocessingInfo::CpreprocessorElifDeclaration:
- case PreprocessingInfo::CpreprocessorEndifDeclaration:
- case PreprocessingInfo::CpreprocessorLineDeclaration:
- case PreprocessingInfo::CpreprocessorErrorDeclaration:
- case PreprocessingInfo::CpreprocessorWarningDeclaration:
- case PreprocessingInfo::CpreprocessorEmptyDeclaration:
- case PreprocessingInfo::CpreprocessorIdentDeclaration:
- case PreprocessingInfo::CpreprocessorCompilerGenerateLineDeclaration:
- {
- cppDirective = new SgEmptyDirectiveStatement();
- break;
- }
-
- default:
- {
- printf ("Error: directive not handled directiveTypeName = %s \n",PreprocessingInfo::directiveTypeName(directive).c_str());
- ROSE_ASSERT(false);
- }
- }
-
- ROSE_ASSERT(cppDirective != NULL);
-
- // Set the defining declaration to be a self reference...
- cppDirective->set_definingDeclaration(cppDirective);
-
- // Build source position information...
- cppDirective->set_startOfConstruct(new Sg_File_Info(*(currentPreprocessingInfo->get_file_info())));
- cppDirective->set_endOfConstruct(new Sg_File_Info(*(currentPreprocessingInfo->get_file_info())));
-
- return cppDirective;
- }
-
-
-void
-AttachPreprocessingInfoTreeTrav::setupPointerToPreviousNode (SgLocatedNode* currentLocNodePtr )
- {
- // If we are at a SgCtorInitializerList then since it is visited last
- // (after the definition) leave the previousLocNodePtr referenced to
- // the function definition.
- if ( (dynamic_cast<SgForInitStatement*> (currentLocNodePtr) == NULL) &&
- (dynamic_cast<SgTypedefSeq*> (currentLocNodePtr) == NULL) &&
- (dynamic_cast<SgCatchStatementSeq*> (currentLocNodePtr) == NULL) &&
- (dynamic_cast<SgFunctionParameterList*>(currentLocNodePtr) == NULL) &&
- (dynamic_cast<SgCtorInitializerList*> (currentLocNodePtr) == NULL) )
- {
- previousLocNodePtr = currentLocNodePtr;
- }
- else
- {
- SgStatement* currentStatement = dynamic_cast<SgStatement*>(currentLocNodePtr);
- ROSE_ASSERT (currentStatement != NULL);
- SgStatement* parentStatement = isSgStatement(currentStatement->get_parent());
- ROSE_ASSERT (parentStatement != NULL);
-
- // printf ("parentStatement = %s \n",parentStatement->sage_class_name());
-#if 1
- previousLocNodePtr = parentStatement;
-#else
- // DQ (11/23/2008): I think that we can eliminate this code since we have the tests
- // below to make sure that no IR node is in the set defined by: (SgForInitStatement,
- // SgTypedefSeq, SgCatchStatementSeq, SgFunctionParameterList, SgCtorInitializerList).
- switch (currentLocNodePtr->variantT())
- {
- case V_SgForInitStatement:
- previousLocNodePtr = parentStatement;
- break;
- case V_SgTypedefSeq:
- previousLocNodePtr = parentStatement;
- printf ("Exiting in SgTypedefSeq case \n");
- ROSE_ABORT();
- break;
-
- case V_SgCatchStatementSeq:
- previousLocNodePtr = parentStatement;
- break;
-
- case V_SgFunctionParameterList:
- previousLocNodePtr = parentStatement;
- break;
-
- case V_SgCtorInitializerList:
- previousLocNodePtr = parentStatement;
- break;
-
- default:
- printf ("AttachPreprocessingInfoTreeTrav::setupPointerToPreviousNode(): default found in switch statement currentLocNodePtr = %s \n",currentLocNodePtr->class_name().c_str());
- ROSE_ABORT();
- break;
- }
-#endif
- }
-
- // Nodes that should not have comments attached (since they are not unparsed directly)
- ROSE_ASSERT (dynamic_cast<SgForInitStatement*> (previousLocNodePtr) == NULL);
- ROSE_ASSERT (dynamic_cast<SgTypedefSeq*> (previousLocNodePtr) == NULL);
- ROSE_ASSERT (dynamic_cast<SgCatchStatementSeq*> (previousLocNodePtr) == NULL);
- ROSE_ASSERT (dynamic_cast<SgFunctionParameterList*>(previousLocNodePtr) == NULL);
- ROSE_ASSERT (dynamic_cast<SgCtorInitializerList*> (previousLocNodePtr) == NULL);
- }
-
-
-// Member function: evaluateInheritedAttribute
-AttachPreprocessingInfoTreeTraversalInheritedAttrribute
-AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute (
- SgNode *n,
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh)
- {
- SgFile *currentFilePtr = NULL;
- SgLocatedNode *currentLocNodePtr = NULL;
- int line = 0, col = 0;
- // PreprocessingInfo *currentPreprocessingInfoPtr;
-
-#if 0
- printf ("In AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): n->class_name() = %s \n",n->class_name().c_str());
-#endif
-
- // DQ (12/10/2007): Declare Fortran specific lexical pass function explicitly.
- // extern int getFortranFixedFormatPreprocessorDirectives( std::string fileName );
- // extern int getFortranFreeFormatPreprocessorDirectives ( std::string fileName );
-#ifdef USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
- extern std::list <stream_element*>* getFortranFixedFormatPreprocessorDirectives( std::string fileName );
- extern std::list <stream_element*>* getFortranFreeFormatPreprocessorDirectives ( std::string fileName );
-#endif
-
- // Check if current AST node is an SgFile object
- // if ((currentFilePtr = dynamic_cast<SgFile*>(n)) != NULL)
- currentFilePtr = isSgFile(n);
- if ( currentFilePtr != NULL )
- {
- // Current AST node is an SgFile object, generate the corresponding list of attributes
-#if DEBUG_ATTACH_PREPROCESSING_INFO
- cout << "=== Visiting SgFile node and building current list of attributes ===" << endl;
-#endif
- currentFileNameId = currentFilePtr->get_file_info()->get_file_id();
-
- // currentListOfAttributes = getPreprocessorDirectives(currentFileName);
-
- if (use_Wave == false)
- {
- // DQ (4/12/2007): Introduce tracking of performance of ROSE.
- TimingPerformance timer ("AST evaluateInheritedAttribute (use_Wave == false):");
-
- // AS(011306) don't need this with the Wave preprocessor (already done in one pass)
- // currentListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- if (currentFilePtr->get_Fortran_only() == true)
- {
-#ifdef USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
- // This is either of two different kinds of Fortran program: fixed format or free format
- // * fix format is used for older Fortran code, F77 and earlier, and
- // * free format is used for newer codes, F90 and later
- if ( SgProject::get_verbose() > 1 )
- {
- printf ("Found a Fortran program (calling lexical pass to gather the Fortran specific token stream) \n");
- }
-
- // If it is not explicitly fixed form, then assume it is free form input.
- // if (currentFilePtr->get_fixedFormat() == true)
- if (currentFilePtr->get_inputFormat() == SgFile::e_fixed_form_output_format)
- {
- if ( SgProject::get_verbose() > 1 )
- {
- printf ("Fortran code assumed to be in fixed format form (skipping translation of tokens) \n");
- }
-
- ROSE_ASSERT(currentFilePtr != NULL);
- string fileNameForDirectivesAndComments = currentFilePtr->get_sourceFileNameWithPath();
-
- // For now we call the lexical pass on the fortran file, but we don't yet translate the tokens.
- // currentListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- // getFortranFixedFormatPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- // LexTokenStreamTypePointer lex_token_stream = getFortranFixedFormatPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- LexTokenStreamTypePointer lex_token_stream = getFortranFixedFormatPreprocessorDirectives( fileNameForDirectivesAndComments );
- ROSE_ASSERT(lex_token_stream != NULL);
-
- // Build an empty list while we skip the translation of tokens
- currentListOfAttributes = new ROSEAttributesList();
-
- // Attach the token stream to the AST
- currentListOfAttributes->set_rawTokenStream(lex_token_stream);
-#if 1
- // DQ (11/23/2008): This is the new support to collect CPP directives and comments from Fortran applications.
- // printf ("Calling collectPreprocessorDirectivesAndCommentsForAST() to collect CPP directives for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
- currentListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_Fortran77_language);
- // printf ("DONE: Calling collectPreprocessorDirectivesAndCommentsForAST() to collect CPP directives for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
-#endif
-#if 0
- // DQ (11/19/2008): This code has been replaced by collectPreprocessorDirectivesAndCommentsForAST().
- // Process the raw token stream into the PreprocessorDirectives and Comment list required to be inserted into the AST.
- // currentListOfAttributes->collectFixedFormatPreprocessorDirectivesAndCommentsForAST(currentFilePtr->get_sourceFileNameWithPath());
- currentListOfAttributes->collectFixedFormatPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments);
-#endif
- }
- else
- {
- if ( SgProject::get_verbose() > 1 )
- {
- printf ("Fortran code assumed to be in free format form (skipping translation of tokens) \n");
- }
-
- if (currentFilePtr->get_inputFormat() != SgFile::e_free_form_output_format)
- {
- printf ("Note: In lexical pass, Fortran code assumed to be free form, but not marked explicitly as such! currentFilePtr->get_inputFormat() = %d \n",currentFilePtr->get_inputFormat());
- }
-
- // For now we call the lexical pass on the fortran file, but we don't yet translate the tokens.
- // currentListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- // getFortranFreeFormatPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- string fileNameForTokenStream = Sg_File_Info::getFilenameFromID(currentFileNameId);
- // printf ("Calling getFortranFreeFormatPreprocessorDirectives() for fileNameForTokenStream = %s \n",fileNameForTokenStream.c_str());
- LexTokenStreamTypePointer lex_token_stream = getFortranFreeFormatPreprocessorDirectives( fileNameForTokenStream );
- ROSE_ASSERT(lex_token_stream != NULL);
-
- // Build an empty list while we skip the translation of tokens
- currentListOfAttributes = new ROSEAttributesList();
-
- // Attach the token stream to the AST
- currentListOfAttributes->set_rawTokenStream(lex_token_stream);
- ROSE_ASSERT(currentListOfAttributes->get_rawTokenStream() != NULL);
-
- // printf ("Fortran Token List Size: currentListOfAttributes->get_rawTokenStream()->size() = %zu \n",currentListOfAttributes->get_rawTokenStream()->size());
-
- // Process the raw token stream into the PreprocessorDirectives and Comment list required to be inserted into the AST.
- // currentListOfAttributes->generatePreprocessorDirectivesAndCommentsForAST(currentFilePtr);
- string fileNameForDirectivesAndComments = currentFilePtr->get_sourceFileNameWithPath();
-
- // DQ (11/23/2008): This is the new support to collect CPP directives and comments from Fortran applications.
- // printf ("Calling collectPreprocessorDirectivesAndCommentsForAST() to collect CPP directives for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
- currentListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_Fortran9x_language);
-
-#if 0
- printf ("Done with processing of separate lexical pass to gather CPP directives \n");
- ROSE_ASSERT(false);
-#endif
-#if 0
- // DQ (11/19/2008): This code has been replaced by collectPreprocessorDirectivesAndCommentsForAST().
- printf ("Calling generatePreprocessorDirectivesAndCommentsForAST() for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
- currentListOfAttributes->generatePreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments);
-#else
- // printf ("Skipping the comments in the fortran file! \n");
-#endif
- }
-
- if ( SgProject::get_verbose() > 1 )
- {
- printf ("Done with separate lexical pass to gather Fortran specific token stream \n");
- }
-
- if ( SgProject::get_verbose() > 1 )
- {
- printf ("Done with processing of separate lexical pass to gather Fortran specific CPP directives and comments from the token stream \n");
- }
-#if 0
- printf ("Done with processing of separate lexical pass to gather Fortran specific CPP directives and comments from the token stream \n");
- ROSE_ASSERT(false);
-#endif
-
-#else // for !USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
- fprintf(stderr, "Fortran parser not enabled\n");
- abort();
-#endif // USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
- }
- else
- {
- // Else we assume this is a C or C++ program (for which the lexical analysis is identical)
- // The lex token stream is now returned in the ROSEAttributesList object.
-
- string fileNameForDirectivesAndComments = currentFilePtr->get_sourceFileNameWithPath();
-
-#if 1
- // DQ (11/23/2008): This is part of CPP handling for Fortran, but tested on C and C++ codes aditionally, (it is redundant for C and C++).
- // This is a way of testing the extraction of CPP directives (on C and C++ codes, so that it is more agressively tested).
- // Since this is a redundant test, it can be removed in later development (its use is only a performance issue).
- currentListOfAttributes = new ROSEAttributesList();
-
- // This call is just a test, this function is defined for use on Fortran. For C and C++ we have alternative methods to extract the CPP directives and comments.
- // printf ("Call collectPreprocessorDirectivesAndCommentsForAST to test C and C++ preprocessor directive collaction \n");
- currentListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_C_language);
- // printf ("DONE: Call collectPreprocessorDirectivesAndCommentsForAST to test C and C++ preprocessor directive collaction \n");
-#endif
-
- // This function has been modified to clear any existing list of PreprocessingInfo*
- // objects (so that we can test the function: collectPreprocessorDirectivesAndCommentsForAST()).
- // currentListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
- currentListOfAttributes = getPreprocessorDirectives(fileNameForDirectivesAndComments);
- }
-
- // printf ("AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): currentListOfAttributes = %p size() = %d \n",currentListOfAttributes,(int)currentListOfAttributes->size());
- }
- else
- {
- // This is the case of: (use_Wave == true).
-
- // AS(011306) fetch the list of attributes from the Wave output
- std::string currentStringFilename( Sg_File_Info::getFilenameFromID(currentFileNameId) );
-
- ROSE_ASSERT(currentMapOfAttributes != NULL);
- if (currentMapOfAttributes->find(currentStringFilename) == currentMapOfAttributes->end())
- {
- // There is no existing list for this file, so build an empty list.
- currentListOfAttributes = new ROSEAttributesList();
- }
- else
- {
- // If there already exists a list for the current file then get that list.
- ROSE_ASSERT( currentMapOfAttributes->find(currentStringFilename)->second != NULL);
- currentListOfAttributes = currentMapOfAttributes->find(currentStringFilename)->second;
- }
- }
-
- ROSE_ASSERT(currentListOfAttributes != NULL);
- sizeOfCurrentListOfAttributes = currentListOfAttributes->getLength();
- }
- else
- {
- // The current node is NOT a SgFile IR node.
-
- // Move attributes from the list of attributes into the collection of the current AST nodes,
- // we only consider statements for the moment, but this needs to be refined further on.
- // Probably we will have to consider each SgLocatedNode IR node within the AST.
- if (dynamic_cast<SgStatement*>(n) != NULL)
- {
- // The following should always work since each statement is a located node
- currentLocNodePtr = dynamic_cast<SgLocatedNode*>(n);
- ROSE_ASSERT(currentLocNodePtr != NULL);
-
- // Attach the comments only to nodes from the same file
- int fileNameId = currentFileNameId;
- ROSE_ASSERT(currentLocNodePtr->get_file_info());
-
- // DQ (6/20/2005): Compiler generated is not enough, it must be marked for output explicitly
- // bool isCompilerGenerated = currentLocNodePtr->get_file_info()->isCompilerGenerated();
- bool isCompilerGenerated = currentLocNodePtr->get_file_info()->isCompilerGeneratedNodeToBeUnparsed();
- // JJW (6/25/2008): These are always flagged as "to be
- // unparsed", even if they are not unparsed because their
- // corresponding declarations aren't unparsed
- if (isSgClassDefinition(currentLocNodePtr) ||
- isSgFunctionDefinition(currentLocNodePtr)) {
- SgLocatedNode* ln = isSgLocatedNode(currentLocNodePtr->get_parent());
- Sg_File_Info* parentFi = ln ? ln->get_file_info() : NULL;
- if (parentFi && parentFi->isCompilerGenerated() && !parentFi->isCompilerGeneratedNodeToBeUnparsed()) {
- isCompilerGenerated = false;
- }
- }
- bool isTransformation = currentLocNodePtr->get_file_info()->isTransformation();
-
- // Try to not call get_filename() if it would be inappropriate (either when isCompilerGenerated || isTransformation)
-
- // DQ (10/27/2007): Initialized to -1 upon suggestion by Andreas.
- int fileIdForOriginOfCurrentLocatedNode = -1;
- if ( !isCompilerGenerated && !isTransformation )
- fileIdForOriginOfCurrentLocatedNode = currentLocNodePtr->get_file_info()->get_file_id();
-#if 0
- printf ("isCompilerGenerated = %s isTransformation = %s fileIdForOriginOfCurrentLocatedNode = %s \n",
- isCompilerGenerated ? "true" : "false",isTransformation ? "true" : "false",fileIdForOriginOfCurrentLocatedNode.c_str());
-#endif
- // DQ (5/24/2005): Relaxed to handle compiler generated and transformed IR nodes
- if ( isCompilerGenerated || isTransformation || fileNameId == fileIdForOriginOfCurrentLocatedNode )
- {
- // Current node belongs to the file the name of which has been specified
- // on the command line
- line = currentLocNodePtr->get_file_info()->get_line();
- col = currentLocNodePtr->get_file_info()->get_col();
-#if 0
- printf ("Insert any comment before %p = %s = %s (compilerGenerate=%s) at line = %d col = %d \n",
- currentLocNodePtr,currentLocNodePtr->class_name().c_str(),SageInterface::get_name(currentLocNodePtr).c_str(),
- isCompilerGenerated ? "true" : "false", line, col);
-#endif
-#if 0
- printf ("In AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute() calling iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber(): n->class_name() = %s \n",n->class_name().c_str());
-#endif
- // Iterate over the list of comments and directives and add them to the AST
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber(currentLocNodePtr,line,PreprocessingInfo::before, reset_start_index );
-
- // save the previous node (in an accumulator attribute), but handle some nodes differently
- // to avoid having comments attached to them since they are not unparsed directly.
- setupPointerToPreviousNode(currentLocNodePtr);
- }
-#if 0
- else
- {
- cout << "Node belongs to a different file: ";
- }
-#endif
- }
- }
-
- return inh;
- }
-
-
-// Member function: evaluateSynthesizedAttribute
-AttachPreprocessingInfoTreeTraversalSynthesizedAttribute
-AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(
- SgNode *n,
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh,
- SubTreeSynthesizedAttributes st)
- {
- AttachPreprocessingInfoTreeTraversalSynthesizedAttribute syn;
- // PreprocessingInfo *currentPreprocessingInfoPtr = NULL;
-
-#if 0
- printf ("In AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(): n->sage_class_name() = %s \n",n->sage_class_name());
- if (isSgStatement(n) && (isSgStatement(n)->get_parent() != NULL) )
- printf (" parent = %s \n",isSgStatement(n)->get_parent()->sage_class_name());
-
- ROSE_ASSERT(previousLocNodePtr != NULL);
- printf (" previousLocNodePtr->sage_class_name() = %s \n",previousLocNodePtr->sage_class_name());
-#endif
-
- // error checking
- if (isSgCaseOptionStmt(n) != NULL)
- {
- // make sure there is a valid body
-#if 0
- if (isSgCaseOptionStmt(n)->get_body() == NULL)
- {
- // DEBUGGING: print out the location where we are failing
- // SgStatement* parent = isSgStatement(n)->get_parent();
- SgStatement* parent = isSgStatement(isSgStatement(n)->get_parent());
- if (parent != NULL)
- {
- Sg_File_Info* fileInfo = parent->get_file_info();
- printf ("parent = %s filename = %s line = %d \n",
- parent->sage_class_name(),fileInfo->get_filename(),fileInfo->get_line());
- }
- }
-#endif
- ROSE_ASSERT (isSgCaseOptionStmt(n)->get_body() != NULL);
- }
-
- // error checking
- if (isSgClassDeclaration(n) != NULL)
- {
- // DEBUGGING: print out the location where we are failing
-#if 0
- SgStatement* parent = isSgStatement(isSgStatement(n)->get_parent());
- if (parent != NULL)
- {
- // make sure there is a valid body
- if (isSgClassDeclaration(n)->get_endOfConstruct() == NULL)
- {
- Sg_File_Info* fileInfo = parent->get_file_info();
- printf ("parent = %s filename = %s line = %d \n",
- parent->sage_class_name(),fileInfo->get_filename(),fileInfo->get_line());
- }
- }
-#endif
- if (isSgClassDeclaration(n)->get_endOfConstruct() == NULL)
- {
- ROSE_ASSERT(n->get_file_info() != NULL);
- n->get_file_info()->display("Warning: SgClassDeclaration::get_endOfConstruct() == NULL");
- }
-
- // DQ (2/7/2004): Need to find this error so that I can fix it correctly
- // QY: removed this assertion to pass template classes. need further fix
- ROSE_ASSERT (isSgClassDeclaration(n)->get_endOfConstruct() != NULL);
- }
-
- // Only process SgLocatedNode object and the SgFile object
- SgFile* fileNode = dynamic_cast<SgFile*>(n);
- SgLocatedNode* locatedNode = dynamic_cast<SgLocatedNode*>(n);
- if ( (locatedNode != NULL) || (fileNode != NULL) )
- {
- // Attach the comments only to nodes from the same file
- int fileNameId = currentFileNameId;
-
- // DQ (10/27/2007): This is a valgrind error: use of uninitialized variable below!
- // Initialized with a value that could not match a valid file_id.
- int fileIdForOriginOfCurrentLocatedNode = -99;
-
- bool isCompilerGeneratedOrTransformation = false;
- int lineOfClosingBrace = 0;
- if (locatedNode != NULL)
- {
- ROSE_ASSERT(locatedNode->get_file_info());
- // printf ("Calling locatedNode->get_file_info()->get_filename() \n");
-
- // DQ (6/20/2005): Compiler generated IR nodes to be output are now marked explicitly!
- // isCompilerGeneratedOrTransformation = locatedNode->get_file_info()->isCompilerGenerated() ||
- // locatedNode->get_file_info()->isTransformation() ||
- isCompilerGeneratedOrTransformation = locatedNode->get_file_info()->isCompilerGeneratedNodeToBeUnparsed() ||
- locatedNode->get_file_info()->isTransformation();
-
- // bool isCompilerGenerated = currentLocNodePtr->get_file_info()->isCompilerGeneratedNodeToBeUnparsed();
- // bool isTransformation = currentLocNodePtr->get_file_info()->isTransformation();
-
- // DQ (6/20/2005): Notice that we use the new hasPositionInSource() member function
- // if ( isCompilerGeneratedOrTransformation == false )
- if ( locatedNode->get_file_info()->hasPositionInSource() == true )
- fileIdForOriginOfCurrentLocatedNode = locatedNode->get_file_info()->get_file_id();
- if (locatedNode->get_endOfConstruct() != NULL)
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
- lineOfClosingBrace = locatedNode->get_endOfConstruct()->get_line();
- }
- }
- else
- {
- // handle the trivial case of a SgFile node being from it's own file
- fileIdForOriginOfCurrentLocatedNode = fileNameId;
- // Use one billion as the max number of lines in a file
- const int OneBillion = 1000000000;
- lineOfClosingBrace = OneBillion;
- }
-
- // Make sure the astNode matches the current file's list of comments and CPP directives.
- // DQ (5/24/2005): Handle cases of isCompilerGenerated or isTransformation
- if ( (isCompilerGeneratedOrTransformation == true) || (fileNameId == fileIdForOriginOfCurrentLocatedNode) )
- {
-#if 0
- printf ("In AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(): %p = %s lineOfClosingBrace = %d \n",
- n,n->sage_class_name(),lineOfClosingBrace);
-#endif
- switch (n->variantT())
- {
- // I wanted to leave the SgFile case in the switch statement rather
- // than separating it out in a conditional statement at the top of the file.
- // case V_SgFile:
- case V_SgSourceFile:
- case V_SgBinaryFile:
- {
- // printf ("Case SgFile: See if we can find a better target to attach these comments than %s \n",
- // previousLocNodePtr->sage_class_name());
-
- SgLocatedNode* targetNode = previousLocNodePtr;
-
- // printf ("In SgFile: previousLocNodePtr = %s \n",previousLocNodePtr->sage_class_name());
-
- // If the target is a SgBasicBlock then try to find it's parent in the global scope
- if (isSgBasicBlock(previousLocNodePtr) != NULL)
- {
- while ( (targetNode != NULL) && (isSgGlobal(targetNode->get_parent()) == NULL) )
- {
- targetNode = dynamic_cast<SgLocatedNode*>(targetNode->get_parent());
- // printf ("loop: targetNode = %s \n",targetNode->sage_class_name());
- }
- }
-
- // printf ("In SgFile: targetNode = %s \n",targetNode->sage_class_name());
-
- // Iterate over the list of comments and directives and add them to the AST
- bool reset_start_index = true;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( targetNode, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index );
-
-#if 0
- // DQ (1/22/2008): This IS a problem for the AST file I/O...which tries to write out the ROSEAttributesList of PreprocessingInfo objects.
- // This is likely because the elements of that list are shared and were already processed at an earlier step in the AST File I/O.
- // This is not a problem for the list of PreprocessingInfo since at this point they have already been added to the AST and are no longer
- // required. If we want to keep the actual token stream then that will have to be addressed. We should also consider translating the
- // raw token stream (using the lex data structures) to use the SgToken data structure so that it could be saved with the AST. All of
- // this is later work however...
-
- // DQ (1/21/2008): Save the details of the token information for this file (even though at this point we are mostly done with it)
- SgFile* file = isSgFile(n);
- string filename = file->get_sourceFileNameWithPath();
- ROSE_ASSERT(file->get_preprocessorDirectivesAndCommentsList() != NULL);
-
- // printf ("Adding secondary lex pass information (currentListOfAttributes = %p) to file = %s \n",currentListOfAttributes,filename.c_str());
- file->get_preprocessorDirectivesAndCommentsList()->addList(filename,currentListOfAttributes);
-#else
- // DQ (1/21/2008): Original code
- // printf ("Delete Fortran Token List Size: currentListOfAttributes->get_rawTokenStream()->size() = %zu \n",currentListOfAttributes->get_rawTokenStream()->size());
- delete currentListOfAttributes;
-#endif
- currentListOfAttributes = NULL;
-
- // Reset the pointer to the previous located node and the current list size
- previousLocNodePtr = NULL;
- sizeOfCurrentListOfAttributes = 0;
- break;
- }
-
- // This case helps place the comment or directive relative
- // to the closing brace of a SgBasicBlock.
- case V_SgBasicBlock:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
-
- // The following should always work since each statement is a located node
- SgBasicBlock* basicBlock = dynamic_cast<SgBasicBlock*>(n);
-#if 0
- printf ("Case SgBasicBlock: lineOfClosingBrace = %d \n",lineOfClosingBrace);
- printf ("Case SgBasicBlock: See if we can find a better target to attach these comments than %s \n",previousLocNodePtr->sage_class_name());
-#endif
-
- // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( basicBlock, lineOfClosingBrace, PreprocessingInfo::inside,reset_start_index );
-
- // DQ (4/9/2005): We need to point to the SgBasicBlock and not the last return statement (I think)
- // Reset the previousLocNodePtr to the current node so that all
- // PreprocessingInfo objects will be inserted relative to the
- // current node next time.
- previousLocNodePtr = basicBlock;
- break;
- }
-
- case V_SgClassDeclaration:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
-
- // The following should always work since each statement is a located node
- SgClassDeclaration* classDeclaration = dynamic_cast<SgClassDeclaration*>(n);
-
- // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index );
- // printf ("Adding comment/directive to base of class declaration \n");
- // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- // ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside );
-
- previousLocNodePtr = classDeclaration;
- break;
- }
-
- // GB (09/18/2007): Added support for preprocessing info inside typedef declarations (e.g. after the
- // base type, which is what the previousLocNodePtr might point to).
- case V_SgTypedefDeclaration:
- {
- ROSE_ASSERT(locatedNode->get_endOfConstruct() != NULL);
-
- SgTypedefDeclaration *typedefDeclaration = isSgTypedefDeclaration(n);
- ROSE_ASSERT(typedefDeclaration != NULL);
-
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index );
-
- previousLocNodePtr = typedefDeclaration;
- break;
- }
-
- // GB (09/19/2007): Added support for preprocessing info inside variable declarations (e.g. after the
- // base type, which is what the previousLocNodePtr might point to).
- case V_SgVariableDeclaration:
- {
- ROSE_ASSERT(locatedNode->get_endOfConstruct() != NULL);
-
- SgVariableDeclaration *variableDeclaration = isSgVariableDeclaration(n);
- ROSE_ASSERT(variableDeclaration != NULL);
-
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index );
-
- previousLocNodePtr = variableDeclaration;
- break;
- }
-
- case V_SgClassDefinition:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
-
- // DQ (3/19/2005): This is a more robust process (although it introduces a new location for a comment/directive)
- // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- // ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after );
- // printf ("Adding comment/directive to base of class definition \n");
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index );
-
- // previousLocNodePtr = locatedNode;
- break;
- }
-
- case V_SgEnumDeclaration:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
-
- // The following should always work since each statement is a located node
- SgEnumDeclaration* enumDeclaration = dynamic_cast<SgEnumDeclaration*>(n);
-
- // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
- // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- // ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after );
- // printf ("Adding comment/directive to base of enum declaration \n");
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index );
-
- previousLocNodePtr = enumDeclaration;
- break;
- }
-
- // DQ (5/3/2004): Added support for namespaces
- case V_SgNamespaceDeclarationStatement:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
-
- // The following should always work since each statement is a located node
- SgNamespaceDeclarationStatement* namespaceDeclaration =
- dynamic_cast<SgNamespaceDeclarationStatement*>(n);
-
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index );
-
- previousLocNodePtr = namespaceDeclaration;
- break;
- }
-
- // DQ (5/3/2004): Added support for namespaces
- case V_SgNamespaceDefinitionStatement:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
-
- // The following should always work since each statement is a located node
- SgNamespaceDefinitionStatement* namespaceDefinition =
- dynamic_cast<SgNamespaceDefinitionStatement*>(n);
-
- // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
- // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- // ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after );
- // printf ("Adding comment/directive to base of namespace definition \n");
- bool reset_start_index = false;
- iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index );
-
- previousLocNodePtr = namespaceDefinition;
- break;
- }
-
- // DQ (4/9/2005): Added support for templates instaiations which are compiler generated
- // but OK to attach comments to them (just not inside them!).
- case V_SgTemplateInstantiationMemberFunctionDecl:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
- // printf ("Found a SgTemplateInstantiationMemberFunctionDecl but only record it as a previousLocNodePtr \n");
- previousLocNodePtr = locatedNode;
- }
-
- // DQ (4/21/2005): this can be the last statement and if it is we have to
- // record it as such so that directives/comments can be attached after it.
- case V_SgTemplateInstantiationDirectiveStatement:
- {
- ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
- previousLocNodePtr = locatedNode;
- }
-
- default:
- {
-#if 0
- printf ("Skipping any possability of attaching a comment/directive after a %s \n",n->sage_class_name());
- // ROSE_ASSERT(false);
-#endif
- }
- }
- }
-
-#if 0
- if (locatedNode != NULL)
- {
- printf ("Output attached comments: \n");
- printOutComments(locatedNode);
- }
-#endif
- }
-
- return syn;
- }
-
+// DQ (11/28/2008): What does this evaluate to??? Does this mix C++ constants with CPP values (does this make sense? Is "true" defined?)
#if CAN_NOT_COMPILE_WITH_ROSE != true
///////////////////////////////////////////////////////////////////////////////
@@ -1138,9 +22,7 @@
#include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp> // lexer class
-
#include "advanced_preprocessing_hooks.h"
-// #include "attachPreprocessingInfo.h"
#include "attributeListMap.h"
#endif
@@ -1155,52 +37,64 @@
// #include <string>
+#if 0
+// DQ (11/30/2008): This does not appear to be used!
-std::list<SgNode*> findNodes(SgNode* astNode){
+std::list<SgNode*>
+findNodes(SgNode* astNode)
+ {
std::list<SgNode*> returnList;
if(isSgFile(astNode)!=NULL)
returnList.push_back(astNode);
return returnList;
-}
+ }
+#endif
+#if 0
+// DQ (12/16/2008): comment out while I debug the non-wave support.
-
// AS (011306) Support for Wave preprocessor
- void
-attachPreprocessingInfo(SgFile *sageFilePtr, std::map<std::string,ROSEAttributesList*>* attrMap)
+void
+attachPreprocessingInfo(SgSourceFile *sageFilePtr, std::map<std::string,ROSEAttributesList*>* attrMap)
{
// DQ (7/6/2005): Introduce tracking of performance of ROSE.
TimingPerformance timer ("AST Comment Processing (using Wave, inner part):");
// Dummy attribute
AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh;
+ // AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh(NULL);
// Make sure that the argument is not a NULL pointer
ROSE_ASSERT(sageFilePtr);
+ // DQ (12/16/2008): comment out while I debug the non-wave support.
+#if 0
// Create tree traversal object for attaching the preprocessing information (using Wave)
AttachPreprocessingInfoTreeTrav tt(attrMap);
// Run tree traversal on specified source file
tt.traverseWithinFile(sageFilePtr,inh);
+#else
+ printf ("Wave support not implemented in new support for CPP directives and comment handling. \n");
+ ROSE_ASSERT(false);
+#endif
}
+#endif
-
-// DQ (4/5/2006): Older version not using Wave preprocessor
-// This is the function to be called from the main function
-// DQ: Now called by the SgFile constructor body (I think)
- void
-attachPreprocessingInfo(SgFile *sageFilePtr)
+// DQ (11/30/2008): Refactored this code out of the simpler function to isolate
+// the Wave specific handling.
+void
+attachPreprocessingInfoUsingWave (SgSourceFile *sageFilePtr)
{
ROSE_ASSERT(sageFilePtr != NULL);
-//#ifdef USE_ROSE_BOOST_WAVE_SUPPORT2
+ // DQ (11/30/2008):
+ // 1) Where are the tokens generated by Wave?
+ // 2) Where are the PreprocessorInfo objects generated?
+ // 3) Why is the commandline processed (redundantly with information already in SgSourceFile)?
- //std::cerr << "Checking to see if Wave is used " << std::endl;
- if(sageFilePtr->get_wave() == true )
- {
std::cerr << "Using WAVE" << std::endl;
// DQ (7/6/2005): Introduce tracking of performance of ROSE.
@@ -1210,30 +104,42 @@
// SgProject* project = frontend(argc,argv);
std::vector<std::string> includeSpecifierlist;
-
// Build the list that we will hand off to boost-wave
- //std::vector<std::string> includeSpecifierlist;
+ // std::vector<std::string> includeSpecifierlist;
std::vector<std::string> macroList;
std::vector<std::string> preincludeList;
+#if 0
+// .mine
+ string predefinedMacros = CXX_SPEC_DEF;
+
+ if (SgProject::get_verbose() >= 1)
+ std::cout << "XXXXXXXXXXXX: " << CXX_SPEC_DEF << std::endl;
+
+ // DQ (11/30/2008): This information is already available in the SgSourceFile
+ // or SgProject IR nodes so it is not required to reparse the commandline here.
+
+ vector<string> predefinedMacroList = CommandlineProcessing::generateArgListFromString(predefinedMacros);
+#else
+ // DQ (12/22/2008): I expect that this is the better version...
const char* predefinedMacroListRaw[] = CXX_SPEC_DEF;
vector<string> predefinedMacroList(predefinedMacroListRaw, predefinedMacroListRaw + sizeof(predefinedMacroListRaw) / sizeof(*predefinedMacroListRaw));
+#endif
// for (vector<string>::iterator i = predefinedMacroList.begin(); i != predefinedMacroList.end(); i++)
vector<string>::iterator i = predefinedMacroList.begin();
while (i != predefinedMacroList.end())
{
-
- //AS(03/12/08) CXX_SPEC_DEF has been changed to only contain macro defs
+ // AS(03/12/08) CXX_SPEC_DEF has been changed to only contain macro defs
if (i->substr(0,2) == "-D")
{
string macro = i->substr(2);
- if(SgProject::get_verbose() >= 1)
- printf ("Adding predefined macro to the macroList macro = %s \n",macro.c_str());
+ if (SgProject::get_verbose() >= 1)
+ printf ("Adding predefined macro to the macroList macro = %s \n",macro.c_str());
macroList.push_back(macro);
}
- else
+ else
{
string preincludeMarker = "--preinclude";
if (i->substr(0,preincludeMarker.size()) == preincludeMarker)
@@ -1242,22 +148,28 @@
// The following option is the file name associated with the "--preinclude" option
preincludeList.push_back(*i);
- if(SgProject::get_verbose() >= 1)
+ if(SgProject::get_verbose() >= 1)
std::cout << "Predefined macro: " << *i << std::endl;
}
- else if(i->empty()){}
- else
+ else
{
- printf ("Found a non -D macro definition (and non preinclude file) in the predefined macro list substring = %s *i = %s \n",i->substr(0,2).c_str(),i->c_str());
+ if(i->empty())
+ {
+ }
+ else
+ {
+ printf ("Found a non -D macro definition (and non preinclude file) in the predefined macro list substring = %s *i = %s \n",i->substr(0,2).c_str(),i->c_str());
+ }
}
}
+
i++;
}
// Now add the entries specified on the commandline
- if(SgProject::get_verbose() >= 1)
- std::cout << "INCLUDES FROM COMMANDLInE" << std::endl;
+ if (SgProject::get_verbose() >= 1)
+ std::cout << "INCLUDES FROM COMMANDLINE" << std::endl;
std::vector<std::string> commandLine = sageFilePtr->get_originalCommandLineArgumentList();
for (vector<string>::iterator i = commandLine.begin(); i != commandLine.end(); i++)
@@ -1279,22 +191,28 @@
macroList.push_back(macro);
}
}
+
if(SgProject::get_verbose() >= 1)
- std::cout << "DONE INCLUDES FROM COMMANDLInE" << std::endl;
+ std::cout << "DONE INCLUDES FROM COMMANDLINE" << std::endl;
std::vector<SgNode*> accessFunctionsList;
- // Build list of value expressions
+ // DQ (11/30/2008): Why are we getting all the SgFloatValExp and SgDoubleValExp IR nodes?
+
+ // Build list of value expressions
std::vector<SgNode*> valueExp = NodeQuery::querySubTree (sageFilePtr,&queryFloatDoubleValExp);
// Open and read in the specified input file.
std::string sourceFileName = sageFilePtr->getFileName();
- if(SgProject::get_verbose() >= 1){
- std::cout << "Source file name: \"" << sourceFileName << "\"" << std::endl;
- std::cout << "Source file name: \"" << sageFilePtr->getFileName()<< "\"" << std::endl;
- }
- // sourceFileName=string(CurrentPath)+"/"+sourceFileName;
+ if (SgProject::get_verbose() >= 1)
+ {
+ std::cout << "Source file name: \"" << sourceFileName << "\"" << std::endl;
+ std::cout << "Source file name: \"" << sageFilePtr->getFileName()<< "\"" << std::endl;
+ }
+
+ // Here we open the input file for processing using WAVE.
+ // sourceFileName = string(CurrentPath)+"/"+sourceFileName;
std::ifstream instream(sourceFileName.c_str());
std::string instring;
@@ -1304,10 +222,13 @@
ROSE_ASSERT(false);
}
+ // DQ (11/30/2008): What does this do? Please document why this is required.
instream.unsetf(std::ios::skipws);
- instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
- std::istreambuf_iterator<char>());
+ instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),std::istreambuf_iterator<char>());
+ // DQ (11/30/2008): Is there no namespace for the Wave types?
+ // Also which of these three statements builds the token list?
+
// The template boost::wave::cpplexer::lex_token<> is the token type to be used by the Wave library.
::token_type x;
@@ -1328,12 +249,17 @@
// The preprocessing of the input stream is done on the fly behind the
// scenes during iteration over the context_type::iterator_type stream.
- ROSE_ASSERT(sourceFileName.size()>0);
+ ROSE_ASSERT(sourceFileName.size() > 0);
ROSE_ASSERT(instring.begin() != instring.end());
+
+ // DQ (11/30/2008): What does this do?
context_type ctx (instring.begin(), instring.end(), sourceFileName.c_str());
- // std::cout << "Current file name: " << get_current_filename()
-// This get_hooks() member function was added by the Author of boost-wave to handle
+ // std::cout << "Current file name: " << get_current_filename()
+
+ // DQ (11/30/2008): Andreas just mentioned that the AttributeListMap is not required and could be eliminated.
+
+ // This get_hooks() member function was added by the Author of boost-wave to handle
// a problem pointed out by Andreas.
AttributeListMap attributeListMap(sageFilePtr);
ctx.get_hooks().attributeListMap = &attributeListMap;
@@ -1342,17 +268,17 @@
// Preserve comments through preprocessing so that the output token-stream
// contains the comments.
- if(SgProject::get_verbose() >= 1)
- std::cout << "BEFORE ADDING PREDEFINES" << std::endl;
+ if (SgProject::get_verbose() >= 1)
+ std::cout << "BEFORE ADDING PREDEFINES" << std::endl;
if( sageFilePtr->get_C_only() == true){
- //Tentaive support for C. For now treat it like C99 since Wave does not
- //have an option for just C.
- ctx.set_language(boost::wave::support_c99);
+ // Tentaive support for C. For now treat it like C99 since Wave does not
+ // have an option for just C.
+ ctx.set_language(boost::wave::support_c99);
}else if( sageFilePtr->get_C99_only() == true ){
- ctx.set_language(boost::wave::support_c99);
+ ctx.set_language(boost::wave::support_c99);
}else{
- ctx.set_language(boost::wave::support_cpp);
+ ctx.set_language(boost::wave::support_cpp);
}
ctx.set_language(boost::wave::enable_long_long(ctx.get_language()));
@@ -1361,66 +287,59 @@
// Force a specific file to be included before all others
if( sageFilePtr->get_C_only() == true){
- //Tentaive support for C. For now treat it like C99 since Wave does not
- //have an option for just C.
- ctx.add_macro_definition(std::string("ROSE_CPP_MODE=0"),true);
+ // Tentaive support for C. For now treat it like C99 since Wave does not
+ // have an option for just C.
+ ctx.add_macro_definition(std::string("ROSE_CPP_MODE=0"),true);
}else if( sageFilePtr->get_C99_only() == true ){
- ctx.add_macro_definition(std::string("ROSE_CPP_MODE=0"),true);
+ ctx.add_macro_definition(std::string("ROSE_CPP_MODE=0"),true);
}else{
- ctx.add_macro_definition(std::string("ROSE_CPP_MODE=1"),true);
-
-
+ ctx.add_macro_definition(std::string("ROSE_CPP_MODE=1"),true);
}
- if(SgProject::get_verbose() >= 1)
- std::cout << "MIDDLE OF ADDING PREDEFINES" << std::endl;
+ if (SgProject::get_verbose() >= 1)
+ std::cout << "MIDDLE OF ADDING PREDEFINES" << std::endl;
- for(std::vector<std::string>::iterator it_beg = macroList.begin();
- it_beg != macroList.end(); ++it_beg){
-
- if(SgProject::get_verbose() >= 1)
- std::cout << "Predef macro:\"" << *it_beg << "\""<<std::endl;
- if((*it_beg)!="")
- ctx.add_macro_definition(*it_beg,true);
-
- }
+ for (std::vector<std::string>::iterator it_beg = macroList.begin(); it_beg != macroList.end(); ++it_beg)
+ {
+ if (SgProject::get_verbose() >= 1)
+ std::cout << "Predef macro:\"" << *it_beg << "\""<<std::endl;
+ if ((*it_beg)!="")
+ ctx.add_macro_definition(*it_beg,true);
+ }
- if(SgProject::get_verbose() >= 1)
- std::cout << "AFTER ADDING PREDEFINES" << std::endl;
+ if (SgProject::get_verbose() >= 1)
+ std::cout << "AFTER ADDING PREDEFINES" << std::endl;
-
// Add include paths specified on commandline to the context object
std::vector<string>::const_iterator firstInclude = includeSpecifierlist.begin();
std::vector<std::string>::const_iterator lastInclude = includeSpecifierlist.end();
-
- if(SgProject::get_verbose() >= 1)
- printf ("Adding the /usr/include/ file \n");
+ if (SgProject::get_verbose() >= 1)
+ printf ("Adding the /usr/include/ file \n");
// DQ (4/7/2006): Not sure we want to do this, if we did want to do so then it should
// be in the list of EDG as well and in which case, what order should it be placed?
string internalIncludePaths[] = CXX_INCLUDE_STRING;
- //if(SgProject::get_verbose() >= 1)
- // std::cout << "INTERNAL INCLUDE PATHS " << CXX_INCLUDE_STRING << std::endl;
+ // if(SgProject::get_verbose() >= 1)
+ // std::cout << "INTERNAL INCLUDE PATHS " << CXX_INCLUDE_STRING << std::endl;
vector<string> internalIncludePathList(internalIncludePaths, internalIncludePaths + sizeof(internalIncludePaths)/sizeof(string));
- //internalIncludePathList.push_back("-I"+string(CurrentPath)+"/");
+ // internalIncludePathList.push_back("-I"+string(CurrentPath)+"/");
-
string includeBase = findRoseSupportPathFromBuild("include-staging", "include");
for (vector<string>::iterator i = internalIncludePathList.begin(); i != internalIncludePathList.end(); i++)
- {
- ROSE_ASSERT (!i->empty());
- string fullPath = (*i)[0] == '/' ? *i : (includeBase + "/" + *i);
+ {
+ ROSE_ASSERT (!i->empty());
+ string fullPath = (*i)[0] == '/' ? *i : (includeBase + "/" + *i);
- ctx.add_sysinclude_path(fullPath.c_str());
+ ctx.add_sysinclude_path(fullPath.c_str());
}
std::string sys_include = "/usr/include/";
ctx.add_sysinclude_path(sys_include.c_str());
- if(SgProject::get_verbose() >= 1)
+ if (SgProject::get_verbose() >= 1)
printf ("DONE: Adding the /usr/include/ file \n");
while(firstInclude != lastInclude)
@@ -1431,34 +350,36 @@
++firstInclude;
}
-
-
+ // DQ (11/30/2008): What bug does this refer to in ROSE?
// variable needed by the program to account for the bug in the column
// position of value expressions within ROSE.
context_type::token_type lastOperatorToken(boost::wave::T_RIGHTPAREN,")",boost::wave::util::file_position_type("",0,0));
- ;
+
// Attaching an attribute list to the current hooks object so that
// preprocessing infos can be extracted
map<std::string,ROSEAttributesList*> currentMapOfAttributes;
- // std::string x,y;
+ // std::string x,y;
// current file position is saved for exception handling
boost::wave::util::file_position_type current_position;
- // accessFunctionsList = NodeQuery::querySubTree (project,&queryFloatDoubleValExp);
+ // DQ (11/30/2008): Andreas says this AST Query is part of the alternative approach to extract
+ // the strings used for floating point values (this work later was implemented in EDG directly).
+ // So this feature of the Wave preprocessing is not used currently, but it appears to be
+ // exectuted (it should be commented out).
accessFunctionsList = NodeQuery::querySubTree (sageFilePtr,&queryFloatDoubleValExp);
-
std::cerr << "For some reason we have " << std::endl;
- //Locate all value expression with Wave and set the string value of the
- //corresponding value expressions within the ROSE AST to the string value found
- //by Wave.
+
+ // Locate all value expression with Wave and set the string value of the
+ // corresponding value expressions within the ROSE AST to the string value found
+ // by Wave.
context_type::iterator_type first = ctx.begin();
- context_type::iterator_type last = ctx.end();
+ context_type::iterator_type last = ctx.end();
// analyze the input file, print out the preprocessed hooks
- if(SgProject::get_verbose() >= 1)
- printf ("Adding the preinclude file \n");
+ if (SgProject::get_verbose() >= 1)
+ printf ("Adding the preinclude file \n");
ROSE_ASSERT(preincludeList.size() == 1);
for (vector<string>::reverse_iterator i = preincludeList.rbegin(); i != preincludeList.rend(); ++i)
@@ -1466,84 +387,85 @@
vector<string>::reverse_iterator copyOf_i = i;
copyOf_i++;
- if(SgProject::get_verbose() >= 1)
+ if (SgProject::get_verbose() >= 1)
printf ("Adding preinclude file = %s \n",i->c_str());
// DQ (4/7/2006): This currently fails
first.force_include( i->c_str(), copyOf_i == preincludeList.rend() );
-// first.force_include( i->c_str(), false);
-
- if(SgProject::get_verbose() >= 1)
+ // first.force_include( i->c_str(), false);
+
+ if (SgProject::get_verbose() >= 1)
printf ("DONE: Adding preinclude file = %s \n",i->c_str());
}
-#if 1
-
- if(SgProject::get_verbose() >= 1)
- printf ("DONE: Adding the preinclude file \n");
+ if (SgProject::get_verbose() >= 1)
+ printf ("DONE: Adding the preinclude file \n");
try{
- while (first != last) {
+ while (first != last)
+ {
using namespace boost::wave;
try{
- current_position = (*first).get_position();
- if(first->get_position().get_file()!="<built-in>"){
- //std::cout << first->get_position().get_file() << " l" << first->get_position().get_line()
- // << " " << (*first).get_value() << std::endl;
- }
+ current_position = (*first).get_position();
+ if(first->get_position().get_file()!="<built-in>"){
+ // std::cout << first->get_position().get_file() << " l" << first->get_position().get_line()
+ // << " " << (*first).get_value() << std::endl;
+ }
+ token_id id = token_id(*first);
+ // Attach comments found by Wave to the AST
+ if((T_CCOMMENT == id) | (T_CPPCOMMENT == id)){
+ attributeListMap.found_directive(*first);
+ }
- token_id id = token_id(*first);
- //Attach comments found by Wave to the AST
- if((T_CCOMMENT == id) | (T_CPPCOMMENT == id)){
- attributeListMap.found_directive(*first);
- }
+ wave_tokenStream.push_back(*first);
+ first++;
+ }
+ catch (boost::wave::cpp_exception &e)
+ {
+ // some preprocessing error
+ // This is a problem for using compass with emacs (see testEmacs.C).
+ // cerr << "WAVE 1: " << e.file_name() << "(" << e.line_no() << "): "
+ // << e.description() << endl;
+ }
+ catch (boost::wave::cpplexer::lexing_exception &e)
+ {
+ // some lexing error
+ cerr << "WAVE 2:" << e.file_name() << "(" << e.line_no() << "): "
+ << e.description() << endl;
+ }
- wave_tokenStream.push_back(*first);
- first++;
- }
- catch (boost::wave::cpp_exception &e) {
- // some preprocessing error
- // This is a problem for using compass with emacs (see testEmacs.C).
- // cerr << "WAVE 1: " << e.file_name() << "(" << e.line_no() << "): "
- // << e.description() << endl;
- }
- catch (boost::wave::cpplexer::lexing_exception &e) {
- // some lexing error
- cerr
- << "WAVE 2:" << e.file_name() << "(" << e.line_no() << "): "
- << e.description() << endl;
- }
+ }
+ }
- }
- }
- catch (boost::wave::cpp_exception &e) {
+ catch (boost::wave::cpp_exception &e)
+ {
// some preprocessing error
- cerr
- << "WAVE 3: " << e.file_name() << "(" << e.line_no() << "): "
- << e.description() << endl;
- }
- catch (boost::wave::cpplexer::lexing_exception &e) {
+ cerr << "WAVE 3 (boost::wave::cpp_exception): " << e.file_name() << "(" << e.line_no() << "): "
+ << e.description() << endl;
+ }
+ catch (boost::wave::cpplexer::lexing_exception &e)
+ {
// some lexing error
- cerr
- << "WAVE 4:" << e.file_name() << "(" << e.line_no() << "): "
- << e.description() << endl;
- }
- catch (std::exception &e) {
+ cerr << "WAVE 4 (boost::wave::cpplexer::lexing_exception):" << e.file_name() << "(" << e.line_no() << "): "
+ << e.description() << endl;
+ }
+ catch (std::exception &e)
+ {
// use last recognized token to retrieve the error position
- cerr
- << "WAVE 5:" << current_position.get_file()
- << "(" << current_position.get_line() << "): "
- << "exception caught: " << e.what()
- << endl;
- }
- catch (...) {
+ cerr << "WAVE 5 (std::exception):" << current_position.get_file()
+ << "(" << current_position.get_line() << "): "
+ << "exception caught: " << e.what()
+ << endl;
+ }
+ catch (...)
+ {
// use last recognized token to retrieve the error position
- cerr
- << "WAVE 6:" << current_position.get_file()
- << "(" << current_position.get_line() << "): "
- << "unexpected exception caught." << endl;
- }
+ cerr << "WAVE 6 (all other exceptions):" << current_position.get_file()
+ << "(" << current_position.get_line() << "): "
+ << "unexpected exception caught." << endl;
+ }
+
attributeListMap.attach_line_to_macro_call();
#if 0
@@ -1558,171 +480,118 @@
attachPreprocessingInfo(sgFile,&attributeListMap.currentMapOfAttributes);
}
#else
-
- //AS(01/04/07) Create a global map of filenames to PreprocessingInfo*'s as it is inefficient
- //to get this by a traversal of the AST
-
- for(AttributeListMap::attribute_map_type::iterator it_files = attributeListMap.currentMapOfAttributes.begin();
- it_files != attributeListMap.currentMapOfAttributes.end();
- ++it_files){
-
+ // AS(01/04/07) Create a global map of filenames to PreprocessingInfo*'s as it is inefficient
+ // to get this by a traversal of the AST
+ for(AttributeListMap::attribute_map_type::iterator it_files = attributeListMap.currentMapOfAttributes.begin(); it_files != attributeListMap.currentMapOfAttributes.end(); ++it_files)
+ {
std::string filename2 = it_files->first;
ROSEAttributesList* attrList = it_files->second;
- //mapFilenameToAttributes[filename2] = attrList->getList();
+ // mapFilenameToAttributes[filename2] = attrList->getList();
std::vector<PreprocessingInfo*>* preproc_info = new std::vector<PreprocessingInfo*>();
mapFilenameToAttributes[filename2] = preproc_info;
- for(std::vector<PreprocessingInfo*>::iterator it_preproc = attrList->getList().begin();
- it_preproc != attrList->getList().end();
- ++it_preproc){
+ for (std::vector<PreprocessingInfo*>::iterator it_preproc = attrList->getList().begin(); it_preproc != attrList->getList().end(); ++it_preproc)
+ {
preproc_info->push_back(*it_preproc);
+ }
+ if (SgProject::get_verbose() >= 1)
+ {
+ std::cout << "Size of vector: " << preproc_info->size() << std::endl;
+ std::cout << "Iterating over filename:" << filename2 << std::endl;
+ }
+ }
-
- };
-
- if(SgProject::get_verbose() >= 1){
-
- std::cout << "Size of vector: " << preproc_info->size() << std::endl;
- std::cout << "Iterating over filename:" << filename2 << std::endl;
- }
- }
-
- if(SgProject::get_verbose() >= 1)
+ if (SgProject::get_verbose() >= 1)
std::cout << "Size of mapFilenameToAttributes:" << mapFilenameToAttributes.size() << std::endl;
-
+#if 0
// DQ (and AS (4/6/2006): Call this for the single input file
attachPreprocessingInfo(sageFilePtr,&attributeListMap.currentMapOfAttributes);
+#else
+ printf ("Commented out Wave support while debugging non-wave support. \n");
+ ROSE_ASSERT(false);
#endif
+#endif
#if 0
- printf ("Ending at base of attachPreprocessingInfo(SgFile*) \n");
+ printf ("Ending at base of attachPreprocessingInfoUsingWave(SgSourceFile*) \n");
ROSE_ABORT();
#endif
+ }
- // else for conditional use of Boost-Wave
+// DQ (4/5/2006): Older version not using Wave preprocessor
+// This is the function to be called from the main function
+// DQ: Now called by the SgFile constructor body (I think)
+void
+attachPreprocessingInfo(SgSourceFile *sageFilePtr)
+ {
+ ROSE_ASSERT(sageFilePtr != NULL);
+
+#if 0
+ printf ("Inside of attachPreprocessingInfo(): wave = %s file = %p = %s \n",
+ sageFilePtr->get_wave() ? "true" : "false",sageFilePtr,sageFilePtr->get_sourceFileNameWithPath().c_str());
#endif
- }else
-
-//#endif
- {
-//#else
- // DQ (7/6/2005): Introduce tracking of performance of ROSE.
- TimingPerformance timer ("AST Comment and CPP Directive Processing (not using Wave):");
- // DQ (4/7/2006): Older version of code (not using boost-wave)
-
- // Dummy attribute (nothing is done here since this is an empty class)
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh;
-
- // Make sure that the argument is not a NULL pointer
- ROSE_ASSERT(sageFilePtr);
-
- // DQ (4/19/2006): Now supporting either the collection or ALL comments and CPP directives
- // into header file AST nodes or just the collection of the comments and CPP directives
- // into the source file.
- // printf ("sageFilePtr->get_collectAllCommentsAndDirectives() = %s \n",sageFilePtr->get_collectAllCommentsAndDirectives() ? "true" : "false");
- if (sageFilePtr->get_collectAllCommentsAndDirectives() == true)
+ if (sageFilePtr->get_wave() == true )
{
- printf ("Collect all comments and CPP directives into the AST (from header files) \n");
+ // This case uses the information generated by Wave.
- // Create tree traversal object for attaching the preprocessing information
- AttachAllPreprocessingInfoTreeTrav tt(sageFilePtr);
+ // Wave is a tokenization tool that provided an interface
+ // for macros (and provides a better interface for
+ // tokenization than anything that we have written from
+ // scratch). Wave is a part of the Boost library.
- // Run tree traversal on specified source file
- tt.traverse(sageFilePtr, inh);
-
- // DQ (3/30/2006): Commented this out with help from Lingxiao.
- // This gets the list of header files using EDG's -M (--dependencies) option.
- // This list is provided in order so that header files without IR nodes
- // have have their comments and CPP directive processed for inclusion into
- // the AST (important if such a header file included "#if 0" only, for example).
- // tt.attach_left_info();
-#if PRINT_DEVELOPER_WARNINGS
- printf ("Skipping possible header files that contain no IR nodes (the comments and CPP directives in them will not be extracted) \n");
-#endif
-
-#if 0
- // DQ (10/27/2007): Output debugging information
- if ( SgProject::get_verbose() >= 0 )
- {
- tt.display("Output from collecting ALL comments and CPP directives (across source and header files)");
- }
-#endif
+ attachPreprocessingInfoUsingWave (sageFilePtr);
}
else
{
- // DQ (4/13/2007): Introduce tracking of performance of ROSE.
- TimingPerformance timer ("AST Comment and CPP Directive Processing (traversal to attach):");
+ // DQ (7/6/2005): Introduce tracking of performance of ROSE.
+ TimingPerformance timer ("AST Comment and CPP Directive Processing (not using Wave):");
- // Make sure that the argument is not a NULL pointer
- ROSE_ASSERT(sageFilePtr);
+ // Dummy attribute (nothing is done here since this is an empty class)
+ AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh;
- // Create tree traversal object for attaching the preprocessing information (not using Wave)
- AttachPreprocessingInfoTreeTrav tt;
+ // DQ (4/19/2006): Now supporting either the collection or ALL comments and CPP directives
+ // into header file AST nodes or just the collection of the comments and CPP directives
+ // into the source file.
+ // printf ("sageFilePtr->get_collectAllCommentsAndDirectives() = %s \n",sageFilePtr->get_collectAllCommentsAndDirectives() ? "true" : "false");
- // Run tree traversal on specified source file
- tt.traverseWithinFile(sageFilePtr,inh);
+ bool processAllFiles = sageFilePtr->get_collectAllCommentsAndDirectives();
+ AttachPreprocessingInfoTreeTrav tt(sageFilePtr,processAllFiles);
-#if 1
+ // DQ (12/19/2008): Added support for Fortran CPP files.
+ // If this is a Fortran file requiring CPP processing then we want to call traverse, instead of
+ // traverseWithinFile, so that the whole AST will be processed (which is in a SgSourceFile
+ // using a name without the "_preprocessed" suffix, though the statements in the file are
+ // marked with a source position from the filename with the "_preprocessed" suffix).
+ bool requiresCPP = sageFilePtr->get_requires_C_preprocessor();
+
+ if (processAllFiles == true || requiresCPP == true)
+ {
+ tt.traverse(sageFilePtr, inh);
+ }
+ else
+ {
+ tt.traverseWithinFile(sageFilePtr,inh);
+ }
+
+#if 0
+ // This is pointless since at this point the last step of the traversla has reset the lists (state held in tt).
// DQ (10/27/2007): Output debugging information
if ( SgProject::get_verbose() >= 3 )
{
- tt.display("Output from collecting comments and CPP directives in source file only");
+ if (processAllFiles == true)
+ tt.display("Output from collecting ALL comments and CPP directives (across source and header files)");
+ else
+ tt.display("Output from collecting comments and CPP directives in source file only");
}
#endif
}
-
- }
- // endif for USE_ROSE_BOOST_WAVE_SUPPORT
-//#endif
}
-
-
-// DQ (10/27/2007): Added display function to output information gather durring the collection of
-// comments and CPP directives across all files.
-void
-AttachPreprocessingInfoTreeTrav::display(const std::string & label) const
- {
- // Output internal information
-
- printf ("Inside of AttachPreprocessingInfoTreeTrav::display(%s) \n",label.c_str());
-
- printf (" previousLocNodePtr = %p = %s \n",previousLocNodePtr,previousLocNodePtr != NULL ? previousLocNodePtr->class_name().c_str() : "NULL");
- printf (" currentListOfAttributes = %p \n",currentListOfAttributes);
- printf (" sizeOfCurrentListOfAttributes = %d \n",sizeOfCurrentListOfAttributes);
- printf (" currentFileNameId = %d \n",currentFileNameId);
- printf (" use_Wave = %s \n",use_Wave ? "true" : "false");
- printf (" start_index = %d \n",start_index);
- printf (" currentMapOfAttributes = %p \n",currentMapOfAttributes);
-
- if (currentListOfAttributes != NULL)
- {
- printf (" currentListOfAttributes.size() = %d \n",currentListOfAttributes->size());
- currentListOfAttributes->display("Called from AttachPreprocessingInfoTreeTrav::display()");
- }
-
- if (currentMapOfAttributes != NULL)
- {
- std::map<std::string,ROSEAttributesList*>::iterator i = currentMapOfAttributes->begin();
- while (i != currentMapOfAttributes->end())
- {
- string filename = i->first;
- size_t numberOfAttributes = i->second->size();
- printf (" filename = %s has %zu attributes \n",filename.c_str(),numberOfAttributes);
-
- i->second->display("Called from AttachPreprocessingInfoTreeTrav::display()");
-
- i++;
- }
- }
- }
-
-
// EOF
Modified: branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.h
===================================================================
--- branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/attachPreprocessingInfo.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -4,15 +4,9 @@
#ifndef _ATTACH_PREPROCESSING_INFO_H_
#define _ATTACH_PREPROCESSING_INFO_H_
-//#include "rose.h"
-//#include "Cxx_Grammar.h"
+#include "attachPreprocessingInfoTraversal.h"
-// #include "sage3.h"
-// #include "roseInternal.h"
-// #include <typeinfo>
-// #include "AstProcessing.h"
-#if 1
// DQ (4/5/2006): Andreas has removed this code!
// void printOutComments ( SgLocatedNode* locatedNode );
@@ -25,88 +19,27 @@
// ROSEAttributesList *getPreprocessorDirectives( std::string fileName, LexTokenStreamTypePointer & input_token_stream_pointer );
ROSEAttributesList *getPreprocessorDirectives( std::string fileName );
-// Need dummy classes and the actual tree traversal class
-// DQ: Renamed classes, can't have DI and DS polluting the global name space (potential for strange errors)
-// class DI : public SgInheritedAttribute {};
-// class DS : public SgSynthesizedAttribute {};
-class AttachPreprocessingInfoTreeTraversalInheritedAttrribute : public AstInheritedAttribute {};
-class AttachPreprocessingInfoTreeTraversalSynthesizedAttribute : public AstSynthesizedAttribute {};
+void attachPreprocessingInfo(SgSourceFile *sageFile);
-class AttachPreprocessingInfoTreeTrav
- : public SgTopDownBottomUpProcessing<AttachPreprocessingInfoTreeTraversalInheritedAttrribute,
- AttachPreprocessingInfoTreeTraversalSynthesizedAttribute>
- {
- protected: //Pi-- private:
- //! accumulator attribute
- SgLocatedNode *previousLocNodePtr;
+// DQ (11/30/2008): Part of refactoring of code specific to Wave.
+void attachPreprocessingInfoUsingWave(SgSourceFile *sageFile);
- //! List of all comments and CPP directives
- ROSEAttributesList *currentListOfAttributes;
+#if 0
+// DQ (12/16/2008): comment out while I debug the non-wave support.
- //! size of list?
- int sizeOfCurrentListOfAttributes;
-
- //! current file name id (only handle strings from current file)
- int currentFileNameId;
-
- //! AS(011306) Map of ROSEAttributesLists mapped to filename from Wave
- std::map<std::string,ROSEAttributesList*>* currentMapOfAttributes;
-
- //! AS(011306) Use_Wave == true specifies if a wave preprocessor is used
- bool use_Wave;
-
- //! AS(092107) Optimization variable to avoid n^2 complexity in
- //! iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber()
- int start_index;
-
-
- public:
- // DQ (9/24/2007): Moved function definition to source file from header file.
- // AS(011306) Constructor for use of Wave Preprocessor
- AttachPreprocessingInfoTreeTrav( std::map<std::string,ROSEAttributesList*>* attrMap);
-
- public:
-
- // DQ (9/24/2007): Moved function definition to source file from header file.
- // Constructor
- AttachPreprocessingInfoTreeTrav();
-
- void setupPointerToPreviousNode (SgLocatedNode* currentLocNodePtr );
-
- void iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
- ( SgLocatedNode* locatedNode, int lineNumber, PreprocessingInfo::RelativePositionType location, bool reset_start_index );
-
- // Member function to be executed on each node of the AST
- // in the course of its traversal
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute
- evaluateInheritedAttribute( SgNode *n,
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh);
-
- AttachPreprocessingInfoTreeTraversalSynthesizedAttribute
- evaluateSynthesizedAttribute( SgNode *n,
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh,
- SubTreeSynthesizedAttributes st);
-
- // DQ (10/27/2007): Added display function to output information gather durring the collection of
- // comments and CPP directives across all files.
- void display(const std::string & label) const;
- };
-#endif
-
-void attachPreprocessingInfo(SgFile *sageFile);
-
// AS (012006) Added the function
// void attachPreprocessingInfo(SgFile *sageFile, std::map<string,ROSEAttributesList*>*);
// to support reintroductions of macros and fetching of preprocessor directive using Wave.
// This function does not in itself rely on Wave, but simply takes the same arguement as
// 'attachPreprocessingInfo(SgFile *sageFile)', but adds an argument std::map<string,ROSEAttributesList*>*
// which is a map of a pair (filename,list of attributes in that file). The two functions will perform
-// the same tasks in all ways but the way they find the preprocessor diretives. In addition to that
+// the same tasks in all ways but the way they find the preprocessor directives. In addition to that
// the mechanism here opens up for reintroduction of unexpanded macros into the AST without
// changing the implementation at all. This relies on some external mechanism, that be the
// Wave preprocessor or some other, to find the preprocessor directives and the unexpanded
// macros.
-void attachPreprocessingInfo(SgFile *sageFile, std::map<std::string,ROSEAttributesList*>*);
+void attachPreprocessingInfo(SgSourceFile *sageFile, std::map<std::string,ROSEAttributesList*>*);
+#endif
#endif
Copied: branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.C (from rev 188, trunk/src/frontend/SageIII/attachPreprocessingInfoTraversal.C)
===================================================================
--- branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.C (rev 0)
+++ branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,1285 @@
+/****************************************************************************
+
+Remarks on Unparsing and on attaching preprocessing information to AST nodes
+----------------------------------------------------------------------------
+Markus Kowarschik, 10/2002
+
+The SgFile (always) constructor calls the function
+void attachPreprocessingInfo(SgFile *sageFilePtr);
+which in turn calls getPreprocessorDirectives (see above) and then
+invokes a tree traversal in order to attach the preprocessor directives
+(i.e., the preprocessingInfo objects) to located nodes in the AST.
+(Currently, we only attach preprocessingInfo objects to SgStatement
+objects.)
+
+For this purpose, I added a new data member
+attachedPreprocessingInfoType* attachedPreprocessingInfoPtr;
+to the SgLocatedNode class. This is done in ROSETTA/src/node.C.
+
+Furthermore, I added the corresponding access functions:
+void addToAttachedPreprocessingInfo(preprocessingInfo *prepInfoPtr);
+attachedPreprocessingInfoType* getAttachedPreprocessingInfo(void);
+to the SgLocatedNode class. This is done in ROSETTA/Grammar/LocatedNode.code.
+
+The tree traversal works as follows: whenever it hits a located node
+(currently: a statement), it checks if there is preprocessing info the
+line number of which is less or equal than the line number of the current
+located node (currently: of the current statement). If this is the case,
+the corresponding preprocessing info is attached to the current
+located node (currently: before the current statement), unparse flag: "before".
+All this is done in the evaluateInheritedAttribute member function of the
+derived tree traversal class.
+
+The evaluateSynthesizedAttribute member function deletes the list of
+preprocessingInfo objects as soon as the traversal returns to a SgFile
+object and attaches trailing preprocessing information to the last located
+node (currently to the last statement) that has been visited in
+the file (unparse flag: "after").
+
+Node that the preprocessingInfo objects are always attached to AST nodes.
+By switching the USE_OLD_MECHANISM_OF_HANDLING_PREPROCESSING_INFO flag,
+you only change the mechanism which the unparser is based on!
+If USE_OLD_MECHANISM_OF_HANDLING_PREPROCESSING_INFO is set to 1, then
+the unparser simply ignores the preprocessingInfo objects that have
+been attached to the AST nodes.
+
+Problems with the handling of preprocessing information can be
+found in the directory ROSE/TESTS/KnownBugs/AttachPreprocessingInfo.
+
+****************************************************************************/
+
+// This file implements the extraction of the attributes (comments and
+// preprocessor directives) from the original source file and their insertion
+// into the AST data structure.
+// The idea is to re-introduce them (as correctly as possible) when the
+// transformed AST is unparsed later on.
+
+// #include "attachPreprocessingInfo.h"
+// #include "sage3.h"
+#include "rose.h"
+
+// DQ (12/31/2005): This is OK if not declared in a header file
+using namespace std;
+
+// Debug flag
+#define DEBUG_ATTACH_PREPROCESSING_INFO 0
+
+AttachPreprocessingInfoTreeTrav::AttachPreprocessingInfoTreeTrav( SgSourceFile* file, bool includeDirectivesAndCommentsFromAllFiles )
+ {
+ // previousLocNodePtr = NULL;
+ // currentListOfAttributes = NULL;
+ // sizeOfCurrentListOfAttributes = 0;
+ // currentFileName = NULL;
+ // currentMapOfAttributes = NULL;
+ use_Wave = false;
+ processAllIncludeFiles = includeDirectivesAndCommentsFromAllFiles;
+ // start_index = 0;
+
+ sourceFile = file;
+ }
+
+
+// DQ (10/27/2007): Added display function to output information gather durring the collection of
+// comments and CPP directives across all files.
+void
+AttachPreprocessingInfoTreeTrav::display(const std::string & label) const
+ {
+ // Output internal information
+
+ printf ("Inside of AttachPreprocessingInfoTreeTrav::display(%s) \n",label.c_str());
+
+ printf (" use_Wave = %s \n",use_Wave ? "true" : "false");
+ printf (" processAllIncludeFiles = %s \n",processAllIncludeFiles ? "true" : "false");
+
+ // printf (" previousLocNodePtr = %p = %s \n",previousLocNodePtr,previousLocNodePtr != NULL ? previousLocNodePtr->class_name().c_str() : "NULL");
+ // printf (" currentListOfAttributes = %p \n",currentListOfAttributes);
+ // printf (" sizeOfCurrentListOfAttributes = %d \n",sizeOfCurrentListOfAttributes);
+ // printf (" currentFileNameId = %d \n",currentFileNameId);
+ // printf (" start_index = %d \n",start_index);
+ // printf (" currentMapOfAttributes = %p \n",currentMapOfAttributes);
+
+ // Call the separate support for output of the static data
+ // AttachPreprocessingInfoTreeTrav::display_static_data(label);
+
+ printf ("attributeMapForAllFiles: \n");
+ for (AttributeMapType::const_iterator i = attributeMapForAllFiles.begin(); i != attributeMapForAllFiles.end(); i++)
+ {
+ printf (" file id = %d list pointer = %p list size = %d filename = %s \n",
+ i->first,i->second,(int)((i->second != NULL) ? i->second->size() : -1),Sg_File_Info::getFilenameFromID(i->first).c_str());
+
+ // After the traversal, the last action in the evaluateSynthesizedAttribute() function for a SgSourceFile,
+ // is to set the pointer to NULL. So this is OK to be NULL if this function is called after the traversal.
+ // ROSE_ASSERT(i->second != NULL);
+ if (i->second != NULL)
+ {
+ i->second->display("Called from AttachPreprocessingInfoTreeTrav::display_static_data()");
+ }
+ }
+
+ printf ("previousLocatedNodeMap: \n");
+ for (previousLocatedNodeInFileType::const_iterator i = previousLocatedNodeMap.begin(); i != previousLocatedNodeMap.end(); i++)
+ {
+ printf (" id = %d previous node = %p = %s file = %s \n",
+ i->first,i->second,(i->second != NULL) ? i->second->class_name().c_str() : "NULL",Sg_File_Info::getFilenameFromID(i->first).c_str());
+
+ // After the traversal, the last action in the evaluateSynthesizedAttribute() function for a SgSourceFile,
+ // is to set the pointer to NULL. So this is OK to be NULL if this function is called after the traversal.
+ // ROSE_ASSERT(i->second != NULL);
+ }
+
+ printf ("startIndexMap: \n");
+ for (StartingIndexAttributeMapType::const_iterator i = startIndexMap.begin(); i != startIndexMap.end(); i++)
+ {
+ printf (" id = %d starting index = %d file = %s \n",
+ i->first,i->second,Sg_File_Info::getFilenameFromID(i->first).c_str());
+ }
+ }
+
+
+void
+AttachPreprocessingInfoTreeTrav::iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( SgLocatedNode* locatedNode, int lineNumber, PreprocessingInfo::RelativePositionType location, bool reset_start_index, ROSEAttributesList *currentListOfAttributes)
+ {
+ // DQ (11/23/2008): Added comment.
+ // This is the main function called to insert all PreprocessingInfo objects into IR nodes. This function currently
+ // adds the PreprocessingInfo objects as attributes, but will be modified to insert the CPP directive specific
+ // PreprocessingInfo objects as separate IR nodes and leave PreprocessingInfo objects that are comments inserts
+ // as attributes. Note that attributes imply PreprocessingInfo specific atributes and not the more general
+ // mechanism available in ROSE for user defined attributes to be saved into the AST.
+
+ ROSE_ASSERT(currentListOfAttributes != NULL);
+
+#if 0
+ // Debugging information...
+ printf ("In iterateOverListAndInsertPrev... locatedNode = %s lineNumber = %d location = %s \n",locatedNode->class_name().c_str(),lineNumber,PreprocessingInfo::relativePositionName(location).c_str());
+ if ( dynamic_cast<SgLocatedNode*>(locatedNode) != NULL )
+ {
+ printf ("starting line number = %d \n",locatedNode->get_startOfConstruct()->get_line());
+ if (locatedNode->get_endOfConstruct() != NULL)
+ printf ("ending line number = %d \n",locatedNode->get_endOfConstruct()->get_line());
+ }
+ else
+ {
+ printf ("locatedNode is not a SgLocatedNode object \n");
+
+ // DQ (12/16/2008): I think this should be an error.
+ ROSE_ASSERT(false);
+ }
+#endif
+
+#if DEBUG_ATTACH_PREPROCESSING_INFO
+ // Debugging information...
+ {
+ int line = locatedNode->get_startOfConstruct()->get_line();
+ int col = locatedNode->get_startOfConstruct()->get_col();
+ cout << "Visiting SgStatement node: " << line << ", " << col << " -> ";
+ cout << getVariantName(locatedNode->variantT()) << endl;
+ }
+#if 0
+ printf("-----> Address: %p\n", locatedNode);
+ cout << "-----> Filename: " << locatedNode->get_file_info()->get_filename() << endl;
+ if (locatedNode->getAttachedPreprocessingInfo() == NULL)
+ cout << "-----> No PreprocessingInfo objects attached yet" << endl;
+ else
+ cout << "-----> There are already PreprocessingInfo objects attached to this AST node" << endl;
+#endif
+ cout << "Traversing current list of attributes of length " << sizeOfCurrentListOfAttributes << endl;
+#endif
+
+ // for ( int i = 0; i < sizeOfCurrentListOfAttributes; i++ )
+ // AS(09/21/07) Because the AttachAllPreprocessingInfoTreeTrav can call the evaluateInheritedAttribute(..)
+ // which calls this function the start_index can not be static for this function. Instead it is made
+ // a class member variable for AttachPreprocessingInfoTreeTrav so that it can be reset by AttachAllPreprocessingInfoTreeTrav
+ // when processing a new file.
+
+ // static int start_index = 0;
+ // int currentFileId = locatedNode->get_startOfConstruct()->get_file_id();
+ Sg_File_Info* locatedFileInfo = locatedNode->get_file_info();
+ int currentFileId = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ locatedFileInfo->get_file_id();
+
+ // printf ("In iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber(): currentFileId = %d \n",currentFileId);
+
+ int start_index = startIndexMap[currentFileId];
+
+ if (attributeMapForAllFiles.find(currentFileId) == attributeMapForAllFiles.end())
+ {
+ printf ("Error: locatedNode = %p = %s currentFileId = %d file = %s \n",locatedNode,locatedNode->class_name().c_str(),currentFileId,Sg_File_Info::getFilenameFromID(currentFileId).c_str());
+ }
+ ROSE_ASSERT(attributeMapForAllFiles.find(currentFileId) != attributeMapForAllFiles.end());
+ int sizeOfCurrentListOfAttributes = attributeMapForAllFiles[currentFileId]->size();
+
+#if 0
+ printf ("Initial start_index = %d \n",start_index);
+#endif
+
+ // DQ (12/23/2008): Note: I think that this should be turned into a while loop (starting at start_index,
+ // to lineNumber when location == PreprocessingInfo::before, and to the sizeOfCurrentListOfAttributes
+ // when location == PreprocessingInfo::after).
+ for ( int i = start_index; i < sizeOfCurrentListOfAttributes; i++ )
+#if 0
+ // DQ (12/23/2008): This is tighter control over the number of iterations required.
+ int i = start_index;
+
+ // We might want this to be tighter in the cases of (location != PreprocessingInfo::before)
+ // Not that here we use a billion to represent a large number.
+ int bound = (location == PreprocessingInfo::before) ? lineNumber : 1000000000;
+
+ PreprocessingInfo *currentPreprocessingInfoPtr = (*currentListOfAttributes)[i];
+ // while (currentPreprocessingInfoPtr->getLineNumber() < bound && i < sizeOfCurrentListOfAttributes)
+ while ( (i < sizeOfCurrentListOfAttributes) && (currentPreprocessingInfoPtr->getLineNumber() < bound) )
+#endif
+ {
+ PreprocessingInfo *currentPreprocessingInfoPtr = (*currentListOfAttributes)[i];
+#if 0
+ if ( currentPreprocessingInfoPtr != NULL )
+ printf ("currentPreprocessingInfoPtr->getLineNumber() = %d lineNumber = %d \n",currentPreprocessingInfoPtr->getLineNumber(),lineNumber);
+#endif
+#if 0
+ printf ("currentPreprocessingInfoPtr->getLineNumber() = %d lineNumber = %d internalString = %s \n",currentPreprocessingInfoPtr->getLineNumber(),lineNumber,currentPreprocessingInfoPtr->getString().c_str());
+#endif
+
+ ROSE_ASSERT(currentPreprocessingInfoPtr != NULL);
+ int currentPreprocessingInfoLineNumber = currentPreprocessingInfoPtr->getLineNumber();
+#if 1
+ // DQ (12/23/2008): So far this is the most reliable way to break out of the loop.
+ ROSE_ASSERT(currentPreprocessingInfoPtr != NULL);
+ if ( (currentPreprocessingInfoLineNumber > lineNumber) && (location == PreprocessingInfo::before) )
+ {
+ // DQ (12/23/2008): I think that under this constraint we could exit this loop!
+ // printf ("Warning: Why are we searching this list of PreprocessingInfo beyond the line number of the current statement (using break) \n");
+
+ // DQ (12/23/2008): I don't like the design which forces an exit from the loop here, but this is the most robust implementation so far.
+ break;
+ }
+#endif
+ // bool attachCommentOrDirective = (currentPreprocessingInfoPtr != NULL) && (currentPreprocessingInfoPtr->getLineNumber() <= lineNumber);
+ bool attachCommentOrDirective = (currentPreprocessingInfoLineNumber <= lineNumber);
+
+ if ( attachCommentOrDirective == true )
+ {
+#if 0
+ printf ("Attaching \"%s\" (from line# %d) to %s locatedNode = %p = %s = %s at line %d \n",
+ currentPreprocessingInfoPtr->getString().c_str(),
+ currentPreprocessingInfoPtr->getLineNumber(),
+ (locatedNode->get_file_info()->isCompilerGenerated() == true) ? "compiler-generated" : "non-compiler-generated",
+ locatedNode,
+ locatedNode->class_name().c_str(),SageInterface::get_name(locatedNode).c_str(),
+ (locatedNode->get_file_info()->isCompilerGenerated() == true) ? -1 : locatedNode->get_file_info()->get_line());
+ // printf ("locatedNode->unparseToString() = %s \n",locatedNode->unparseToString().c_str());
+#endif
+
+ // Mark this PreprocessingInfo object as having been placed into the AST
+ // It might make more sense to remove it from the list so it doesn't have
+ // to be traversed next time.
+ // currentPreprocessingInfoPtr->setHasBeenCopied();
+ currentListOfAttributes->getList()[i] = NULL;
+
+ // DQ (4/13/2007): If we are going to invalidate the list of accumulated attributes then we can start
+ // next time at the next index (at least). This removes the order n^2 complexity of traversing over the whole loop.
+ // start_index = i+1;
+ ROSE_ASSERT(startIndexMap.find(currentFileId) != startIndexMap.end());
+ startIndexMap[currentFileId] = i+1;
+ // printf ("Incremented start_index to be %d \n",startIndexMap[currentFileId]);
+
+ // Mark the location relative to the current node where the PreprocessingInfo
+ // object should be unparsed (before or after) relative to the current locatedNode
+ currentPreprocessingInfoPtr->setRelativePosition(location);
+
+#if 1
+ // This uses the old code to attach comments and CPP directives to the AST as attributes.
+ // printf ("Attaching CPP directives %s to IR nodes as attributes. \n",PreprocessingInfo::directiveTypeName(currentPreprocessingInfoPtr->getTypeOfDirective()).c_str());
+ locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
+#else
+ // Removed older equivalent code!
+#endif
+
+ // For now leave the lists unmodified so that we can support debugging.
+ // delete currentPreprocessingInfoPtr;
+ // currentPreprocessingInfoPtr = NULL;
+
+ // debugging info
+ // printOutComments(locatedNode);
+ }
+#if 0
+ // Increment the loop index
+ i++;
+
+ // Reset the PreprocessingInfo pointer using the incremented value of "i"
+ currentPreprocessingInfoPtr = (*currentListOfAttributes)[i];
+#endif
+ }
+
+ // DQ (12/12/2008): We should not need this state, so why support resetting it, unless the traversal needs to be called multiple times.
+ // DQ (4/13/2007): The evaluation of the synthesized attribute for a SgFile will trigger the reset of the start index to 0.
+ if (reset_start_index == true)
+ {
+ // Reset all the start_index data members (for each associated file)
+ // start_index = 0;
+ for (StartingIndexAttributeMapType::iterator it = startIndexMap.begin(); it != startIndexMap.end(); it++)
+ {
+ it->second = 0;
+ }
+ }
+ }
+
+
+void
+AttachPreprocessingInfoTreeTrav::setupPointerToPreviousNode (SgLocatedNode* currentLocNodePtr )
+ {
+ // If we are at a SgCtorInitializerList IR nodes (and a few others)
+ // then since it is visited last (after the definition) leave the
+ // previousLocNodePtr referenced to the function definition.
+
+ // Supports assertions at end of function
+ SgLocatedNode* previousLocNodePtr = NULL;
+
+ // DQ (12/12/2008): Newer implementation to support multiple files.
+ // int currentFileId = currentLocNodePtr->get_startOfConstruct()->get_file_id();
+ Sg_File_Info* locatedFileInfo = currentLocNodePtr->get_file_info();
+ int currentFileId = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ locatedFileInfo->get_file_id();
+
+#if 0
+ printf ("setupPointerToPreviousNode: currentFileId = %d currentLocNodePtr = %s \n",currentFileId,currentLocNodePtr->class_name().c_str());
+#endif
+
+ if ( (dynamic_cast<SgForInitStatement*> (currentLocNodePtr) == NULL) &&
+ (dynamic_cast<SgTypedefSeq*> (currentLocNodePtr) == NULL) &&
+ (dynamic_cast<SgCatchStatementSeq*> (currentLocNodePtr) == NULL) &&
+ (dynamic_cast<SgFunctionParameterList*>(currentLocNodePtr) == NULL) &&
+ (dynamic_cast<SgCtorInitializerList*> (currentLocNodePtr) == NULL) )
+ {
+#if 0
+ // Debugging output...
+ if (previousLocatedNodeMap.find(currentFileId) == previousLocatedNodeMap.end())
+ {
+ printf ("Note that previousLocatedNodeMap does not have an entry for currentFileId = %d \n",currentFileId);
+ }
+#endif
+ previousLocatedNodeMap[currentFileId] = currentLocNodePtr;
+ ROSE_ASSERT(previousLocatedNodeMap.find(currentFileId) != previousLocatedNodeMap.end());
+
+ // Supports assertions at end of function
+ previousLocNodePtr = currentLocNodePtr;
+ }
+ else
+ {
+ SgStatement* currentStatement = dynamic_cast<SgStatement*>(currentLocNodePtr);
+ ROSE_ASSERT (currentStatement != NULL);
+ SgStatement* parentStatement = isSgStatement(currentStatement->get_parent());
+
+ // We can't enforce this since currentStatement may be SgGlobal and the parent
+ // is SgSourceFile (which is not a SgStatement).
+ // ROSE_ASSERT (parentStatement != NULL);
+ ROSE_ASSERT ( (parentStatement != NULL) || (isSgGlobal(currentStatement) != NULL) );
+
+ // printf ("parentStatement = %s \n",parentStatement->sage_class_name());
+ previousLocatedNodeMap[currentFileId] = parentStatement;
+
+ // Supports assertions at end of function
+ previousLocNodePtr = parentStatement;
+ }
+
+ // Nodes that should not have comments attached (since they are not unparsed directly
+ // within the generation of the source code by the unparser (no associated unparse functions))
+ ROSE_ASSERT (dynamic_cast<SgForInitStatement*> (previousLocNodePtr) == NULL);
+ ROSE_ASSERT (dynamic_cast<SgTypedefSeq*> (previousLocNodePtr) == NULL);
+ ROSE_ASSERT (dynamic_cast<SgCatchStatementSeq*> (previousLocNodePtr) == NULL);
+ ROSE_ASSERT (dynamic_cast<SgFunctionParameterList*>(previousLocNodePtr) == NULL);
+ ROSE_ASSERT (dynamic_cast<SgCtorInitializerList*> (previousLocNodePtr) == NULL);
+ }
+
+
+ROSEAttributesList*
+AttachPreprocessingInfoTreeTrav::buildCommentAndCppDirectiveList ( bool use_Wave )
+ {
+ // This function abstracts the collection of comments and CPP directives into a list.
+ // The list is then used to draw from as the AST is traversed and the list elements
+ // are woven into the AST.
+#if 0
+ printf ("Inside of AttachPreprocessingInfoTreeTrav::buildCommentAndCppDirectiveList(use_Wave = %s) \n",use_Wave ? "true" : "false");
+#endif
+
+ // DQ (12/10/2007): Declare Fortran specific lexical pass function explicitly.
+ // extern int getFortranFixedFormatPreprocessorDirectives( std::string fileName );
+ // extern int getFortranFreeFormatPreprocessorDirectives ( std::string fileName );
+#ifdef USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
+ extern std::list <stream_element*>* getFortranFixedFormatPreprocessorDirectives( std::string fileName );
+ extern std::list <stream_element*>* getFortranFreeFormatPreprocessorDirectives ( std::string fileName );
+#endif
+
+ ROSEAttributesList* returnListOfAttributes = new ROSEAttributesList();
+
+ // Build an empty list while we skip the translation of tokens
+ // returnListOfAttributes = new ROSEAttributesList();
+
+ ROSE_ASSERT(sourceFile != NULL);
+ string fileNameForDirectivesAndComments = sourceFile->get_sourceFileNameWithPath();
+ string fileNameForTokenStream = fileNameForDirectivesAndComments;
+
+ // If this is a CPP processed file then modify the name to reflect that the CPP output is
+ // to be process and it was assigned a different file name (with "_preprocessed" suffix).
+ if (sourceFile->get_requires_C_preprocessor() == true)
+ {
+ fileNameForDirectivesAndComments = sourceFile->generate_C_preprocessor_intermediate_filename(fileNameForDirectivesAndComments);
+ }
+#if 0
+ printf ("Inside of buildCommentAndCppDirectiveList(): fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
+ printf (" fileNameForTokenStream = %s \n",fileNameForTokenStream.c_str());
+#endif
+
+ // currentFileNameId = currentFilePtr->get_file_info()->get_file_id();
+ // ROSE_ASSERT(currentFileNameId >= 0);
+
+ // Note that we need the SgSourceFile so that we get information about what language type this is to support.
+ // SgSourceFile* currentFilePtr = sourceFile;
+
+ if (use_Wave == false)
+ {
+ // DQ (4/12/2007): Introduce tracking of performance of ROSE.
+ TimingPerformance timer ("AST evaluateInheritedAttribute (use_Wave == false):");
+
+ if (sourceFile->get_Fortran_only() == true)
+ {
+#ifdef USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
+ // This is either of two different kinds of Fortran programs: fixed format or free format
+ // * fix format is generally used for older Fortran code, F77 and earlier, and
+ // * free format is generall used for newer codes, F90 and later
+ // * however this is a general rule, specifically a F03 code can use fixed format.
+
+ // If it is not explicitly fixed form, then assume it is free form input.
+ // if (currentFilePtr->get_fixedFormat() == true)
+ if (sourceFile->get_inputFormat() == SgFile::e_fixed_form_output_format)
+ {
+ if ( SgProject::get_verbose() > 1 )
+ {
+ printf ("Fortran code assumed to be in fixed format form (skipping translation of tokens) \n");
+ }
+
+ // For now we call the lexical pass on the fortran file, but we don't yet translate the tokens.
+ // returnListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
+ // getFortranFixedFormatPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
+ // LexTokenStreamTypePointer lex_token_stream = getFortranFixedFormatPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
+ LexTokenStreamTypePointer lex_token_stream = getFortranFixedFormatPreprocessorDirectives( fileNameForTokenStream );
+ ROSE_ASSERT(lex_token_stream != NULL);
+
+ // Attach the token stream to the AST
+ returnListOfAttributes->set_rawTokenStream(lex_token_stream);
+#if 1
+ // DQ (11/23/2008): This is the new support to collect CPP directives and comments from Fortran applications.
+ // printf ("Calling collectPreprocessorDirectivesAndCommentsForAST() to collect CPP directives for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
+ returnListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_Fortran77_language);
+ // printf ("DONE: Calling collectPreprocessorDirectivesAndCommentsForAST() to collect CPP directives for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
+#endif
+#if 0
+ // DQ (11/19/2008): This code has been replaced by collectPreprocessorDirectivesAndCommentsForAST().
+ // Process the raw token stream into the PreprocessorDirectives and Comment list required to be inserted into the AST.
+ // returnListOfAttributes->collectFixedFormatPreprocessorDirectivesAndCommentsForAST(currentFilePtr->get_sourceFileNameWithPath());
+ returnListOfAttributes->collectFixedFormatPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments);
+#endif
+ }
+ else
+ {
+ // int currentFileNameId = currentFilePtr->get_file_info()->get_file_id();
+ // For now we call the lexical pass on the fortran file, but we don't yet translate the tokens.
+ // returnListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
+ // getFortranFreeFormatPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
+ // string fileNameForTokenStream = Sg_File_Info::getFilenameFromID(currentFileNameId);
+
+ LexTokenStreamTypePointer lex_token_stream = getFortranFreeFormatPreprocessorDirectives( fileNameForTokenStream );
+ ROSE_ASSERT(lex_token_stream != NULL);
+
+ // Attach the token stream to the AST
+ returnListOfAttributes->set_rawTokenStream(lex_token_stream);
+ ROSE_ASSERT(returnListOfAttributes->get_rawTokenStream() != NULL);
+
+ // printf ("Fortran Token List Size: returnListOfAttributes->get_rawTokenStream()->size() = %zu \n",returnListOfAttributes->get_rawTokenStream()->size());
+
+ // DQ (11/23/2008): This is the new support to collect CPP directives and comments from Fortran applications.
+ // printf ("Calling collectPreprocessorDirectivesAndCommentsForAST() to collect CPP directives for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
+ returnListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_Fortran9x_language);
+
+#if 0
+ printf ("Done with processing of separate lexical pass to gather CPP directives \n");
+ ROSE_ASSERT(false);
+#endif
+#if 0
+ // DQ (11/19/2008): This code has been replaced by collectPreprocessorDirectivesAndCommentsForAST().
+ printf ("Calling generatePreprocessorDirectivesAndCommentsForAST() for fileNameForDirectivesAndComments = %s \n",fileNameForDirectivesAndComments.c_str());
+ returnListOfAttributes->generatePreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments);
+#endif
+ }
+
+#if 0
+ printf ("Done with processing of separate lexical pass to gather Fortran specific CPP directives and comments from the token stream \n");
+ ROSE_ASSERT(false);
+#endif
+
+#else // for !USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
+ fprintf(stderr, "Fortran parser not enabled \n");
+ ROSE_ABORT();
+#endif // USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
+ }
+ else
+ {
+ // Else we assume this is a C or C++ program (for which the lexical analysis is identical)
+ // The lex token stream is now returned in the ROSEAttributesList object.
+
+#if 1
+ // DQ (11/23/2008): This is part of CPP handling for Fortran, but tested on C and C++ codes aditionally, (it is redundant for C and C++).
+ // This is a way of testing the extraction of CPP directives (on C and C++ codes, so that it is more agressively tested).
+ // Since this is a redundant test, it can be removed in later development (its use is only a performance issue).
+ // returnListOfAttributes = new ROSEAttributesList();
+
+ // This call is just a test, this function is defined for use on Fortran. For C and C++ we have alternative methods to extract the CPP directives and comments.
+ // printf ("Call collectPreprocessorDirectivesAndCommentsForAST to test C and C++ preprocessor directive collection \n");
+ returnListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(fileNameForDirectivesAndComments,ROSEAttributesList::e_C_language);
+ // printf ("DONE: Call collectPreprocessorDirectivesAndCommentsForAST to test C and C++ preprocessor directive collection \n");
+#endif
+
+ // This function has been modified to clear any existing list of PreprocessingInfo*
+ // objects (so that we can test the function: collectPreprocessorDirectivesAndCommentsForAST()).
+ // returnListOfAttributes = getPreprocessorDirectives( Sg_File_Info::getFilenameFromID(currentFileNameId) );
+ // printf ("Calling lex or wave based mechanism for collecting CPP directives, comments, and token stream \n");
+ returnListOfAttributes = getPreprocessorDirectives(fileNameForDirectivesAndComments);
+ // printf ("DONE: Calling lex or wave based mechanism for collecting CPP directives, comments, and token stream \n");
+ }
+ }
+ else
+ {
+ // This is the case of: (use_Wave == true). This mode does NOT work for Fortran code!
+ ROSE_ASSERT(sourceFile->get_Fortran_only() == false);
+
+ // AS(011306) fetch the list of attributes from the Wave output
+ // int currentFileNameId = currentFilePtr->get_file_info()->get_file_id();
+ // std::string currentStringFilename = Sg_File_Info::getFilenameFromID(currentFileNameId);
+ string currentStringFilename = sourceFile->get_file_info()->get_filename();
+
+#if 0
+ // DQ (12/12/2008): Comment out for now while we work on non-wave support.
+ ROSE_ASSERT(mapOfAttributes != NULL);
+ if (mapOfAttributes->find(currentStringFilename) == mapOfAttributes->end())
+ {
+ // There is no existing list for this file, so build an empty list.
+ // returnListOfAttributes = new ROSEAttributesList();
+ }
+ else
+ {
+ // If there already exists a list for the current file then get that list.
+ ROSE_ASSERT( mapOfAttributes->find(currentStringFilename)->second != NULL);
+
+ // Delete the empty list build at the top of the function.
+ delete returnListOfAttributes;
+ returnListOfAttributes = NULL;
+
+ returnListOfAttributes = mapOfAttributes->find(currentStringFilename)->second;
+ }
+#else
+ printf ("Commented out for now while we work on non-wave support. \n");
+ ROSE_ASSERT(false);
+#endif
+ }
+
+ ROSE_ASSERT(returnListOfAttributes != NULL);
+
+ return returnListOfAttributes;
+ }
+
+
+ROSEAttributesList*
+AttachPreprocessingInfoTreeTrav::getListOfAttributes ( int currentFileNameId )
+ {
+ // This function will get the list of CPP directives and comments if it exists,
+ // or build it if required. The function is called each time we come to a IR
+ // node as part of the traversal. If it is a new IR node (from a file not previously
+ // visited) then the associated file will be read to gather its CPP directives and
+ // comments.
+
+ ROSEAttributesList* currentListOfAttributes = NULL;
+
+#if 0
+ printf ("In AttachPreprocessingInfoTreeTrav::getListOfAttributes() currentFileNameId = %d file = %s \n",currentFileNameId,Sg_File_Info::getFilenameFromID(currentFileNameId).c_str());
+#endif
+
+ // Check if this is a file id that is associated with a source file or a special
+ // value to represent compiler generated IR nodes, transformations, etc.
+ if (currentFileNameId >= 0)
+ {
+ // Check if the attributes have been gathered for this file
+ if (attributeMapForAllFiles.find(currentFileNameId) == attributeMapForAllFiles.end())
+ {
+ // If not then read the file and collect the CPP directives and comments from each file.
+
+ // We always want to process the source file, but not always all the include files.
+ // int sourceFileNameId = sourceFile->get_file_info()->get_file_id();
+ Sg_File_Info* sourceFileInfo = sourceFile->get_file_info();
+ int sourceFileNameId = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFileInfo->get_filename())) :
+ sourceFileInfo->get_file_id();
+
+ bool skipProcessFile = (processAllIncludeFiles == false) && (currentFileNameId != sourceFileNameId);
+#if 0
+ printf ("currentFileNameId = %d sourceFileNameId = %d skipProcessFile = %s \n",currentFileNameId,sourceFileNameId,skipProcessFile ? "true" : "false");
+#endif
+ if (skipProcessFile == false)
+ {
+ attributeMapForAllFiles[currentFileNameId] = buildCommentAndCppDirectiveList(use_Wave);
+
+ ROSE_ASSERT(attributeMapForAllFiles.find(currentFileNameId) != attributeMapForAllFiles.end());
+ currentListOfAttributes = attributeMapForAllFiles[currentFileNameId];
+ ROSE_ASSERT(currentListOfAttributes != NULL);
+ }
+ }
+ else
+ {
+ currentListOfAttributes = attributeMapForAllFiles[currentFileNameId];
+ ROSE_ASSERT(currentListOfAttributes != NULL);
+ }
+ }
+
+ return currentListOfAttributes;
+ }
+
+
+// Member function: evaluateInheritedAttribute
+AttachPreprocessingInfoTreeTraversalInheritedAttrribute
+AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute (
+ SgNode *n,
+ AttachPreprocessingInfoTreeTraversalInheritedAttrribute inheritedAttribute)
+ {
+ // This is this inherited attribute evaluation. It is executed as a preorder traversal
+ // of the AST. We don't use anything in the inherited attribute at present, however,
+ // some actions have to be executed as we first visit an IR node and some have to be
+ // executed as we last vist an IR node (post-order; see the evaluateSynthezidedAttribute()
+ // member function).
+
+#if 0
+ printf ("In AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): n->class_name() = %s \n",n->class_name().c_str());
+#endif
+
+ // Check if current AST node is an SgFile object
+ SgFile* currentFilePtr = isSgFile(n);
+ if ( currentFilePtr != NULL )
+ {
+ // Current AST node is an SgFile object, generate the corresponding list of attributes
+
+#if DEBUG_ATTACH_PREPROCESSING_INFO
+ cout << "=== Visiting SgSourceFile node and building current list of attributes ===" << endl;
+#endif
+
+ // This entry should not be present, so generate the list.
+ // If this is a preprocessed file then change the name so that we generate the correct list for the correct file.
+ // int currentFileNameId = currentFilePtr->get_file_info()->get_file_id();
+ Sg_File_Info* currentFileInfo = currentFilePtr->get_file_info();
+ ROSE_ASSERT(currentFileInfo != NULL);
+#if 0
+ printf ("(SgSourceFile) currentFilePtr->get_requires_C_preprocessor() = %s \n",currentFilePtr->get_requires_C_preprocessor() == true ? "true" : "false");
+ printf ("(SgSourceFile) sourceFile->get_file_info()->get_filename() = %s \n",sourceFile->get_file_info()->get_filename());
+#endif
+ ROSE_ASSERT(sourceFile == currentFilePtr);
+#if 0
+ printf ("(SgSourceFile) currentFilePtr->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename()) = %s \n",currentFilePtr->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename()).c_str());
+#endif
+ int currentFileNameId = (currentFilePtr->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(currentFilePtr->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ currentFileInfo->get_file_id();
+#if 0
+ printf ("(SgSourceFile) currentFileNameId = %d \n",currentFileNameId);
+ printf ("(SgSourceFile) currentFileName for currentFileNameId = %s \n",Sg_File_Info::getFilenameFromID(currentFileNameId).c_str());
+#endif
+ // Temporary code (testing this)
+ ROSE_ASSERT(currentFileNameId >= 0);
+#if 0
+ if (currentFileNameId < 0)
+ {
+ printf ("Error (currentFileNameId < 0): currentFileNameId = %d (return from evaluateInheritedAttribute function) \n",currentFileNameId);
+ ROSE_ASSERT(false);
+
+ return inheritedAttribute;
+ }
+#endif
+ ROSE_ASSERT(attributeMapForAllFiles.find(currentFileNameId) == attributeMapForAllFiles.end());
+
+ // This will cause the CPP directives and comments list to be generated for the source file.
+ ROSEAttributesList* currentListOfAttributes = getListOfAttributes(currentFileNameId);
+ ROSE_ASSERT(currentListOfAttributes != NULL);
+ }
+ else
+ {
+ // The current node is NOT a SgFile IR node.
+
+ // Move attributes from the list of attributes into the collection of the current AST nodes,
+ // we only consider statements for the moment, but this needs to be refined further on.
+ // Probably we will have to consider each SgLocatedNode IR node within the AST.
+ // if (dynamic_cast<SgStatement*>(n) != NULL)
+ SgStatement* statement = isSgStatement(n);
+ if (statement != NULL)
+ {
+ SgLocatedNode* currentLocNodePtr = NULL;
+ int line = 0;
+ int col = 0;
+
+ // The following should always work since each statement is a located node
+ currentLocNodePtr = dynamic_cast<SgLocatedNode*>(n);
+ ROSE_ASSERT(currentLocNodePtr != NULL);
+
+ // Attach the comments only to nodes from the same file
+ ROSE_ASSERT(currentLocNodePtr->get_file_info() != NULL);
+ // int currentFileNameId = currentLocNodePtr->get_file_info()->get_file_id();
+ Sg_File_Info* currentFileInfo = currentLocNodePtr->get_file_info();
+ ROSE_ASSERT(currentFileInfo != NULL);
+ int currentFileNameId = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ currentFileInfo->get_file_id();
+#if 0
+ printf ("(SgStatement) currentFileNameId = %d \n",currentFileNameId);
+ printf ("(SgStatement) currentFileName for currentFileNameId = %s \n",Sg_File_Info::getFilenameFromID(currentFileNameId).c_str());
+#endif
+ ROSEAttributesList* currentListOfAttributes = getListOfAttributes(currentFileNameId);
+
+ // printf ("currentListOfAttributes = %p \n",currentListOfAttributes);
+
+ // If currentListOfAttributes == NULL then this was not an IR node from a file where we wanted
+ // to include CPP directives and comments.
+ if (currentListOfAttributes != NULL)
+ {
+ // DQ (6/20/2005): Compiler generated is not enough, it must be marked for output explicitly
+ // bool isCompilerGenerated = currentLocNodePtr->get_file_info()->isCompilerGenerated();
+ bool isCompilerGenerated = currentLocNodePtr->get_file_info()->isCompilerGeneratedNodeToBeUnparsed();
+
+ // JJW (6/25/2008): These are always flagged as "to be unparsed", even if they are not
+ // unparsed because their corresponding declarations aren't unparsed
+ if (isSgClassDefinition(currentLocNodePtr) || isSgFunctionDefinition(currentLocNodePtr))
+ {
+ SgLocatedNode* ln = isSgLocatedNode(currentLocNodePtr->get_parent());
+ Sg_File_Info* parentFi = ln ? ln->get_file_info() : NULL;
+ if (parentFi && parentFi->isCompilerGenerated() && !parentFi->isCompilerGeneratedNodeToBeUnparsed())
+ {
+ isCompilerGenerated = false;
+ }
+ }
+ bool isTransformation = currentLocNodePtr->get_file_info()->isTransformation();
+
+ // Try to not call get_filename() if it would be inappropriate (either when isCompilerGenerated || isTransformation)
+
+ // DQ (10/27/2007): Initialized to -1 upon suggestion by Andreas.
+ int fileIdForOriginOfCurrentLocatedNode = -1;
+ if ( !isCompilerGenerated && !isTransformation )
+ {
+ // fileIdForOriginOfCurrentLocatedNode = currentLocNodePtr->get_file_info()->get_file_id();
+ Sg_File_Info* currentFileInfo = currentLocNodePtr->get_file_info();
+ ROSE_ASSERT(currentFileInfo != NULL);
+ fileIdForOriginOfCurrentLocatedNode = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ currentFileInfo->get_file_id();
+ }
+
+#if 0
+ printf ("evaluateInheritedAttribute: isCompilerGenerated = %s isTransformation = %s fileIdForOriginOfCurrentLocatedNode = %d \n",
+ isCompilerGenerated ? "true" : "false",isTransformation ? "true" : "false",fileIdForOriginOfCurrentLocatedNode);
+#endif
+ // DQ (5/24/2005): Relaxed to handle compiler generated and transformed IR nodes
+ if ( isCompilerGenerated || isTransformation || currentFileNameId == fileIdForOriginOfCurrentLocatedNode )
+ {
+ // Current node belongs to the file the name of which has been specified
+ // on the command line
+ line = currentLocNodePtr->get_file_info()->get_line();
+ col = currentLocNodePtr->get_file_info()->get_col();
+#if 0
+ printf ("Insert any comment before %p = %s = %s (compilerGenerate=%s) at line = %d col = %d \n",
+ currentLocNodePtr,currentLocNodePtr->class_name().c_str(),SageInterface::get_name(currentLocNodePtr).c_str(),
+ isCompilerGenerated ? "true" : "false", line, col);
+#endif
+#if 0
+ printf ("In AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute() calling iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber(): n->class_name() = %s \n",n->class_name().c_str());
+#endif
+
+ // Iterate over the list of comments and directives and add them to the AST
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber(
+ currentLocNodePtr,line,PreprocessingInfo::before, reset_start_index,
+ currentListOfAttributes );
+
+ // save the previous node (in an accumulator attribute), but handle some nodes differently
+ // to avoid having comments attached to them since they are not unparsed directly.
+ // printf ("currentLocNodePtr = %p = %s \n",currentLocNodePtr,currentLocNodePtr->class_name().c_str());
+ setupPointerToPreviousNode(currentLocNodePtr);
+ }
+#if 0
+ // Debugging output
+ else
+ {
+ cout << "Node belongs to a different file: ";
+ }
+#endif
+ }
+ }
+ }
+
+ return inheritedAttribute;
+ }
+
+
+// Member function: evaluateSynthesizedAttribute
+AttachPreprocessingInfoTreeTraversalSynthesizedAttribute
+AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(
+ SgNode *n,
+ AttachPreprocessingInfoTreeTraversalInheritedAttrribute inheritedAttribute,
+ SubTreeSynthesizedAttributes synthiziedAttributeList)
+ {
+ // DQ (11/29/2008): FIXME: Note that this traversal does not use its inheritedAttribute
+ // or synthiziedAttributeList attributes, so it could be expressed as a much
+ // simpler visit traversal. We might do that later, if we decide that we REALLY
+ // don't require inheritedAttribute or synthiziedAttributeList attributes.
+
+ AttachPreprocessingInfoTreeTraversalSynthesizedAttribute returnSynthesizeAttribute;
+
+#if 0
+ printf ("In AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(): n->class_name() = %s \n",n->class_name().c_str());
+ if (isSgStatement(n) && (isSgStatement(n)->get_parent() != NULL) )
+ {
+ printf (" parent = %s \n",isSgStatement(n)->get_parent()->class_name().c_str());
+ ROSE_ASSERT(isSgStatement(n)->get_file_info() != NULL);
+ isSgStatement(n)->get_file_info()->display("In AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute()");
+ }
+#endif
+
+ // These used to be a problem, so we can continue to test tese specific cases.
+ ROSE_ASSERT (isSgCaseOptionStmt(n) == NULL || isSgCaseOptionStmt(n)->get_body() != NULL);
+ ROSE_ASSERT (isSgClassDeclaration(n) == NULL || isSgClassDeclaration(n)->get_endOfConstruct() != NULL);
+
+ // Only process SgLocatedNode object and the SgFile object
+ SgFile* fileNode = dynamic_cast<SgFile*>(n);
+ SgLocatedNode* locatedNode = dynamic_cast<SgLocatedNode*>(n);
+ if ( (locatedNode != NULL) || (fileNode != NULL) )
+ {
+#if 1
+ // Attach the comments only to nodes from the same file
+ // int fileNameId = currentFileNameId;
+ // ROSE_ASSERT(locatedNode->get_file_info() != NULL);
+ int currentFileNameId = -9;
+ if (locatedNode != NULL)
+ {
+ ROSE_ASSERT(locatedNode->get_file_info() != NULL);
+ currentFileNameId = locatedNode->get_file_info()->get_file_id();
+ }
+ else
+ {
+ // ROSE_ASSERT(fileNode->get_file_info() != NULL);
+ // currentFileNameId = fileNode->get_file_info()->get_file_id();
+ Sg_File_Info* currentFileInfo = sourceFile->get_file_info();
+ ROSE_ASSERT(currentFileInfo != NULL);
+ currentFileNameId = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ currentFileInfo->get_file_id();
+ }
+#else
+ // DQ (12/17/2008): this should be simpler code.
+ currentFileNameId = n->get_file_info()->get_file_id();
+#endif
+
+#if 0
+ printf ("currentFileNameId = %d \n",currentFileNameId);
+#endif
+ // DQ (10/27/2007): This is a valgrind error: use of uninitialized variable below!
+ // Initialized with a value that could not match a valid file_id.
+ int fileIdForOriginOfCurrentLocatedNode = -99;
+
+ bool isCompilerGeneratedOrTransformation = false;
+ int lineOfClosingBrace = 0;
+ if (locatedNode != NULL)
+ {
+ ROSE_ASSERT(locatedNode->get_file_info());
+ // printf ("Calling locatedNode->get_file_info()->get_filename() \n");
+
+ // DQ (6/20/2005): Compiler generated IR nodes to be output are now marked explicitly!
+ // isCompilerGeneratedOrTransformation = locatedNode->get_file_info()->isCompilerGenerated() ||
+ // locatedNode->get_file_info()->isTransformation() ||
+ isCompilerGeneratedOrTransformation = locatedNode->get_file_info()->isCompilerGeneratedNodeToBeUnparsed() ||
+ locatedNode->get_file_info()->isTransformation();
+
+ // bool isCompilerGenerated = currentLocNodePtr->get_file_info()->isCompilerGeneratedNodeToBeUnparsed();
+ // bool isTransformation = currentLocNodePtr->get_file_info()->isTransformation();
+
+ // DQ (6/20/2005): Notice that we use the new hasPositionInSource() member function
+ // if ( isCompilerGeneratedOrTransformation == false )
+ if ( locatedNode->get_file_info()->hasPositionInSource() == true )
+ fileIdForOriginOfCurrentLocatedNode = locatedNode->get_file_info()->get_file_id();
+
+ if (locatedNode->get_endOfConstruct() != NULL)
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+ lineOfClosingBrace = locatedNode->get_endOfConstruct()->get_line();
+ }
+ }
+ else
+ {
+ // handle the trivial case of a SgFile node being from it's own file
+ // fileIdForOriginOfCurrentLocatedNode = currentFileNameId;
+ // fileIdForOriginOfCurrentLocatedNode = sourceFile->get_file_info()->get_file_id();
+
+ Sg_File_Info* currentFileInfo = sourceFile->get_file_info();
+ ROSE_ASSERT(currentFileInfo != NULL);
+ fileIdForOriginOfCurrentLocatedNode = (sourceFile->get_requires_C_preprocessor() == true) ?
+ Sg_File_Info::getIDFromFilename(sourceFile->generate_C_preprocessor_intermediate_filename(sourceFile->get_file_info()->get_filename())) :
+ currentFileInfo->get_file_id();
+
+ // Use one billion as the max number of lines in a file
+ const int OneBillion = 1000000000;
+
+ lineOfClosingBrace = OneBillion;
+ }
+#if 0
+ printf ("currentFileNameId = %d fileIdForOriginOfCurrentLocatedNode = %d \n",currentFileNameId,fileIdForOriginOfCurrentLocatedNode);
+ printf ("currentFileName for currentFileNameId = %s \n",Sg_File_Info::getFilenameFromID(currentFileNameId).c_str());
+#endif
+ // Make sure the astNode matches the current file's list of comments and CPP directives.
+ // DQ (5/24/2005): Handle cases of isCompilerGenerated or isTransformation
+ if ( (isCompilerGeneratedOrTransformation == true) || (currentFileNameId == fileIdForOriginOfCurrentLocatedNode) )
+ {
+#if 0
+ printf ("In AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(): %p = %s lineOfClosingBrace = %d \n",
+ n,n->sage_class_name(),lineOfClosingBrace);
+#endif
+
+#if 0
+ // Debugging code
+ if (attributeMapForAllFiles.find(currentFileNameId) == attributeMapForAllFiles.end())
+ {
+ Sg_File_Info::display_static_data("debugging in AttachPreprocessingInfoTreeTrav");
+
+ // output internal data in maps...
+ // display_static_data("debugging in AttachPreprocessingInfoTreeTrav");
+ display("debugging in AttachPreprocessingInfoTreeTrav");
+ }
+
+ printf ("currentFileName for currentFileNameId = %d = %s \n",currentFileNameId,Sg_File_Info::getFilenameFromID(currentFileNameId).c_str());
+#endif
+ // Note that since this is for the original file, the list of attributes should already be in the map.
+ // Note that values of currentFileNameId < 0 are for IR nodes that don't have a mapped source position
+ // (e.g. compiler generated, unknown, etc.).
+ ROSE_ASSERT(processAllIncludeFiles == false || ((currentFileNameId < 0) || (attributeMapForAllFiles.find(currentFileNameId) != attributeMapForAllFiles.end())));
+
+ // ROSEAttributesList* currentListOfAttributes = attributeMapForAllFiles[currentFileNameId];
+ ROSEAttributesList* currentListOfAttributes = getListOfAttributes(currentFileNameId);
+ // ROSE_ASSERT(currentListOfAttributes != NULL);
+ if (currentListOfAttributes == NULL)
+ {
+#if 0
+ printf ("Not supporting gathering of CPP directives and comments for this file currentFileNameId = %d \n",currentFileNameId);
+#endif
+ return returnSynthesizeAttribute;
+ }
+
+ ROSE_ASSERT(previousLocatedNodeMap.find(currentFileNameId) != previousLocatedNodeMap.end());
+ SgLocatedNode* previousLocNodePtr = previousLocatedNodeMap[currentFileNameId];
+
+ switch (n->variantT())
+ {
+ // SgBinaryFile need not be in the switch since we don't attach CPP directives or comments to it.
+ case V_SgBinaryFile:
+ {
+ printf ("Error: SgBinaryFile need not be in the switch since we don't attach CPP directives or comments to it ... \n");
+ ROSE_ASSERT(false);
+ break;
+ }
+
+ // I wanted to leave the SgFile case in the switch statement rather
+ // than separating it out in a conditional statement at the top of the file.
+ // case V_SgFile:
+ case V_SgSourceFile:
+ {
+ // printf ("Case SgFile: See if we can find a better target to attach these comments than %s \n",
+ // previousLocNodePtr->sage_class_name());
+
+ // SgLocatedNode* targetNode = previousLocNodePtr;
+ ROSE_ASSERT(previousLocatedNodeMap.find(currentFileNameId) != previousLocatedNodeMap.end());
+ SgLocatedNode* targetNode = previousLocatedNodeMap[currentFileNameId];
+
+ // printf ("In SgFile: previousLocNodePtr = %s \n",previousLocNodePtr->sage_class_name());
+ // printf ("In SgSourceFile: initial value of targetNode = %p = %s \n",targetNode,targetNode->class_name().c_str());
+
+ // If the target is a SgBasicBlock then try to find its parent in the global scope
+ // if (isSgBasicBlock(previousLocNodePtr) != NULL)
+ if (isSgBasicBlock(targetNode) != NULL)
+ {
+ while ( (targetNode != NULL) && (isSgGlobal(targetNode->get_parent()) == NULL) )
+ {
+ targetNode = dynamic_cast<SgLocatedNode*>(targetNode->get_parent());
+ // printf ("loop: targetNode = %s \n",targetNode->sage_class_name());
+ }
+ }
+
+ // This case appears for test2008_08.f90: the SgProgramHeaderStatement is not present in the source code
+ // so we can't attach a comment to it.
+ if (targetNode->get_file_info()->get_file_id() < 0)
+ {
+ printf ("Error: we should not be calling iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber() using targetNode->get_file_info()->get_file_id() = %d \n",targetNode->get_file_info()->get_file_id());
+ printf ("In SgFile: targetNode = %s \n",targetNode->class_name().c_str());
+ printf ("currentFileName for currentFileNameId = %d = %s \n",currentFileNameId,Sg_File_Info::getFilenameFromID(currentFileNameId).c_str());
+ printf ("sourceFile = %s \n",sourceFile->get_sourceFileNameWithPath().c_str());
+
+ ROSE_ASSERT(false);
+ // return returnSynthesizeAttribute;
+ }
+
+ // Iterate over the list of comments and directives and add them to the AST
+ bool reset_start_index = true;
+ // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ // ( targetNode, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index,inheritedAttribute.currentListOfAttributes );
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( targetNode, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index, currentListOfAttributes );
+
+ // DQ (12/19/2008): Output debugging information (needs to be output before we reset the attributeMapForAllFiles map entries
+ if ( SgProject::get_verbose() >= 3 )
+ {
+ bool processAllFiles = sourceFile->get_collectAllCommentsAndDirectives();
+ if (processAllFiles == true)
+ display("Output from collecting ALL comments and CPP directives (across source and header files)");
+ else
+ display("Output from collecting comments and CPP directives in source file only");
+ }
+
+#if 0
+ // DQ (1/22/2008): This IS a problem for the AST file I/O...which tries to write out the ROSEAttributesList of PreprocessingInfo objects.
+ // This is likely because the elements of that list are shared and were already processed at an earlier step in the AST File I/O.
+ // This is not a problem for the list of PreprocessingInfo since at this point they have already been added to the AST and are no longer
+ // required. If we want to keep the actual token stream then that will have to be addressed. We should also consider translating the
+ // raw token stream (using the lex data structures) to use the SgToken data structure so that it could be saved with the AST. All of
+ // this is later work however...
+
+ // DQ (1/21/2008): Save the details of the token information for this file (even though at this point we are mostly done with it)
+ SgFile* file = isSgFile(n);
+ string filename = file->get_sourceFileNameWithPath();
+ ROSE_ASSERT(file->get_preprocessorDirectivesAndCommentsList() != NULL);
+
+ // printf ("Adding secondary lex pass information (inheritedAttribute.currentListOfAttributes = %p) to file = %s \n",inheritedAttribute.currentListOfAttributes,filename.c_str());
+ file->get_preprocessorDirectivesAndCommentsList()->addList(filename,inheritedAttribute.currentListOfAttributes);
+#else
+ // DQ (1/21/2008): Original code
+ // printf ("Delete Fortran Token List Size: currentListOfAttributes->get_rawTokenStream()->size() = %zu \n",currentListOfAttributes->get_rawTokenStream()->size());
+ // delete inheritedAttribute.currentListOfAttributes;
+ // delete currentListOfAttributes;
+ ROSE_ASSERT(attributeMapForAllFiles.find(currentFileNameId) != attributeMapForAllFiles.end());
+
+ // For now just reset the pointer to NULL, but later we might want to delete the lists (to avoid a memory leak).
+ // delete attributeMapForAllFiles[currentFileNameId];
+ attributeMapForAllFiles[currentFileNameId] = NULL;
+#endif
+ currentListOfAttributes = NULL;
+
+ // Reset the pointer to the previous located node and the current list size
+ previousLocatedNodeMap[currentFileNameId] = NULL;
+ startIndexMap[currentFileNameId] = 0;
+
+ // DQ (12/19/2008): I think this should be true, but check it!
+ ROSE_ASSERT(previousLocatedNodeMap.size() == startIndexMap.size());
+
+ break;
+ }
+
+ // This case helps place the comment or directive relative
+ // to the closing brace of a SgBasicBlock.
+ case V_SgBasicBlock:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+
+ // The following should always work since each statement is a located node
+ SgBasicBlock* basicBlock = dynamic_cast<SgBasicBlock*>(n);
+#if 0
+ printf ("Case SgBasicBlock: lineOfClosingBrace = %d \n",lineOfClosingBrace);
+ printf ("Case SgBasicBlock: See if we can find a better target to attach these comments than %s \n",previousLocNodePtr->sage_class_name());
+#endif
+
+ // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( basicBlock, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index, currentListOfAttributes );
+
+ // DQ (4/9/2005): We need to point to the SgBasicBlock and not the last return statement (I think)
+ // Reset the previousLocNodePtr to the current node so that all
+ // PreprocessingInfo objects will be inserted relative to the
+ // current node next time.
+ // previousLocNodePtr = basicBlock;
+ previousLocatedNodeMap[currentFileNameId] = basicBlock;
+ break;
+ }
+
+ case V_SgClassDeclaration:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+
+ // The following should always work since each statement is a located node
+ SgClassDeclaration* classDeclaration = dynamic_cast<SgClassDeclaration*>(n);
+
+ // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index,currentListOfAttributes );
+ // printf ("Adding comment/directive to base of class declaration \n");
+ // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ // ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside );
+
+ // previousLocNodePtr = classDeclaration;
+ previousLocatedNodeMap[currentFileNameId] = classDeclaration;
+ break;
+ }
+
+ // GB (09/18/2007): Added support for preprocessing info inside typedef declarations (e.g. after the
+ // base type, which is what the previousLocNodePtr might point to).
+ case V_SgTypedefDeclaration:
+ {
+ ROSE_ASSERT(locatedNode->get_endOfConstruct() != NULL);
+
+ SgTypedefDeclaration *typedefDeclaration = isSgTypedefDeclaration(n);
+ ROSE_ASSERT(typedefDeclaration != NULL);
+
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index,currentListOfAttributes );
+
+ // previousLocNodePtr = typedefDeclaration;
+ previousLocatedNodeMap[currentFileNameId] = typedefDeclaration;
+ break;
+ }
+
+ // GB (09/19/2007): Added support for preprocessing info inside variable declarations (e.g. after the
+ // base type, which is what the previousLocNodePtr might point to).
+ case V_SgVariableDeclaration:
+ {
+ ROSE_ASSERT(locatedNode->get_endOfConstruct() != NULL);
+
+ SgVariableDeclaration *variableDeclaration = isSgVariableDeclaration(n);
+ ROSE_ASSERT(variableDeclaration != NULL);
+
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index,currentListOfAttributes );
+
+ // previousLocNodePtr = variableDeclaration;
+ previousLocatedNodeMap[currentFileNameId] = variableDeclaration;
+ break;
+ }
+
+ case V_SgClassDefinition:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+
+ // DQ (3/19/2005): This is a more robust process (although it introduces a new location for a comment/directive)
+ // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ // ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after );
+ // printf ("Adding comment/directive to base of class definition \n");
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index,currentListOfAttributes );
+
+ // previousLocNodePtr = locatedNode;
+ // previousLocatedNodeMap[currentFileNameId] = locatedNode;
+ break;
+ }
+
+ case V_SgEnumDeclaration:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+
+ // The following should always work since each statement is a located node
+ SgEnumDeclaration* enumDeclaration = dynamic_cast<SgEnumDeclaration*>(n);
+
+ // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
+ // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ // ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after );
+ // printf ("Adding comment/directive to base of enum declaration \n");
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index,currentListOfAttributes );
+
+ // previousLocNodePtr = enumDeclaration;
+ previousLocatedNodeMap[currentFileNameId] = enumDeclaration;
+ break;
+ }
+
+ // DQ (5/3/2004): Added support for namespaces
+ case V_SgNamespaceDeclarationStatement:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+
+ // The following should always work since each statement is a located node
+ SgNamespaceDeclarationStatement* namespaceDeclaration =
+ dynamic_cast<SgNamespaceDeclarationStatement*>(n);
+
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after, reset_start_index,currentListOfAttributes );
+
+ // previousLocNodePtr = namespaceDeclaration;
+ previousLocatedNodeMap[currentFileNameId] = namespaceDeclaration;
+ break;
+ }
+
+ // DQ (5/3/2004): Added support for namespaces
+ case V_SgNamespaceDefinitionStatement:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+
+ // The following should always work since each statement is a located node
+ SgNamespaceDefinitionStatement* namespaceDefinition =
+ dynamic_cast<SgNamespaceDefinitionStatement*>(n);
+
+ // DQ (3/18/2005): This is a more robust process (although it introduces a new location for a comment/directive)
+ // iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ // ( previousLocNodePtr, lineOfClosingBrace, PreprocessingInfo::after );
+ // printf ("Adding comment/directive to base of namespace definition \n");
+ bool reset_start_index = false;
+ iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( locatedNode, lineOfClosingBrace, PreprocessingInfo::inside, reset_start_index,currentListOfAttributes );
+
+ // previousLocNodePtr = namespaceDefinition;
+ previousLocatedNodeMap[currentFileNameId] = namespaceDefinition;
+ break;
+ }
+
+ // DQ (4/9/2005): Added support for templates instaiations which are compiler generated
+ // but OK to attach comments to them (just not inside them!).
+ case V_SgTemplateInstantiationMemberFunctionDecl:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+ // printf ("Found a SgTemplateInstantiationMemberFunctionDecl but only record it as a previousLocNodePtr \n");
+
+ // previousLocNodePtr = locatedNode;
+ previousLocatedNodeMap[currentFileNameId] = locatedNode;
+ }
+
+ // DQ (4/21/2005): this can be the last statement and if it is we have to
+ // record it as such so that directives/comments can be attached after it.
+ case V_SgTemplateInstantiationDirectiveStatement:
+ {
+ ROSE_ASSERT (locatedNode->get_endOfConstruct() != NULL);
+ // previousLocNodePtr = locatedNode;
+ previousLocatedNodeMap[currentFileNameId] = locatedNode;
+ }
+
+ default:
+ {
+#if 0
+ printf ("Skipping any possability of attaching a comment/directive after a %s \n",n->sage_class_name());
+ // ROSE_ASSERT(false);
+#endif
+ }
+ }
+ }
+
+#if 0
+ if (locatedNode != NULL)
+ {
+ printf ("Output attached comments: \n");
+ printOutComments(locatedNode);
+ }
+#endif
+ }
+
+ return returnSynthesizeAttribute;
+ }
+
Copied: branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.h (from rev 188, trunk/src/frontend/SageIII/attachPreprocessingInfoTraversal.h)
===================================================================
--- branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.h (rev 0)
+++ branches/imperial/src/frontend/SageIII/attachPreprocessingInfoTraversal.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,152 @@
+#ifndef _ATTACH_PREPROCESSING_INFO_TRAVERSAL_H_
+#define _ATTACH_PREPROCESSING_INFO_TRAVERSAL_H_
+
+// DQ (4/5/2006): Andreas has removed this code!
+
+// void printOutComments ( SgLocatedNode* locatedNode );
+
+// Need dummy classes and the actual tree traversal class
+// DQ: Renamed classes, can't have DI and DS polluting the global name space (potential for strange errors)
+// class DI : public SgInheritedAttribute {};
+// class DS : public SgSynthesizedAttribute {};
+
+// DQ (12/12/2008): This is the type use to hold all the CPP directives
+// and comments for each of many files.
+typedef std::map<int, ROSEAttributesList*> AttributeMapType;
+typedef std::map<int, int> StartingIndexAttributeMapType;
+typedef std::map<int, SgLocatedNode*> previousLocatedNodeInFileType;
+
+// DQ (11/29/2008): I don't think these are required to be derived from a special class any more!
+// class AttachPreprocessingInfoTreeTraversalInheritedAttrribute : public AstInheritedAttribute {};
+// class AttachPreprocessingInfoTreeTraversalSynthesizedAttribute : public AstSynthesizedAttribute {};
+class AttachPreprocessingInfoTreeTraversalInheritedAttrribute
+ {
+ // DQ (11/30/2008): I want to permit different list of directives and comments to be woven into the AST.
+ // Comments and directives from the original source file need to be inserted into the AST for C/C++/Fortran.
+ // However, for Fortran we also need to gather and insert the linemarker directives into the AST so that
+ // we can support an analysis of the AST that will mark where code has been included from for the case of
+ // Fortran using CPP directives (e.g. #include directives). To support this the mechanism for weaving
+ // the ROSEAttributesList has be be used twice (just for CPP Fortran code) and we need to use this
+ // weaving implementat with two different lists of directives. But moving the ROSEAttributesList
+ // into the inherited attribute we can set it differently for the two times we require it to be done.
+
+ public:
+ // DQ (12/12/2008): Make this a map to handle the attributes from more than one file (even if we
+ // only handle a single file, this added flexability is easier to support directly than to have
+ // an outer traversal vll an inner traversal). This more general interface supports the case
+ // where we save all comments and CPP directives used from include files in addition to the main
+ // source file.
+ // ROSEAttributesList* currentListOfAttributes;
+ // AttributeMapType* attributeMapForAllFiles;
+
+#if 0
+ // Constructor.
+ AttachPreprocessingInfoTreeTraversalInheritedAttrribute(ROSEAttributesList* listOfAttributes)
+ : currentListOfAttributes(listOfAttributes)
+ {
+ // Nothing else to do here.
+ }
+#else
+ // AttachPreprocessingInfoTreeTraversalInheritedAttrribute(AttributeMapType* attributeMap) : attributeMapForAllFiles(attributeMap)
+ AttachPreprocessingInfoTreeTraversalInheritedAttrribute()
+ {
+ // Nothing else to do here.
+ }
+#endif
+ };
+
+// This is an empty class, meaning that we could likely just have implemented a TopDownProcessing traversal.
+class AttachPreprocessingInfoTreeTraversalSynthesizedAttribute {};
+
+class AttachPreprocessingInfoTreeTrav
+ : public SgTopDownBottomUpProcessing<AttachPreprocessingInfoTreeTraversalInheritedAttrribute,
+ AttachPreprocessingInfoTreeTraversalSynthesizedAttribute>
+ {
+ protected: // Pi-- private:
+ //! accumulator attribute
+ // SgLocatedNode *previousLocNodePtr;
+
+ // Store the location in the AST of the previous node associated with each file.
+ previousLocatedNodeInFileType previousLocatedNodeMap;
+
+ // DQ (11/30/2008): This is now stored in the inherited attribute (so that it can be set external to the traversal).
+ // List of all comments and CPP directives
+ // ROSEAttributesList *currentListOfAttributes;
+ AttributeMapType attributeMapForAllFiles;
+
+ // DQ (12/12/2008): I don't think this is required since it is just the list size!
+ // size of list?
+ // int sizeOfCurrentListOfAttributes;
+
+ // DQ (12/12/2008): This allows buildCommentAndCppDirectiveList() to get information about what language
+ // and version of language (fixed or free format for Fortran) as required to gather CPP directives and
+ // comments (more for comments than for CPP directives). This is required even if processing other files
+ // (include files).
+ //! current source file name id (only handle strings from current file)
+ // int currentFileNameId;
+ SgSourceFile* sourceFile;
+
+ //! AS(011306) Map of ROSEAttributesLists mapped to filename from Wave
+ // DQ (12./12/2008): this should be updated to use int instead of strings.
+ // For now I will not touch the Wave specific implementation.
+ // std::map<std::string,ROSEAttributesList*>* currentMapOfAttributes;
+
+ //! AS(011306) Use_Wave == true specifies if a wave preprocessor is used
+ bool use_Wave;
+
+ //! AS(092107) Optimization variable to avoid n^2 complexity in
+ //! iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber()
+ // int start_index;
+ StartingIndexAttributeMapType startIndexMap;
+
+ // DQ (12/16/2008): Added support to collect CPP directives and comments from all
+ // include files (except should specified using exclusion lists via the command line).
+ bool processAllIncludeFiles;
+
+ public:
+ // DQ (9/24/2007): Moved function definition to source file from header file.
+ // AS(011306) Constructor for use of Wave Preprocessor
+ AttachPreprocessingInfoTreeTrav( std::map<std::string,ROSEAttributesList*>* attrMap);
+
+ public:
+
+ // DQ (9/24/2007): Moved function definition to source file from header file.
+ // Constructor
+ AttachPreprocessingInfoTreeTrav( SgSourceFile* file, bool includeDirectivesAndCommentsFromAllFiles );
+#if 0
+ AttachPreprocessingInfoTreeTrav();
+#endif
+ void setupPointerToPreviousNode (SgLocatedNode* currentLocNodePtr );
+
+ void iterateOverListAndInsertPreviouslyUninsertedElementsAppearingBeforeLineNumber
+ ( SgLocatedNode* locatedNode, int lineNumber, PreprocessingInfo::RelativePositionType location,
+ bool reset_start_index, ROSEAttributesList *currentListOfAttributes );
+
+ // Member function to be executed on each node of the AST
+ // in the course of its traversal
+ AttachPreprocessingInfoTreeTraversalInheritedAttrribute
+ evaluateInheritedAttribute( SgNode *n, AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh);
+
+ AttachPreprocessingInfoTreeTraversalSynthesizedAttribute
+ evaluateSynthesizedAttribute( SgNode *n, AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh, SubTreeSynthesizedAttributes st);
+
+ // DQ (10/27/2007): Added display function to output information gather durring the collection of
+ // comments and CPP directives across all files.
+ void display(const std::string & label) const;
+
+ AttributeMapType & get_attributeMapForAllFiles() { return attributeMapForAllFiles; }
+
+ // Access function for elements in the map of attribute lists.
+ ROSEAttributesList* getListOfAttributes ( int currentFileNameId );
+
+ // output for debugging.
+ // void display_static_data( const std::string & label ) const;
+
+ // DQ (11/30/2008): Refactored code to isolate this from the inherited attribute evaluation.
+ // static ROSEAttributesList* buildCommentAndCppDirectiveList ( SgFile *currentFilePtr, std::map<std::string,ROSEAttributesList*>* mapOfAttributes, bool use_Wave );
+ ROSEAttributesList* buildCommentAndCppDirectiveList ( bool use_Wave );
+ };
+
+#endif
+
+// EOF
Deleted: branches/imperial/src/frontend/SageIII/attach_all_info.C
===================================================================
--- branches/imperial/src/frontend/SageIII/attach_all_info.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/attach_all_info.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,681 +0,0 @@
-// #include "attach_all_info.h"
-#include "sage3.h"
-
-using namespace std;
-
-// extern ROSEAttributesList *getPreprocessorDirectives(const char *fileName);
-
-wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t::
-wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t(SgLocatedNode* node, ROSEAttributesList * preprocInfo,
- int len)
- : previousLocNodePtr(node), currentListOfAttributes(preprocInfo),
- sizeOfCurrentListOfAttributes(len)
-{
-}
-
-
-static const char* OPTION_PREFIX_ROSE = "-rose:";
-static const char* OPTION_VALUE_SEPARATOR = "$^";
-
-
-static const char* OPTION_EXCLUDEDIRECTIVES = "*excludeCommentsAndDirectives";
-static const char* OPTION_INCLUDEDIRECTIVES = "*includeCommentsAndDirectives";
-static const char* OPTION_EXCLUDEDIRECTIVESFILENAME = "*excludeCommentsAndDirectivesFrom";
-static const char* OPTION_INCLUDEDIRECTIVESFILENAME = "*includeCommentsAndDirectivesFrom";
-
-
-//Read all the words in a file into an vector of strings
-std::vector<std::string>
-readWordsInFile( std::string filename){
- std::vector<std::string> variantsToUse;
- std::fstream file_op(filename.c_str());
- if (file_op.fail()) {
- std::cout << "error: could not find file \"" << filename
- << "\" which is meant to include the styles to enforce with "
- << "the name checker." << std::endl;
- exit(1); // abort program
-
- }
-
- std::string current_word;
-
- while(file_op >> current_word){
- //First word denotes what the regular expression should operate
- //upon. Second word denotes the regular expression
- variantsToUse.push_back(current_word);
- }
-
- return variantsToUse;
-}
-
-//! Wrapper around the SLA string option processing routine.
-int
-getRoseOptionValuesFromCommandline (vector<string>& argv, const string& opt_name,
- std::vector<std::string>& values)
- {
- int num_matches = sla_str (argv,
- OPTION_PREFIX_ROSE,
- OPTION_VALUE_SEPARATOR,
- opt_name,
- (std::string *)NULL);
- if (num_matches > 0)
- {
- vector<string> raw_values(num_matches);
- sla_str (argv,
-OPTION_PREFIX_ROSE, OPTION_VALUE_SEPARATOR, opt_name,
- &raw_values[0]);
- values.insert(values.end(), raw_values.begin(), raw_values.end());
- }
- return num_matches;
- }
-
-
-
-
-AttachAllPreprocessingInfoTreeTrav::
-AttachAllPreprocessingInfoTreeTrav(SgFile * sagep)
- : AttachPreprocessingInfoTreeTrav(),
- sage_file(sagep),
- map_of_all_attributes(),
- nFiles(0),
- map_of_file_order(),
- array_of_first_nodes(16, (SgNode*)NULL),
- dependancies(cin)
- {
- lookForExcludePaths = false;
- lookForIncludePaths = false;
- start_index = 0;
- src_file_name = sage_file->getFileName();
-
- // AS(093007) Find the commandline options to include and/or exclude paths
-
- vector<string> argv = sage_file->get_originalCommandLineArgumentList();
-
- std::vector<std::string> raw_conf_filename;
-
- printf ("AttachAllPreprocessingInfoTreeTrav constructor: This code is now redundant with the include/exclude support for paths and filename in SgProject \n");
-
- // Read option to exclude directives
- getRoseOptionValuesFromCommandline (argv, OPTION_EXCLUDEDIRECTIVES, raw_conf_filename);
-
- if ( raw_conf_filename.size() >= 1 )
- {
- ROSE_ASSERT( raw_conf_filename.size() >= 1);
- lookForExcludePaths = true;
-
- for( unsigned int i = 0 ; i < raw_conf_filename.size() ; i++ )
- {
- pathsToExclude.push_back(raw_conf_filename[i]);
- }
- }
-
- // Read option to include directives
- raw_conf_filename.clear();
- getRoseOptionValuesFromCommandline (argv, OPTION_INCLUDEDIRECTIVES, raw_conf_filename);
-
- if ( raw_conf_filename.size() >= 1 )
- {
- ROSE_ASSERT( raw_conf_filename.size() >= 1);
- lookForIncludePaths = true;
-
- for( unsigned int i = 0 ; i < raw_conf_filename.size() ; i++ )
- {
- pathsToInclude.push_back(raw_conf_filename[i]);
- }
- }
-
- // Read option to include directives from filename
- raw_conf_filename.clear();
- getRoseOptionValuesFromCommandline (argv, OPTION_INCLUDEDIRECTIVESFILENAME, raw_conf_filename);
-
- if ( raw_conf_filename.size() >= 1 )
- {
- ROSE_ASSERT( raw_conf_filename.size() >= 1);
- lookForIncludePaths = true;
-
- std::vector<std::string> wordsInFile;
- for( unsigned int i = 0 ; i < raw_conf_filename.size() ; i++ )
- {
- wordsInFile = readWordsInFile(raw_conf_filename[i]);
- for( unsigned int j = 0 ; j < wordsInFile.size() ; j++ )
- pathsToInclude.push_back(wordsInFile[j]);
- }
- }
-
- // Read option to exclude directives from filename
- raw_conf_filename.clear();
- getRoseOptionValuesFromCommandline (argv, OPTION_EXCLUDEDIRECTIVESFILENAME, raw_conf_filename);
-
- if ( raw_conf_filename.size() >= 1 )
- {
- ROSE_ASSERT( raw_conf_filename.size() == 1);
-
- lookForExcludePaths = true;
- std::vector<std::string> wordsInFile;
- for( unsigned int i = 0 ; i < raw_conf_filename.size() ; i++ )
- {
- wordsInFile = readWordsInFile(raw_conf_filename[i]);
- for( unsigned int j = 0 ; j < wordsInFile.size() ; j++ )
- pathsToExclude.push_back(wordsInFile[j]);
- }
- }
- }
-
-
-AttachPreprocessingInfoTreeTraversalInheritedAttrribute
-AttachAllPreprocessingInfoTreeTrav::evaluateInheritedAttribute ( SgNode *n, AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh)
- {
- wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t save_data;
-
- SgFile *currentFilePtr = dynamic_cast<SgFile*>(n);
- SgLocatedNode *currentLocNodePtr = dynamic_cast<SgLocatedNode*>(n);
- int file_name_id = -1;
- Sg_File_Info * file_info_ptr = NULL;
- bool isCompilerGenerated = false;
- bool isTransformation = false;
-
- if ( ( currentFilePtr == NULL ) && ( currentLocNodePtr == NULL ) )
- return inh;
-
- // get a valid file name, and check if it is a new file; if yes, get
- // all the comments and store the list into map. Then set save_data
- // to prepare for the parent function.
-
- // 1. find the file name for the current node:
- if ( currentFilePtr!=NULL )
- {
- file_name_id = currentFilePtr->get_file_info()->get_file_id();
- }
- else
- {
- if ( currentLocNodePtr!=NULL )
- {
- file_info_ptr = currentLocNodePtr->get_file_info();
- assert ( file_info_ptr!=NULL );
-
- // Pi: compiler generated nodes have no real file names with them,
- // so use the currentFileName as their names:
- isCompilerGenerated = file_info_ptr->isCompilerGenerated();
- // isCompilerGenerated = file_info_ptr->isCompilerGeneratedNodeToBeUnparsed();
- isTransformation = file_info_ptr->isTransformation();
- if ( isCompilerGenerated == true || isTransformation == true )
- {
- file_name_id = currentFileNameId;
- }
- else
- {
- file_name_id = file_info_ptr->get_file_id();
- }
- }
- }
-
- // 2. check whether the file name is new:
- // AS(09/21/07) Reset start_index since we are dealing with a new file
- start_index = 0;
-
- map<int, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t>::iterator attr_list_itr = map_of_all_attributes.find(file_name_id);
-
- // If the name is not in the map then ... it is a new file and we have to process it
- if ( attr_list_itr == map_of_all_attributes.end() )
- {
-#ifdef outputallfilenamefound
- cerr << "-->>> NEW file : " << file_name_str << endl;
-#endif
- save_data.previousLocNodePtr = previousLocNodePtr;
-
- // AS(092907) Only collect the filenames we are interested in
- // AS(093007) Logic to include or exclude finding comments in paths
- bool includePath = true;
-
- std::string file_name_str = Sg_File_Info::getFilenameFromID(file_name_id);
-
- // If the command line directive to look for include paths has been
- // specified. See if the current filename is in the list of
- // included paths.
- if( lookForIncludePaths == true )
- {
- includePath = false;
- for (std::vector<std::string>::iterator iItr = pathsToInclude.begin(); iItr != pathsToInclude.end(); ++iItr)
- {
- if ( file_name_str.find(*iItr) != string::npos )
- {
- includePath = true;
- break;
- }
- }
- }
-
- bool excludePath = false;
-
- // If the command line directive to look for exclude paths has been
- // specified. See if the current filename is in the list of
- // excluded paths.
- if ( lookForExcludePaths == true )
- {
- for (std::vector<std::string>::iterator iItr = pathsToExclude.begin(); iItr != pathsToExclude.end(); ++iItr)
- {
- if ( file_name_str.find(*iItr) != string::npos )
- {
- excludePath = true;
- break;
- }
- }
- }
-
- if ( (excludePath == false) && (includePath == true) )
- {
- // This scans the file and collects the token stream...
- printf ("AttachAllPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): Calling getPreprocessorDirectives for file = %s \n",file_name_str.c_str());
- save_data.currentListOfAttributes = getPreprocessorDirectives(file_name_str);
- }
- else
- {
- // This builds an empty list; does not traverse the file
- printf ("AttachAllPreprocessingInfoTreeTrav::evaluateInheritedAttribute(): Building an empty list to represent the data from file = %s \n",file_name_str.c_str());
- save_data.currentListOfAttributes = new ROSEAttributesList();
- }
-
- save_data.sizeOfCurrentListOfAttributes = save_data.currentListOfAttributes->getLength();
- map_of_all_attributes[file_name_id] = save_data;
-
- }
- else
- {
- save_data = (*attr_list_itr).second;
- }
-
- // 3. set data used by the parent before calling it:
- currentFileNameId = file_name_id;
- previousLocNodePtr = save_data.previousLocNodePtr;
- currentListOfAttributes = save_data.currentListOfAttributes;
- sizeOfCurrentListOfAttributes = save_data.sizeOfCurrentListOfAttributes;
-
- // 4. call the parent and record changes to the data used:
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh_rsl = AttachPreprocessingInfoTreeTrav::evaluateInheritedAttribute(n, inh);
- save_data.previousLocNodePtr = previousLocNodePtr;
- save_data.currentListOfAttributes = currentListOfAttributes;
- save_data.sizeOfCurrentListOfAttributes = sizeOfCurrentListOfAttributes;
- map_of_all_attributes[currentFileNameId] = save_data;
-
- // 5. set the first attachable node for each file to make it simple
- // 5. to attach rest preproc info (the special case when a file
- // 5. contains no IR nodes): such info is attached to the first node
- // 5. of the next file.
- if ( dynamic_cast<SgStatement*>(n) != NULL )
- {
- // Nodes that should not have comments attached (since they are not unparsed)
- // Conditions obtained from src/ROSETTA/Grammar/LocatedNode.code:251
- switch ( n->variantT() )
- {
- case V_SgForInitStatement:
- case V_SgTypedefSeq:
- case V_SgCatchStatementSeq:
- case V_SgFunctionParameterList:
- case V_SgCtorInitializerList:
- goto return_inh;
-
- default:
- {
- // 5. if the first node for a file doesn't exist, then add it; otherwise do nothing:
- map<int, int>::iterator first_node_itr = map_of_file_order.find(currentFileNameId);
- if ( first_node_itr == map_of_file_order.end() )
- {
- map_of_file_order[currentFileNameId] = nFiles;
- add_first_node_for_file(currentFileNameId, n, nFiles);
- nFiles++;
- }
- break;
- }
- }
- }
-
- // The inh/inh_rsl is no use for now.
- return_inh:
-
- return inh_rsl;
- }
-
-AttachPreprocessingInfoTreeTraversalSynthesizedAttribute
-AttachAllPreprocessingInfoTreeTrav::
-evaluateSynthesizedAttribute ( SgNode *n,
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh,
- SubTreeSynthesizedAttributes st)
-{
- wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t save_data;
-
- SgFile *currentFilePtr = dynamic_cast<SgFile*>(n);
- SgLocatedNode *currentLocNodePtr = dynamic_cast<SgLocatedNode*>(n);
- int file_name_id = -1;
- Sg_File_Info * file_info_ptr = NULL;
- bool isCompilerGenerated = false;
- bool isTransformation = false;
-
- if( ( currentFilePtr != NULL ) || ( currentLocNodePtr != NULL ) )
- {
-
-
- // get a valid file name, and check if it is a new file; if yes, get
- // all the comments and store the list into map. Then set save_data
- // to prepare for the parent function.
-
- // 1. find the file name for the current node:
- if ( currentFilePtr!=NULL ) {
- file_name_id = currentFilePtr->get_file_info()->get_file_id();
- } else if ( currentLocNodePtr!=NULL ) {
- file_info_ptr = currentLocNodePtr->get_file_info();
- assert ( file_info_ptr!=NULL );
-
- // Pi: compiler generated nodes have no real file names with them,
- // so use the currentFileName as their names:
- isCompilerGenerated = file_info_ptr->isCompilerGenerated();
-// isCompilerGenerated = file_info_ptr->isCompilerGeneratedNodeToBeUnparsed();
- isTransformation = file_info_ptr->isTransformation();
- if ( isCompilerGenerated==true || isTransformation==true ) {
- file_name_id = currentFileNameId;
- } else {
- file_name_id = file_info_ptr->get_file_id();
- }
- }
-
- // 2. check whether the file name is new:
- //AS(09/21/07) Reset start_index since we are dealing with a new file
- start_index = 0;
-
- map<int, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t>::iterator attr_list_itr
- = map_of_all_attributes.find(file_name_id);
- if ( attr_list_itr==map_of_all_attributes.end() ) {
-#ifdef outputallfilenamefound
- cerr << "-->>> NEW file : " << file_name_str << endl;
-#endif
- save_data.previousLocNodePtr = previousLocNodePtr;
-
- //AS(093007) Logic to include or exclude finding comments in paths
- bool includePath = true;
- std::string file_name_str = Sg_File_Info::getFilenameFromID(file_name_id);
-
- //If the command line directive to look for include paths has been
- //specified. See if the current filename is in the list of
- //included paths.
- if( lookForIncludePaths == true )
- {
- includePath = false;
- for(std::vector<std::string>::iterator iItr = pathsToInclude.begin();
- iItr != pathsToInclude.end(); ++iItr)
- {
- if( file_name_str.find(*iItr) != string::npos ){
- includePath = true;
- break;
- }
- }
- }
-
- bool excludePath = false;
-
- //If the command line directive to look for exclude paths has been
- //specified. See if the current filename is in the list of
- //excluded paths.
- if( lookForExcludePaths == true )
- {
- for(std::vector<std::string>::iterator iItr = pathsToExclude.begin();
- iItr != pathsToExclude.end(); ++iItr)
- {
- if( file_name_str.find(*iItr) != string::npos ){
- excludePath = true;
- break;
- }
- }
- }
-
-
- if( (excludePath == false) && (includePath == true) )
- save_data.currentListOfAttributes = getPreprocessorDirectives(file_name_str);
- else
- save_data.currentListOfAttributes = new ROSEAttributesList;
-
- save_data.sizeOfCurrentListOfAttributes = save_data.currentListOfAttributes->getLength();
- map_of_all_attributes[file_name_id] = save_data;
- } else {
- save_data = (*attr_list_itr).second;
- }
-
- // 3. set data used by the parent before calling it:
- currentFileNameId = file_name_id;
- previousLocNodePtr = save_data.previousLocNodePtr;
- currentListOfAttributes = save_data.currentListOfAttributes;
- sizeOfCurrentListOfAttributes = save_data.sizeOfCurrentListOfAttributes;
-
- }
-
- AttachPreprocessingInfoTreeTraversalSynthesizedAttribute syn;
-
- if( ( currentFilePtr != NULL ) || ( currentLocNodePtr != NULL ) )
- {
-
- syn
- = AttachPreprocessingInfoTreeTrav::evaluateSynthesizedAttribute(n, inh, st);
- save_data.previousLocNodePtr = previousLocNodePtr;
- save_data.currentListOfAttributes = currentListOfAttributes;
- save_data.sizeOfCurrentListOfAttributes = sizeOfCurrentListOfAttributes;
- map_of_all_attributes[currentFileNameId] = save_data;
- }
-
- // The inh/st/syn is no use for now.
- // return_syn:
- return syn;
-}
-
-bool AttachAllPreprocessingInfoTreeTrav::
-add_first_node_for_file(const int fn, SgNode* n, int pos)
-{
- bool flag = false;
-
- int totalfiles = array_of_first_nodes.size();
- if ( pos >= totalfiles ) {
- array_of_first_nodes.resize(2*totalfiles, NULL);
- }
-
- if ( array_of_first_nodes[pos]==NULL ) {
- flag = true;
- array_of_first_nodes[pos] = n;
- }
-
- return flag;
-}
-
-pair<SgNode*, PreprocessingInfo::RelativePositionType> AttachAllPreprocessingInfoTreeTrav::
-get_first_node_for_file(const int fn, int hintfororder)
-{
- map<int, int>::iterator first_node_itr = map_of_file_order.find(fn);
- int pos_itr = hintfororder;
- PreprocessingInfo::RelativePositionType loc = PreprocessingInfo::before;
- if ( first_node_itr!=map_of_file_order.end() )
- pos_itr = (*first_node_itr).second;
-
- for (int i=pos_itr; i<nFiles; i++ ) {
- if ( array_of_first_nodes[i]!=NULL )
- return pair<SgNode*, PreprocessingInfo::RelativePositionType>(array_of_first_nodes[i], loc);
- }
-
- loc = PreprocessingInfo::after;
- for (int i=pos_itr-1; i>=0; i-- ) {
- if ( array_of_first_nodes[i]!=NULL )
- return pair<SgNode*, PreprocessingInfo::RelativePositionType>(array_of_first_nodes[i], loc);
- }
-
- loc = PreprocessingInfo::defaultValue;
- return pair<SgNode*, PreprocessingInfo::RelativePositionType>(NULL, loc);
-}
-
-#if 0
-bool AttachAllPreprocessingInfoTreeTrav::
-attach_left_info()
-{
- int lenoffilelist = 0;
- int nleftfiles = 0;
-
- while ( !dependancies.eof() ) {
- string fn;
- dependancies >> fn;
- if ( fn!="" ) {
- map<string, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t>::iterator attr_list_itr = map_of_all_attributes.find(fn);
- lenoffilelist++;
-
- if ( attr_list_itr==map_of_all_attributes.end() ) {
- // handle files containing no IR nodes
- nleftfiles++;
-
- //AS(093007) Logic to include or exclude finding comments in paths
- bool includePath = true;
-
- //If the command line directive to look for include paths has been
- //specified. See if the current filename is in the list of
- //included paths.
- if( lookForIncludePaths == true )
- {
- includePath = false;
- for(std::vector<std::string>::iterator iItr = pathsToInclude.begin();
- iItr != pathsToInclude.end(); ++iItr)
- {
- if( fn.find(*iItr) != string::npos ){
- includePath = true;
- break;
- }
- }
- }
-
- bool excludePath = false;
-
- //If the command line directive to look for exclude paths has been
- //specified. See if the current filename is in the list of
- //excluded paths.
- if( lookForExcludePaths == true )
- {
- for(std::vector<std::string>::iterator iItr = pathsToExclude.begin();
- iItr != pathsToExclude.end(); ++iItr)
- {
- if( fn.find(*iItr) != string::npos ){
- excludePath = true;
- break;
- }
- }
- }
-
-
- ROSEAttributesList* cur_attr_list;
- if( (excludePath == false) && (includePath == true) )
- cur_attr_list = getPreprocessorDirectives(fn);
- else
- cur_attr_list = new ROSEAttributesList;
-
- pair<SgNode*, PreprocessingInfo::RelativePositionType> first_node = get_first_node_for_file(fn, lenoffilelist-nleftfiles);
- cerr << "Hint for attaching : " << lenoffilelist-nleftfiles << endl;
- for ( int i=0; i<cur_attr_list->getLength(); i++ ) {
- PreprocessingInfo * curPreInfo = (*cur_attr_list)[i];
-
- if ( curPreInfo!=NULL ) {
- if ( first_node.first==NULL )
- cerr << "Warning: No node is found for attaching preproc info `" << curPreInfo->getString() << "'" << endl;
- else {
- cur_attr_list->getList()[i] = NULL;
- curPreInfo->setRelativePosition(first_node.second);
- dynamic_cast<SgLocatedNode*>(first_node.first)->addToAttachedPreprocessingInfo(curPreInfo);
- }
- } // end if curPreInfo is not already attached.
- } // end for all attr in current attr_list_itr
- } // end for all lists of attr
- } // end if a file name
- } // end while all files
-
- return true;
-}
-#endif
-
-#if 0
-// DQ (4/19/2006): This is now called from the attachPreprocessingInfo function directly!
-void
-attachAllPreprocessingInfo(SgFile* sagep)
-{
- TimingPerformance timer ("Attaching AST Processing Info:");
-
- // Dummy attribute
- AttachPreprocessingInfoTreeTraversalInheritedAttrribute inh;
-
- // Make sure that the argument is not a NULL pointer
- ROSE_ASSERT(sagep);
-
- // Create tree traversal object for attaching the preprocessing information
- AttachAllPreprocessingInfoTreeTrav tt(sagep);
-
- // Run tree traversal on specified source file
- tt.traverse(sagep, inh);
-
-// DQ (3/30/2006): Commented this out with help from Lingxiao.
-// This gets the list of header files using EDG's -M (--dependencies) option.
-// This list is provided in order so that header files without IR nodes
-// have have their comments and CPP directive processed for inclusion into
-// the AST (important if such a header file included "#if 0" only, for example).
-// tt.attach_left_info();
-#if PRINT_DEVELOPER_WARNINGS
- printf ("Skipping possible header files that contain no IR nodes (the comments and CPP directives in them will not be extracted) \n");
-#endif
-}
-#endif
-
-
-
-// DQ (10/27/2007): Added display function to output information gather durring the collection of
-// comments and CPP directives across all files.
-void
-AttachAllPreprocessingInfoTreeTrav::display(const std::string & label) const
- {
- // Output internal information
-
- printf ("Inside of AttachAllPreprocessingInfoTreeTrav::display(%s) \n",label.c_str());
-
-#if 0
- std::string src_file_name;
- SgFile * sage_file;
- /* map: key = filename, value = a wrapper for the data used in AttachPreprocessingInfoTreeTrav. */
- std::map<int, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t> map_of_all_attributes;
- /* map: key = filename, value = the first node in AST from the file (could be NULL) */
- /* std::map<std::string, SgNode*> map_of_first_node; */
- /* I need to keep the order for each file when it is discovered from AST */
- int nFiles; /* total number of files involved */
- std::map<int, int> map_of_file_order;
- std::vector<SgNode*> array_of_first_nodes;
-
- // Holds paths to exclude when getting all commments and directives
- std::vector<std::string> pathsToExclude;
- bool lookForExcludePaths;
-
- // Holds paths to include when getting all comments and directives
- std::vector<std::string> pathsToInclude;
- bool lookForIncludePaths;
-#endif
-
- printf ("src_file_name = %s \n",src_file_name.c_str());
- printf ("sage_file = %p = %s \n",sage_file,sage_file->getFileName().c_str());
- printf ("Number of files (nFiles) = %d \n",nFiles);
- printf ("lookForExcludePaths = %s \n",lookForExcludePaths ? "true" : "false");
- printf ("lookForIncludePaths = %s \n",lookForIncludePaths ? "true" : "false");
-
- std::map<int, wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t>::const_iterator i = map_of_all_attributes.begin();
- while (i != map_of_all_attributes.end())
- {
- int file_id = i->first;
- SgLocatedNode *previousLocNodePtr = i->second.previousLocNodePtr;
- ROSEAttributesList *currentListOfAttributes = i->second.currentListOfAttributes;
- int sizeOfCurrentListOfAttributes = i->second.sizeOfCurrentListOfAttributes;
-
- printf (" file_id = %d \n",file_id);
- printf (" previousLocNodePtr = %p \n",previousLocNodePtr);
- printf (" currentListOfAttributes = %p \n",currentListOfAttributes);
- printf (" sizeOfCurrentListOfAttributes = %d \n",sizeOfCurrentListOfAttributes);
-
- i++;
- }
-#if 0
- AttachPreprocessingInfoTreeTrav::display("Called from processing ALL comments and directives");
-#endif
- }
-
Modified: branches/imperial/src/frontend/SageIII/attach_all_info.h
===================================================================
--- branches/imperial/src/frontend/SageIII/attach_all_info.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/attach_all_info.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,14 +1,29 @@
#ifndef _ATTACH_ALL_INFO_H_
#define _ATTACH_ALL_INFO_H_
-struct wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t {
- SgLocatedNode *previousLocNodePtr;
- ROSEAttributesList *currentListOfAttributes;
- int sizeOfCurrentListOfAttributes;
+#if 0
+struct wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t
+ {
+ SgLocatedNode *previousLocNodePtr;
+#if 0
+ // DQ (11/30/2008): Moved currentListOfAttributes to inherited attribute
+ ROSEAttributesList *currentListOfAttributes;
+ int sizeOfCurrentListOfAttributes;
+#endif
+ // wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t(SgLocatedNode* node=NULL, ROSEAttributesList* preprocInfo=NULL, int len=0);
+ wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t(SgLocatedNode* node=NULL);
+ };
+#else
+// DQ (12/3/2008): This is the data that we have to save (even though the currentListOfAttributes has been moved to the inherited attribute)
+struct wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t
+ {
+ SgLocatedNode *previousLocNodePtr;
+ ROSEAttributesList *currentListOfAttributes;
+ int sizeOfCurrentListOfAttributes;
+ wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t(SgLocatedNode* node=NULL, ROSEAttributesList* preprocInfo=NULL, int len=0);
+ };
+#endif
- wrap_data_used_by_AttachPreprocessingInfoTreeTrav_t(SgLocatedNode* node=NULL, ROSEAttributesList * preprocInfo=NULL, int len=0);
-};
-
class AttachAllPreprocessingInfoTreeTrav : public AttachPreprocessingInfoTreeTrav
{
private:
Modified: branches/imperial/src/frontend/SageIII/attributeListMap.h
===================================================================
--- branches/imperial/src/frontend/SageIII/attributeListMap.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/attributeListMap.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -4,8 +4,8 @@
#define DEBUG_WAVE_ROSE_CONNECTION 1
#define DEBUG_USE_ROSE_BOOST_WAVE_SUPPORT 1
-
-#include <map>
+// DQ (11/30/2008): This will be defined within the header file system for ROSE.
+// #include <map>
// Header files needed for ROSE
#include "rose.h"
@@ -19,10 +19,9 @@
#include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class
#include <boost/wave/cpplexer/cpp_lex_iterator.hpp> // lexer class
-class AttributeListMap;
+// DQ: I don't think this forward declaration is required...
+// class AttributeListMap;
-
-
////////////////////////////////////////////////////////////////////////
// Function queryFloatDoubleValExp() finds all nodes with type
// SgDoubleVal, SgLongDoubleVal or SgFloatVal
@@ -34,8 +33,6 @@
//class advanced_preprocessing_hooks;
//#include "advanced_preprocessing_hooks.hpp"
-// using namespace std;
-
class AttributeListMap {
private:
Modified: branches/imperial/src/frontend/SageIII/dwarfSupport.C
===================================================================
--- branches/imperial/src/frontend/SageIII/dwarfSupport.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/dwarfSupport.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -2598,18 +2598,18 @@
elfSegmentTableEntry->addNewAttribute("SymbolPruningAttribute",att);
}
- SgAsmElfRelaEntry* elfRelaEntry = isSgAsmElfRelaEntry(node);
- if (elfRelaEntry != NULL)
+ SgAsmElfRelocEntry* elfRelocEntry = isSgAsmElfRelocEntry(node);
+ if (elfRelocEntry != NULL)
{
SymbolPruningAttribute* att = new SymbolPruningAttribute();
- elfRelaEntry->addNewAttribute("SymbolPruningAttribute",att);
+ elfRelocEntry->addNewAttribute("SymbolPruningAttribute",att);
}
- SgAsmElfRelaEntryList* elfRelaEntryList = isSgAsmElfRelaEntryList(node);
- if (elfRelaEntryList != NULL)
+ SgAsmElfRelocEntryList* elfRelocEntryList = isSgAsmElfRelocEntryList(node);
+ if (elfRelocEntryList != NULL)
{
SymbolPruningAttribute* att = new SymbolPruningAttribute();
- elfRelaEntryList->addNewAttribute("SymbolPruningAttribute",att);
+ elfRelocEntryList->addNewAttribute("SymbolPruningAttribute",att);
}
SgAsmElfDynamicEntryList* elfDynamicEntryList = isSgAsmElfDynamicEntryList(node);
Modified: branches/imperial/src/frontend/SageIII/rose_attributes_list.C
===================================================================
--- branches/imperial/src/frontend/SageIII/rose_attributes_list.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/rose_attributes_list.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -10,10 +10,13 @@
///////////////////////////////////////////////////////////////////////////////
// Include the token class from Wave
///////////////////////////////////////////////////////////////////////////////
+
+
// Include Wave itself
#include <boost/wave.hpp>
-//#include <boost/wave/grammars/cpp_xpression_grammar.hpp> //as_string
+// #include <boost/wave/grammars/cpp_xpression_grammar.hpp> //as_string
+
#endif
@@ -643,11 +646,10 @@
break;
// DQ (11/17/2008): Added support for things like: # 1 "<command line>"
- case CpreprocessorCompilerGenerateLineDeclaration:
- returnString = "CpreprocessorCompilerGenerateLineDeclaration";
+ case CpreprocessorCompilerGeneratedLinemarker:
+ returnString = "CpreprocessorCompilerGeneratedLinemarker";
break;
-
default:
returnString = "ERROR DEFAULT REACHED";
printf ("Default reached in PreprocessingInfo::directiveTypeName() exiting ... (directive = %d) \n",directive);
@@ -799,7 +801,7 @@
return file_info;
}
- void
+void
PreprocessingInfo::set_file_info( Sg_File_Info* info )
{
ROSE_ASSERT(this != NULL);
@@ -808,9 +810,45 @@
ROSE_ASSERT(file_info != NULL);
}
+// DQ (11/28/2008): Support for CPP generated linemarkers
+int
+PreprocessingInfo::get_lineNumberForCompilerGeneratedLinemarker()
+ {
+ return lineNumberForCompilerGeneratedLinemarker;
+ }
+std::string
+PreprocessingInfo::get_filenameForCompilerGeneratedLinemarker()
+ {
+ return filenameForCompilerGeneratedLinemarker;
+ }
+std::string
+PreprocessingInfo::get_optionalflagsForCompilerGeneratedLinemarker()
+ {
+ return optionalflagsForCompilerGeneratedLinemarker;
+ }
+// DQ (11/28/2008): Support for CPP generated linemarkers
+void
+PreprocessingInfo::set_lineNumberForCompilerGeneratedLinemarker( int x )
+ {
+ lineNumberForCompilerGeneratedLinemarker = x;
+ }
+
+void
+PreprocessingInfo::set_filenameForCompilerGeneratedLinemarker( std::string x )
+ {
+ filenameForCompilerGeneratedLinemarker = x;
+ }
+
+void
+PreprocessingInfo::set_optionalflagsForCompilerGeneratedLinemarker( std::string x )
+ {
+ optionalflagsForCompilerGeneratedLinemarker = x;
+ }
+
+
// *********************************************
// Member functions for class ROSEATTRIBUTESList
// *********************************************
@@ -1049,8 +1087,14 @@
for (j = attributeList.begin(); j != attributeList.end(); j++)
{
// printf(" %s\n",( (*j)->stringPointer );
- ROSE_ASSERT ( (*j) != NULL );
- printf("LineNumber: %5d: %s\n",(*j)->getLineNumber(),(*j)->getString().c_str());
+
+ // DQ (12/19/2008): Modified to report NULL pointers
+ // ROSE_ASSERT ( (*j) != NULL );
+ // printf("LineNumber: %5d: %s\n",(*j)->getLineNumber(),(*j)->getString().c_str());
+ if ( *j != NULL )
+ printf("LineNumber: %5d: %s\n",(*j)->getLineNumber(),(*j)->getString().c_str());
+ else
+ printf ("Warning: PreprocessingInfo *j == NULL \n");
}
}
@@ -1293,6 +1337,7 @@
return isComment;
}
+#if 0
void
ROSEAttributesList::collectFixedFormatPreprocessorDirectivesAndCommentsForAST( const string & filename )
{
@@ -1305,6 +1350,8 @@
ROSE_ASSERT(this != NULL);
+#error "DEAD CODE"
+
printf ("This is an old version of the function to collect CPP directives and comments \n");
ROSE_ASSERT(false);
@@ -1315,6 +1362,8 @@
// printf ("In ROSEAttributesList::collectFixedFormatPreprocessorDirectivesAndCommentsForAST: Opening file %s for reading comments and CPP directives \n",filename.c_str());
+#error "DEAD CODE"
+
ifstream fixedFormatFile (filename.c_str());
if (fixedFormatFile.is_open())
{
@@ -1334,6 +1383,8 @@
// PreprocessingInfo(DirectiveType, const std::string & inputString, const std::string & filenameString,
// int line_no , int col_no, int nol, RelativePositionType relPos, bool copiedFlag, bool unparsedFlag);
+#error "DEAD CODE"
+
int numberOfLines = 1;
// bool copiedFlag = false;
// bool unparsedFlag = false;
@@ -1348,6 +1399,8 @@
lineCounter++;
}
+#error "DEAD CODE"
+
fixedFormatFile.close();
}
else
@@ -1356,12 +1409,12 @@
ROSE_ASSERT(false);
}
}
+#endif
-
#define DEBUG_CPP_DIRECTIVE_COLLECTION 0
bool
-ROSEAttributesList::isCppDirective( const string & line, PreprocessingInfo::DirectiveType & cppDeclarationKind )
+ROSEAttributesList::isCppDirective( const string & line, PreprocessingInfo::DirectiveType & cppDeclarationKind, std::string & restOfTheLine )
{
// This function tests if a string is a CPP directive (the first line of a CPP directive).
@@ -1414,7 +1467,10 @@
// firstNonBlankCharacter = ' ';
// printf ("firstNonBlankCharacter = %c \n",firstNonBlankCharacter);
bool spaceAfterHash = false;
- while (i < lineLength && firstNonBlankCharacter == ' ' || firstNonBlankCharacter == '#')
+
+ // DQ (12/16/2008): Added support fo tabs between "#" and the directive identifier.
+ // Note that Fortran modes of CPP should not allow any whitespace here (at least for gfortran).
+ while (i < lineLength && (firstNonBlankCharacter == ' ' || firstNonBlankCharacter == '\t') || firstNonBlankCharacter == '#')
{
#if DEBUG_CPP_DIRECTIVE_COLLECTION
printf ("Looping over # or white space between # and CPP directive i = %d \n",i);
@@ -1463,6 +1519,8 @@
long integerValue = -1;
if (spaceAfterHash == true)
{
+ // This is likely going to be a number but test2005_92.C demonstrates a case where this is not true.
+
// printf ("firstNonBlankCharacter = %c \n",firstNonBlankCharacter);
// ROSE_ASSERT(firstNonBlankCharacter == '\"');
#if 0
@@ -1472,13 +1530,56 @@
// The modern way to handle conversion of string to integer value is to
// use strtol(), and not atoi(). But atoi() is simpler.
const char* str = cppIndentifier.c_str();
+ int size = strlen(str)+1;
+ char* buffer = new char[size];
+ // Make a copy of the pointer so that we can always delete the memory that was allocated.
+ char* original_buffer = buffer;
+
+ // We should initialize "buffer" to all Nul chars (this includes a null terminator and the end of the string).
+ for (int j=0; j < size; j++)
+ buffer[j] = '\0';
+
// strtol will put the string into buffer if str is not a number and 2nd parameter is not NULL.
- integerValue = strtol(str,NULL,10);
+ errno = 0;
+ // integerValue = strtol(str,NULL,10);
+ integerValue = strtol(str,&buffer,10);
+ // Setting and checking errno does not appear to work for the detection of errors in the use of strtol
+ if (errno != 0)
+ {
+ printf ("Using errno: This was not a valid string (errno = %d returned) \n",errno);
+ }
+
+ bool isANumber = true;
+ if (strcmp(str,buffer) == 0)
+ {
+ printf ("Using strcmp(): This was not a valid string (buffer = %s returned) \n",buffer);
+ isANumber = false;
+ }
+ // printf ("cppIndentifier = %s integerValue = %ld \n",cppIndentifier.c_str(),integerValue);
+#if 1
+ // Avoid memory leak!
+ delete original_buffer;
+ original_buffer = NULL;
+ buffer = NULL;
+#endif
// This value will be a constant value used to identify a numerical value.
// This value should be a macro defined in some centralized location.
- cppIndentifier = "numeric value";
+ if (isANumber == true)
+ {
+ cppIndentifier = "numeric value";
+
+ // Allow the line number to be a part of the restOfTheLine so it can be processed separately.
+ // printf ("cppIdentifierLength = %d \n",cppIdentifierLength);
+ // printf ("Before being reset: positionOfLastCharacterOfCppIdentifier = %d \n",positionOfLastCharacterOfCppIdentifier);
+ positionOfLastCharacterOfCppIdentifier -= cppIdentifierLength;
+ // printf ("After being reset: positionOfLastCharacterOfCppIdentifier = %d \n",positionOfLastCharacterOfCppIdentifier);
+ }
+ else
+ {
+ // printf ("This is not a number: cppIndentifier = %s \n",cppIndentifier.c_str());
+ }
#endif
}
@@ -1556,7 +1657,7 @@
// DQ (11/17/2008): This handles the case CPP declarations
// such as: "# 1 "test2008_05.F90"", "# 1 "<built-in>"",
// "# 1 "<command line>"" "# 1 "test2008_05.F90""
- cppDeclarationKind = PreprocessingInfo::CpreprocessorCompilerGenerateLineDeclaration;
+ cppDeclarationKind = PreprocessingInfo::CpreprocessorCompilerGeneratedLinemarker;
}
else
{
@@ -1567,11 +1668,12 @@
cppDeclarationKind = PreprocessingInfo::CpreprocessorUnknownDeclaration;
}
+ // Collect the rest of the line: (line length - next character position) + 1.
+ int restOfTheLineLength = (lineLength - (positionOfLastCharacterOfCppIdentifier+1)) + 1;
+ restOfTheLine = line.substr(positionOfLastCharacterOfCppIdentifier+1,restOfTheLineLength);
+
#if 0
// Debug output...
- // Collect the rest of the line: (line length - next character position) + 1.
- int restOfTheLineLength = (lineLength - (positionOfLastCharacterOfCppIdentifier+1)) + 1;
- string restOfTheLine = line.substr(positionOfLastCharacterOfCppIdentifier+1,restOfTheLineLength);
printf ("cppDeclarationKind = %s restOfTheLine = %s \n",PreprocessingInfo::directiveTypeName(cppDeclarationKind).c_str(),restOfTheLine.c_str());
#endif
@@ -1611,7 +1713,9 @@
// Open file for reading line by line!
string line;
- // printf ("In ROSEAttributesList::collectFreeFormatPreprocessorDirectivesAndCommentsForAST: Opening file %s for reading comments and CPP directives \n",filename.c_str());
+#if DEBUG_CPP_DIRECTIVE_COLLECTION
+ printf ("In ROSEAttributesList::collectPreprocessorDirectivesAndCommentsForAST: Opening file %s for reading comments and CPP directives \n",filename.c_str());
+#endif
ifstream targetFile (filename.c_str());
if (targetFile.is_open())
@@ -1631,248 +1735,53 @@
// Debugging output
cout << "collect CPP directives: " << line << endl;
#endif
-
-#if 1
int numberOfLines = 1;
+ string restOfTheLine;
PreprocessingInfo::DirectiveType cppDeclarationKind = PreprocessingInfo::CpreprocessorUnknownDeclaration;
- bool cppDirective = isCppDirective(line,cppDeclarationKind);
+ bool cppDirective = isCppDirective(line,cppDeclarationKind,restOfTheLine);
#if DEBUG_CPP_DIRECTIVE_COLLECTION
// printf ("cppDirective = %s \n",cppDirective ? "true" : "false");
printf ("cppDirective = %s cppDeclarationKind = %s \n",cppDirective ? "true" : "false",PreprocessingInfo::directiveTypeName(cppDeclarationKind).c_str());
#endif
-#else
- bool isCppDirective = false;
- char firstCharacter = line[0];
- if (firstCharacter != ' ' /* SPACE */ && firstCharacter != '\n' /* CR */ &&
- firstCharacter != '\0' /* NUL */ && firstCharacter != '\t' /* TAB */)
+ if (cppDirective == true)
{
- // This has something in the first colum, it might be a CPP directive!
-
- // Error checking on first character
#if 0
- if (!(firstCharacter >= ' ') || !(firstCharacter < 126))
- {
- printf ("firstCharacter = %d line.length() = %zu \n",(int)firstCharacter,line.length());
- }
+ printf ("line.length() = %zu line = %s \n",line.length(),line.c_str());
+ printf ("line[line.length()-1] = %c \n",line[line.length()-1]);
#endif
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("This might be a CPP directive (look for #)! lineCounter = %d \n",lineCounter);
-#endif
- }
-
- char firstNonBlankCharacter = line[0];
- size_t i = 0;
- size_t lineLength = line.length();
- while (i < lineLength && firstNonBlankCharacter == ' ')
- {
- firstNonBlankCharacter = line[i];
- i++;
- }
-
- // The character "!" starts a comment if only blanks are in the leading white space.
- int positionofHashCharacter = -1;
- if (firstNonBlankCharacter == '#')
- {
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("This is a CPP directive: i = %d lineCounter = %d line = %s length = %zu \n",i,lineCounter,line.c_str(),line.length());
-#endif
- isCppDirective = true;
- positionofHashCharacter = i;
- }
-
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("i = %d positionofHashCharacter = %d \n",i,positionofHashCharacter);
-#endif
- bool hasLineContinuation = false;
- char lastCharacter = line[lineLength-1];
- if (lastCharacter == '\\')
- {
- hasLineContinuation = true;
- }
-
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("hasLineContinuation = %s \n",hasLineContinuation ? "true" : "false");
-#endif
-
- PreprocessingInfo::DirectiveType cppDeclarationKind = PreprocessingInfo::CpreprocessorUnknownDeclaration;
-
- int numberOfLines = 1;
-
- if (isCppDirective == true)
- {
- // PreprocessingInfo(DirectiveType, const std::string & inputString, const std::string & filenameString,
- // int line_no , int col_no, int nol, RelativePositionType relPos, bool copiedFlag, bool unparsedFlag);
-
- // firstNonBlankCharacter = ' ';
- // printf ("firstNonBlankCharacter = %c \n",firstNonBlankCharacter);
- bool spaceAfterHash = false;
- while (i < lineLength && firstNonBlankCharacter == ' ' || firstNonBlankCharacter == '#')
+ if (line[line.length()-1] == '\\')
{
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("Looping over # or white space between # and CPP directive i = %d \n",i);
-#endif
- firstNonBlankCharacter = line[i];
- if (spaceAfterHash == false)
- spaceAfterHash = (firstNonBlankCharacter == ' ');
-
- i++;
- }
-
- int positionOfFirstCharacterOfCppIdentifier = i-1;
-
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("positionOfFirstCharacterOfCppIdentifier = %d spaceAfterHash = %s \n",positionOfFirstCharacterOfCppIdentifier,spaceAfterHash ? "true" : "false");
-#endif
- // Need to back up one!
- i = positionOfFirstCharacterOfCppIdentifier;
-
- char nonBlankCharacter = line[positionOfFirstCharacterOfCppIdentifier];
- int positionOfLastCharacterOfCppIdentifier = positionOfFirstCharacterOfCppIdentifier;
- // while (i < lineLength && isLegalCharacterForCppIndentifier(nonBlankCharacter) == true))
- while (i <= lineLength && ( ((nonBlankCharacter >= 'a' && nonBlankCharacter <= 'z') == true) || (nonBlankCharacter >= '0' && nonBlankCharacter <= '9') == true))
- {
- nonBlankCharacter = line[i];
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("In loop: i = %d lineLength = %d nonBlankCharacter = %c \n",i,lineLength,isprint(nonBlankCharacter) ? nonBlankCharacter : '.');
-#endif
- i++;
- }
-
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("i = %d \n",i);
-#endif
-
- // Need to backup two (unless this is the end of the line (as in "#endif")
- positionOfLastCharacterOfCppIdentifier = i-2;
-
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("positionOfLastCharacterOfCppIdentifier = %d \n",positionOfLastCharacterOfCppIdentifier);
-#endif
- int cppIdentifierLength = (positionOfLastCharacterOfCppIdentifier - positionOfFirstCharacterOfCppIdentifier) + 1;
- string cppIndentifier = line.substr(positionOfFirstCharacterOfCppIdentifier,cppIdentifierLength);
-
- // Some names will convert to integer values
- long integerValue = -1;
- if (spaceAfterHash == true)
- {
- // printf ("firstNonBlankCharacter = %c \n",firstNonBlankCharacter);
- // ROSE_ASSERT(firstNonBlankCharacter == '\"');
#if 0
- // The atoi() function is not supposed to be used any more.
- integerValue = atoi(cppIndentifier.c_str());
-#else
- const char* str = cppIndentifier.c_str();
- // strtol will put the string into buffer if str is not a number and 2nd parameter is not NULL.
- integerValue = strtol(str,NULL,10);
- cppIndentifier = "numeric value";
+ printf ("Found line continuation: line = %s \n",line.c_str());
#endif
- }
+ string nextLine;
+ while (line[line.length()-1] == '\\')
+ {
+ getline(targetFile,nextLine);
-#if DEBUG_CPP_DIRECTIVE_COLLECTION
- printf ("cppIdentifierLength = %d cppIndentifier = %s integerValue = %ld \n",cppIdentifierLength,cppIndentifier.c_str(),integerValue);
-#endif
-
- // classify the CCP directive
- if (cppIndentifier == "include")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorIncludeDeclaration;
+ // Add linefeed to force nextLine onto the next line when output.
+ line += "\n" + nextLine;
+ }
}
- else if (cppIndentifier == "includenext")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorIncludeNextDeclaration;
- }
- else if (cppIndentifier == "define")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorDefineDeclaration;
- }
- else if (cppIndentifier == "undef")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorUndefDeclaration;
- }
- else if (cppIndentifier == "ifdef")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorIfdefDeclaration;
- }
- else if (cppIndentifier == "ifndef")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorIfndefDeclaration;
- }
- else if (cppIndentifier == "if")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorIfDeclaration;
- }
- else if (cppIndentifier == "else")
- {
- // printf ("Setting cppIndentifier to CpreprocessorElseDeclaration \n");
- cppDeclarationKind = PreprocessingInfo::CpreprocessorElseDeclaration;
- }
- else if (cppIndentifier == "elif")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorElifDeclaration;
- }
- else if (cppIndentifier == "endif")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorEndifDeclaration;
- }
- else if (cppIndentifier == "line")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorLineDeclaration;
- }
- else if (cppIndentifier == "error")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorErrorDeclaration;
- }
- else if (cppIndentifier == "warning")
- {
- cppDeclarationKind = PreprocessingInfo::CpreprocessorWarningDeclaration;
- }
- else if (cppIndentifier == "pragma")
- {
- // Ignore case of #pragma
- cppDeclarationKind = PreprocessingInfo::CpreprocessorUnknownDeclaration;
- }
- else if (cppIndentifier == "ident")
- {
- // Ignore case of #pragma
- cppDeclarationKind = PreprocessingInfo::CpreprocessorIdentDeclaration;
- }
- else if (cppIndentifier == "numeric value")
- {
- // DQ (11/17/2008): This handles the case CPP declarations
- // such as: "# 1 "test2008_05.F90"", "# 1 "<built-in>"",
- // "# 1 "<command line>"" "# 1 "test2008_05.F90""
- cppDeclarationKind = PreprocessingInfo::CpreprocessorCompilerGenerateLineDeclaration;
- }
- else
- {
- printf ("Error: Unknown cppIndentifier = %s \n",cppIndentifier.c_str());
- ROSE_ASSERT(false);
- cppDeclarationKind = PreprocessingInfo::CpreprocessorUnknownDeclaration;
- }
-
-#if 1
- // Collect the rest of the line: (line length - next character position) + 1.
- int restOfTheLineLength = (lineLength - (positionOfLastCharacterOfCppIdentifier+1)) + 1;
- string restOfTheLine = line.substr(positionOfLastCharacterOfCppIdentifier+1,restOfTheLineLength);
- printf ("cppDeclarationKind = %s restOfTheLine = %s \n",PreprocessingInfo::directiveTypeName(cppDeclarationKind).c_str(),restOfTheLine.c_str());
-#endif
-
+ // printf ("After processing continuation lines: line.length() = %zu line = %s \n",line.length(),line.c_str());
}
-#endif
#if 1
// DQ (11/17/2008): Refactored the code to make it simpler to add here!
- // used switch to provide room for PHP, and pernaps C, C++ if we wanted
- // to handle then this way. Note that C permits multiple comments on a
- // single line, this is not addressed here.
- // if (cppDeclarationKind == PreprocessingInfo::CpreprocessorUnknownDeclaration)
+ // If this is not a CPP directive, then check if it is a comment (note
+ // that for Fortran (for fixed format), a CPP directive could be identified
+ // as a comment so we have to check for CPP directives first.
if (cppDirective == false)
{
bool isComment = false;
+
+ // Used switch to provide room for PHP, and pernaps C, C++ if we wanted
+ // to handle then this way. Note that C permits multiple comments on a
+ // single line, this is not addressed here.
switch (languageType)
{
// case e_Cxx_language: /* C and C++ cases are already handled via the lex based pass. */
@@ -1915,6 +1824,111 @@
lineCounter,0,numberOfLines,PreprocessingInfo::before);
ROSE_ASSERT(cppDirective != NULL);
attributeList.push_back(cppDirective);
+
+ // DQ (11/28/2008): Gather additional data for specific directives (CPP generated linemarkers (e.g. "# <line number> <filename> <flags>").
+ if (cppDeclarationKind == PreprocessingInfo::CpreprocessorCompilerGeneratedLinemarker)
+ {
+ // Gather the line number, filename, and any optional flags.
+ // printf ("\nProcessing a CpreprocessorCompilerGeneratedLinemarker: restOfTheLine = %s \n",restOfTheLine.c_str());
+
+ // The IR node has not been build yet, we have to save the required information into the PreprocessingInfo object.
+ // SgLinemarkerDirectiveStatement* linemarkerDirective = isSgLinemarkerDirectiveStatement(cppDirective);
+ // ROSE_ASSERT(linemarkerDirective != NULL);
+
+ size_t i = 0;
+ size_t positionOfFirstCharacterOfIntegerValue = 0;
+ size_t lineLength = restOfTheLine.length();
+ char nonBlankCharacter = restOfTheLine[0];
+ while (i <= lineLength && (nonBlankCharacter >= '0' && nonBlankCharacter <= '9') == true)
+ {
+ nonBlankCharacter = restOfTheLine[i];
+#if 0
+ printf ("In loop: i = %d lineLength = %d nonBlankCharacter = %c \n",i,lineLength,isprint(nonBlankCharacter) ? nonBlankCharacter : '.');
+#endif
+ i++;
+ }
+
+#if 0
+ printf ("i = %d \n",i);
+#endif
+
+ // Need to backup two (for example if this is the end of the line, as in "#endif")
+ size_t positionOfLastCharacterOfIntegerValue = i-2;
+
+#if 0
+ printf ("positionOfLastCharacterOfIntegerValue = %d \n",positionOfLastCharacterOfIntegerValue);
+#endif
+ int lineNumberLength = (positionOfLastCharacterOfIntegerValue - positionOfFirstCharacterOfIntegerValue) + 1;
+ string cppIndentifier = restOfTheLine.substr(positionOfFirstCharacterOfIntegerValue,lineNumberLength);
+
+ // Some names will convert to integer values
+ long integerValue = -1;
+
+ // printf ("firstNonBlankCharacter = %c \n",firstNonBlankCharacter);
+ // ROSE_ASSERT(firstNonBlankCharacter == '\"');
+#if 0
+ // The atoi() function is not supposed to be used any more.
+ integerValue = atoi(cppIndentifier.c_str());
+#else
+ // The modern way to handle conversion of string to integer value is to
+ // use strtol(), and not atoi(). But atoi() is simpler.
+ const char* str = cppIndentifier.c_str();
+
+ // strtol will put the string into buffer if str is not a number and 2nd parameter is not NULL.
+ integerValue = strtol(str,NULL,10);
+#endif
+#if 0
+ printf ("integerValue = %ld \n",integerValue);
+#endif
+ cppDirective->set_lineNumberForCompilerGeneratedLinemarker(integerValue);
+
+ size_t remainingLineLength = (lineLength - positionOfLastCharacterOfIntegerValue) - 1;
+ string remainingLine = restOfTheLine.substr(positionOfLastCharacterOfIntegerValue+1,remainingLineLength);
+#if 0
+ printf ("lineLength = %d positionOfLastCharacterOfIntegerValue = %d \n",lineLength,positionOfLastCharacterOfIntegerValue);
+ printf ("remainingLineLength = %d remainingLine = %s \n",remainingLineLength,remainingLine.c_str());
+#endif
+ size_t positionOfFirstQuote = remainingLine.find('"');
+ ROSE_ASSERT(positionOfFirstQuote != string::npos);
+
+ size_t positionOfLastQuote = remainingLine.rfind('"');
+ ROSE_ASSERT(positionOfLastQuote != string::npos);
+#if 0
+ printf ("positionOfFirstQuote = %zu positionOfLastQuote = %zu \n",positionOfFirstQuote,positionOfLastQuote);
+#endif
+ int filenameLength = (positionOfLastQuote - positionOfFirstQuote) + 1;
+#if 0
+ printf ("filenameLength = %zu \n",filenameLength);
+#endif
+ string filename = remainingLine.substr(positionOfFirstQuote,filenameLength);
+
+ cppDirective->set_filenameForCompilerGeneratedLinemarker(filename);
+
+ // Add 1 to move past the last quote and 1 more to move beyond any white space.
+ string optionalFlags;
+ if (positionOfLastQuote+2 < remainingLineLength)
+ {
+#if 0
+ printf ("Computing optional flags \n");
+#endif
+ optionalFlags = remainingLine.substr(positionOfLastQuote+2);
+#if 0
+ printf ("Computing optional flags: optionalFlags = %s \n",optionalFlags.c_str());
+#endif
+ }
+
+ // printf ("optionalFlags = %s \n",optionalFlags.c_str());
+ cppDirective->set_optionalflagsForCompilerGeneratedLinemarker(optionalFlags);
+#if 0
+ printf ("cppDirective.lineNumberForCompilerGeneratedLinemarker = %d \n",cppDirective->get_lineNumberForCompilerGeneratedLinemarker());
+ printf ("cppDirective.filenameForCompilerGeneratedLinemarker = %s \n",cppDirective->get_filenameForCompilerGeneratedLinemarker().c_str());
+ printf ("cppDirective.optionalflagsForCompilerGeneratedLinemarker = %s \n",cppDirective->get_optionalflagsForCompilerGeneratedLinemarker().c_str());
+#endif
+#if 0
+ printf ("Exiting as part of debugging ... \n");
+ ROSE_ASSERT(false);
+#endif
+ }
}
lineCounter++;
@@ -1927,7 +1941,7 @@
}
else
{
- cerr << "Unable to open free format Fortran file";
+ cerr << "Unable to open target source file";
ROSE_ASSERT(false);
}
Modified: branches/imperial/src/frontend/SageIII/rose_attributes_list.h
===================================================================
--- branches/imperial/src/frontend/SageIII/rose_attributes_list.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/rose_attributes_list.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -10,7 +10,7 @@
// Include the ROSE lex specific definitions of tokens
#include "general_token_defs.h"
-
+// DQ (12/22/2008): I would appriciate it if this were a better name...
#if CAN_NOT_COMPILE_WITH_ROSE != true
#include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class
@@ -55,7 +55,7 @@
class PreprocessingInfo
{
-
+ // This is part of Wave support in ROSE.
#if CAN_NOT_COMPILE_WITH_ROSE != true
public:
/*
@@ -102,7 +102,6 @@
r_macro_def()
: macro_name(), paramaters(),definition()
{
-
}
} rose_macro_definition;
@@ -179,9 +178,18 @@
// in various files.
enum DirectiveType
{
+ // This is treated as an error
CpreprocessorUnknownDeclaration,
+
+ // These are a classification for comments
C_StyleComment,
CplusplusStyleComment,
+ FortranStyleComment,
+
+ // DQ (11/20/2008): Added classification for blank line (a language independent form of comment).
+ CpreprocessorBlankLine,
+
+ // These are translated into IR nodes
CpreprocessorIncludeDeclaration,
CpreprocessorIncludeNextDeclaration,
CpreprocessorDefineDeclaration,
@@ -200,35 +208,41 @@
CpreprocessorWarningDeclaration,
CpreprocessorEmptyDeclaration,
- // AS (11/18/05): Added macro support
+ // AS (11/18/05): Added macro support (these are generated by the Wave
+ // support, but need to be better documented as to what they mean).
CSkippedToken,
CMacroCall,
// AS & LIAO (8/12/2008): A PreprocessingInfo that is a
- // hand made MacroCall that will expand into a valid
- // statement.
+ // hand made MacroCall that will expand into a valid statement.
CMacroCallStatement,
+ // DQ (11/28/2008): What does this mean!
// A line replacement will replace a sub-tree in the AST
// after a node with position (filename,line)
LineReplacement,
+
+ // The is the 'extern "C" {' construct. Note that this is not captured in
+ // the EDG AST and it is required to be captured as part of the CPP and
+ // comment preprocessing.
ClinkageSpecificationStart,
ClinkageSpecificationEnd,
- // Added support for Fortran comments
- FortranStyleComment,
-
// DQ (11/17/2008): Added support for #ident
CpreprocessorIdentDeclaration,
- // DQ (11/17/2008): This handles the case CPP declarations
- // such as: "# 1 "test2008_05.F90"", "# 1 "<built-in>"",
+ // DQ (11/17/2008): This handles the case CPP declarations (called "linemarkers")
+ // (see Google for more details) such as: "# 1 "test2008_05.F90"", "# 1 "<built-in>"",
// "# 1 "<command line>"" "# 1 "test2008_05.F90""
- CpreprocessorCompilerGenerateLineDeclaration,
+ // The first token is the line number,
+ // the second token is the filename (or string),
+ // the optional tokens (zero or more) are flags:
+ // '1' indicates the start of a new file.
+ // '2' indicates returning to a file (having included another file).
+ // '3' indicates that the following text comes from a system header file, so certain warnings should be supressed.
+ // '4' indicates that the following text should be treated as being wrapped in an implicit 'extern "C"' block
+ CpreprocessorCompilerGeneratedLinemarker,
- // DQ (11/20/2008): Added classification for blank line.
- CpreprocessorBlankLine,
-
LastDirectiveType
};
@@ -237,23 +251,28 @@
// DQ (4/19/2006): Use the SgFileInfo object to hold the more complete
// information about the filename, line number, and column number.
- Sg_File_Info* file_info;
+ Sg_File_Info* file_info;
// int lineNumber;
// int columnNumber;
// Use string class to improve implementation
// char* stringPointer;
- std::string internalString;
+ std::string internalString;
- int numberOfLines;
+ int numberOfLines;
// enum value representing a classification of the different types of directives
- DirectiveType whatSortOfDirective;
+ DirectiveType whatSortOfDirective;
// Corresponding enum value
- RelativePositionType relativePosition;
+ RelativePositionType relativePosition;
- // functions
+ // DQ (11/28/2008): Support for CPP generated linemarkers
+ int lineNumberForCompilerGeneratedLinemarker;
+ std::string filenameForCompilerGeneratedLinemarker;
+ std::string optionalflagsForCompilerGeneratedLinemarker;
+
+ // member functions
public:
~PreprocessingInfo();
PreprocessingInfo();
@@ -325,6 +344,17 @@
// DQ (4/19/2006): Added Sg_File_Info objects to each PreprocessingInfo object
Sg_File_Info* get_file_info() const;
void set_file_info( Sg_File_Info* info );
+
+
+ // DQ (11/28/2008): Support for CPP generated linemarkers
+ int get_lineNumberForCompilerGeneratedLinemarker();
+ std::string get_filenameForCompilerGeneratedLinemarker();
+ std::string get_optionalflagsForCompilerGeneratedLinemarker();
+
+ // DQ (11/28/2008): Support for CPP generated linemarkers
+ void set_lineNumberForCompilerGeneratedLinemarker( int x );
+ void set_filenameForCompilerGeneratedLinemarker( std::string x );
+ void set_optionalflagsForCompilerGeneratedLinemarker( std::string x );
};
// DQ (10/15/2002) Changed list element from "PreprocessingInfo" to
@@ -411,8 +441,9 @@
// CPP directives and comments into the AST. All other tokens are ignore in this pass.
void generatePreprocessorDirectivesAndCommentsForAST( const std::string & filename );
+ // DQ (11/26/2008): This is old code!
// Collection comments and CPP directives for fixed format (easier case)
- void collectFixedFormatPreprocessorDirectivesAndCommentsForAST( const std::string & filename );
+ // void collectFixedFormatPreprocessorDirectivesAndCommentsForAST( const std::string & filename );
// DQ (11/16/2008): Adding support for recognition of CPP directives outside of the lex tokenization.
void collectPreprocessorDirectivesAndCommentsForAST( const std::string & filename, languageTypeEnum languageType );
@@ -420,7 +451,7 @@
// DQ (11/17/2008): Refactored the code.
bool isFortran77Comment( const std::string & line );
bool isFortran90Comment( const std::string & line );
- bool isCppDirective( const std::string & line, PreprocessingInfo::DirectiveType & cppDeclarationKind );
+ bool isCppDirective( const std::string & line, PreprocessingInfo::DirectiveType & cppDeclarationKind, std::string & restOfTheLine );
};
//
Modified: branches/imperial/src/frontend/SageIII/sageInterface/abiStuff.h
===================================================================
--- branches/imperial/src/frontend/SageIII/sageInterface/abiStuff.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/sageInterface/abiStuff.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -133,7 +133,6 @@
//! Layout generator for i386 ABI-like struct layout
// Handles structs and unions only
// Does not handle C++ stuff (inheritance, virtual functions) for now
-// No handling of arrays either
class NonpackedTypeLayoutGenerator: public ChainableTypeLayoutGenerator {
public:
NonpackedTypeLayoutGenerator(ChainableTypeLayoutGenerator* next)
Modified: branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.C
===================================================================
--- branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -362,6 +362,40 @@
return funcType;
}
+
+#if 0
+// DQ (1/4/2009): Need to finish this!!!
+//-----------------------------------------------
+// build member function type,
+//
+// insert into symbol table when not duplicated
+SgMemberFunctionType *
+SageBuilder::buildMemberFunctionType(SgType* return_type, SgFunctionParameterTypeList * typeList, SgClassDefinition *struct_name, unsigned int mfunc_specifier)
+ {
+ ROSE_ASSERT(return_type);
+
+ // SgMemberFunctionType (SgType *return_type=NULL, bool has_ellipses=true, SgClassDefinition *struct_name=NULL, unsigned int mfunc_specifier=0)
+ SgMemberFunctionType * funcType = new SgMemberFunctionType(return_type, false);
+ ROSE_ASSERT(funcType);
+
+ if (typeList!=NULL)
+ {
+ funcType->set_argument_list(typeList);
+ typeList->set_parent(funcType);
+ }
+ SgName typeName = funcType->get_mangled_type();
+ // maintain the type table
+ SgFunctionTypeTable * fTable = SgNode::get_globalFunctionTypeTable();
+ ROSE_ASSERT(fTable);
+
+ SgType* typeInTable = fTable->lookup_function_type(typeName);
+ if (typeInTable==NULL)
+ fTable->insert_function_type(typeName,funcType);
+
+ return funcType;
+ }
+#endif
+
//----------------------------------------------------
//! Build an opaque type with a name, useful when a type's details are unknown during transformation, especially for a runtime library's internal type.
SgType * SageBuilder::buildOpaqueType(std::string const name, SgScopeStatement * scope)
@@ -479,6 +513,11 @@
}
// TODO double check if there are exceptions
func->set_scope(scope);
+
+// DQ (1/5/2009): This is not always true (should likely use SageBuilder::topScopeStack() instead)
+ if (scope != SageBuilder::topScopeStack())
+ printf ("Warning: function parent may not be the same as the function scope (e.g. for member functions) \n");
+
func->set_parent(scope);
// mark as a forward declartion
@@ -516,6 +555,25 @@
//required ty AstConsistencyTests.C:TestAstForProperlySetDefiningAndNondefiningDeclarations()
ctor->set_definingDeclaration(ctor);
ctor->set_firstNondefiningDeclaration(ctor);
+
+// DQ (1/4/2009): Error checking
+ ROSE_ASSERT(result->get_associatedClassDeclaration() != NULL);
+
+ if (result->get_associatedClassDeclaration() == NULL)
+ {
+ printf ("Warning, must set the SgMemberFunctionDeclaration::associatedClassDeclaration \n");
+
+ ROSE_ASSERT(scope != NULL);
+ SgClassDefinition* classDefinition = isSgClassDefinition(scope);
+ ROSE_ASSERT(classDefinition != NULL);
+ SgDeclarationStatement* associatedDeclaration = classDefinition->get_declaration();
+ ROSE_ASSERT(associatedDeclaration != NULL);
+ SgClassDeclaration* associatedClassDeclaration = isSgClassDeclaration(associatedDeclaration);
+
+ // DQ (1/4/2009): This needs to be set, checked in AstConsistencyTests.C!
+ result->set_associatedClassDeclaration(associatedClassDeclaration);
+ }
+
return result;
}
@@ -528,6 +586,10 @@
//required ty AstConsistencyTests.C:TestAstForProperlySetDefiningAndNondefiningDeclarations()
ctor->set_definingDeclaration(ctor);
ctor->set_firstNondefiningDeclaration(ctor);
+
+// DQ (1/4/2009): Error checking
+ ROSE_ASSERT(result->get_associatedClassDeclaration() != NULL);
+
return result;
}
@@ -702,6 +764,17 @@
{
SgComplexVal* result = new SgComplexVal(real_value,imaginary_value,imaginary_value->get_type(),"");
ROSE_ASSERT(result);
+
+// DQ (12/31/2008): set and test the parents
+ if (real_value != NULL)
+ real_value->set_parent(result);
+
+ if (imaginary_value != NULL)
+ imaginary_value->set_parent(result);
+
+ ROSE_ASSERT(real_value == NULL || real_value->get_parent() != NULL);
+ ROSE_ASSERT(imaginary_value == NULL || imaginary_value->get_parent() != NULL);
+
setOneSourcePositionForTransformation(result);
return result;
}
@@ -710,6 +783,17 @@
{
SgComplexVal* result = new SgComplexVal(real_value,imaginary_value,imaginary_value->get_type(),str);
ROSE_ASSERT(result);
+
+// DQ (12/31/2008): set and test the parents
+ if (real_value != NULL)
+ real_value->set_parent(result);
+
+ if (imaginary_value != NULL)
+ imaginary_value->set_parent(result);
+
+ ROSE_ASSERT(real_value == NULL || real_value->get_parent() != NULL);
+ ROSE_ASSERT(imaginary_value == NULL || imaginary_value->get_parent() != NULL);
+
setOneSourcePositionNull(result);
return result;
}
@@ -718,22 +802,41 @@
{
SgComplexVal* result = new SgComplexVal(NULL,buildLongDoubleVal(imaginary_value),SgTypeLongDouble::createType(),"");
ROSE_ASSERT(result);
+
+// DQ (12/31/2008): set and test the parents
+ result->get_imaginary_value()->set_parent(result);
+ ROSE_ASSERT(result->get_imaginary_value()->get_parent() != NULL);
+
setOneSourcePositionForTransformation(result);
return result;
}
SgComplexVal* SageBuilder::buildImaginaryVal(SgValueExp* imaginary_value)
{
+ ROSE_ASSERT(imaginary_value != NULL);
+
SgComplexVal* result = new SgComplexVal(NULL,imaginary_value,imaginary_value->get_type(),"");
ROSE_ASSERT(result);
+
+// DQ (12/31/2008): set and test the parents
+ imaginary_value->set_parent(result);
+ ROSE_ASSERT(imaginary_value->get_parent() != NULL);
+
setOneSourcePositionForTransformation(result);
return result;
}
SgComplexVal* SageBuilder::buildImaginaryVal_nfi(SgValueExp* imaginary_value, const std::string& str)
{
+ ROSE_ASSERT(imaginary_value != NULL);
+
SgComplexVal* result = new SgComplexVal(NULL,imaginary_value,imaginary_value->get_type(),str);
+ imaginary_value->set_parent(result);
ROSE_ASSERT(result);
+
+// DQ (12/31/2008): set and test the parents
+ ROSE_ASSERT(imaginary_value->get_parent() != NULL);
+
setOneSourcePositionNull(result);
return result;
}
@@ -1409,6 +1512,67 @@
return result;
}
+// DQ (1/4/2009): Added support for SgConstructorInitializer
+SgConstructorInitializer *
+SageBuilder::buildConstructorInitializer(
+ SgMemberFunctionDeclaration *declaration/* = NULL*/,
+ SgExprListExp *args/* = NULL*/,
+ SgType *expression_type/* = NULL*/,
+ bool need_name /*= false*/,
+ bool need_qualifier /*= false*/,
+ bool need_parenthesis_after_name /*= false*/,
+ bool associated_class_unknown /*= false*/)
+ {
+ // Prototype:
+ // SgConstructorInitializer (SgMemberFunctionDeclaration *declaration, SgExprListExp *args, SgType *expression_type, bool need_name, bool need_qualifier, bool need_parenthesis_after_name, bool associated_class_unknown);
+
+ // DQ (1/4/2009): Error checking
+ ROSE_ASSERT(declaration->get_associatedClassDeclaration() != NULL);
+
+ SgConstructorInitializer* result = new SgConstructorInitializer( declaration, args, expression_type, need_name, need_qualifier, need_parenthesis_after_name, associated_class_unknown );
+ ROSE_ASSERT(result != NULL);
+ if (args != NULL)
+ {
+ args->set_parent(result);
+ setOneSourcePositionForTransformation(args);
+ }
+
+ setOneSourcePositionForTransformation(result);
+
+ return result;
+ }
+
+// DQ (1/4/2009): Added support for SgConstructorInitializer
+SgConstructorInitializer *
+SageBuilder::buildConstructorInitializer_nfi(
+ SgMemberFunctionDeclaration *declaration/* = NULL*/,
+ SgExprListExp *args/* = NULL*/,
+ SgType *expression_type/* = NULL*/,
+ bool need_name /*= false*/,
+ bool need_qualifier /*= false*/,
+ bool need_parenthesis_after_name /*= false*/,
+ bool associated_class_unknown /*= false*/)
+ {
+ // Prototype:
+ // SgConstructorInitializer (SgMemberFunctionDeclaration *declaration, SgExprListExp *args, SgType *expression_type, bool need_name, bool need_qualifier, bool need_parenthesis_after_name, bool associated_class_unknown);
+
+ // DQ (1/4/2009): Error checking
+ ROSE_ASSERT(declaration->get_associatedClassDeclaration() != NULL);
+
+ SgConstructorInitializer* result = new SgConstructorInitializer( declaration, args, expression_type, need_name, need_qualifier, need_parenthesis_after_name, associated_class_unknown );
+ ROSE_ASSERT(result != NULL);
+ if (args != NULL)
+ {
+ args->set_parent(result);
+ }
+
+ setOneSourcePositionNull(result);
+
+ return result;
+ }
+
+
+
//! Build sizeof() expression with an expression parameter
SgSizeOfOp* SageBuilder::buildSizeOfOp(SgExpression* exp/*= NULL*/)
{
@@ -2740,6 +2904,8 @@
SgEnumDeclaration * SageBuilder::buildEnumDeclaration(const SgName& name, SgScopeStatement* scope /*=NULL*/)
{
+ // DQ (1/11/2009): This function has semantics very different from the buildEnumDeclaration_nfi() function!
+
if (scope == NULL)
scope = SageBuilder::topScopeStack();
SgEnumDeclaration* decl = buildEnumDeclaration_nfi(name, scope);
@@ -2751,8 +2917,7 @@
SgEnumDeclaration * SageBuilder::buildEnumDeclaration_nfi(const SgName& name, SgScopeStatement* scope)
{
- SgEnumDeclaration* defdecl = new SgEnumDeclaration
- (name,NULL);
+ SgEnumDeclaration* defdecl = new SgEnumDeclaration (name,NULL);
ROSE_ASSERT(defdecl);
setOneSourcePositionNull(defdecl);
// constructor is side-effect free
@@ -2762,9 +2927,15 @@
SgEnumDeclaration* nondefdecl = buildNondefiningEnumDeclaration_nfi(name, scope);
nondefdecl->set_definingDeclaration(defdecl);
defdecl->set_firstNondefiningDeclaration(nondefdecl);
+
+ // DQ (1/11/2009): The buildNondefiningEnumDeclaration function builds an entry in the symbol table, and so we don't want a second one!
+#if 0
SgEnumSymbol* mysymbol = new SgEnumSymbol(nondefdecl);
ROSE_ASSERT(mysymbol);
+ // scope->print_symboltable("buildEnumDeclaration_nfi(): before inserting new SgEnumSymbol");
scope->insert_symbol(name, mysymbol);
+#endif
+
defdecl->set_scope(scope);
nondefdecl->set_scope(scope);
defdecl->set_parent(scope);
Modified: branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.h
===================================================================
--- branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/sageInterface/sageBuilder.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -467,6 +467,10 @@
SgAggregateInitializer * buildAggregateInitializer(SgExprListExp * initializers = NULL);
SgAggregateInitializer * buildAggregateInitializer_nfi(SgExprListExp * initializers);
+// DQ (!/4/2009): Added support for building SgConstructorInitializer
+SgConstructorInitializer * buildConstructorInitializer( SgMemberFunctionDeclaration *declaration,SgExprListExp *args,SgType *expression_type,bool need_name,bool need_qualifier,bool need_parenthesis_after_name,bool associated_class_unknown);
+SgConstructorInitializer * buildConstructorInitializer_nfi( SgMemberFunctionDeclaration *declaration,SgExprListExp *args,SgType *expression_type,bool need_name,bool need_qualifier,bool need_parenthesis_after_name,bool associated_class_unknown);
+
//! Build sizeof() expression with an expression parameter
SgSizeOfOp* buildSizeOfOp(SgExpression* exp= NULL);
SgSizeOfOp* buildSizeOfOp_nfi(SgExpression* exp);
Modified: branches/imperial/src/frontend/SageIII/sageInterface/sageInterface.C
===================================================================
--- branches/imperial/src/frontend/SageIII/sageInterface/sageInterface.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/sageInterface/sageInterface.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -817,6 +817,26 @@
break;
}
+ case V_SgInterfaceStatement:
+ {
+ name = "_fortran_interface_stmt_";
+ const SgInterfaceStatement* statement = isSgInterfaceStatement(declaration);
+ ROSE_ASSERT(statement != NULL);
+ ROSE_ASSERT(statement->get_parent() != NULL);
+ name += StringUtility::numberToString(const_cast<SgInterfaceStatement*>(statement));
+ break;
+ }
+
+ case V_SgFortranIncludeLine:
+ {
+ name = "_fortran_include_line_stmt_";
+ const SgFortranIncludeLine* statement = isSgFortranIncludeLine(declaration);
+ ROSE_ASSERT(statement != NULL);
+ ROSE_ASSERT(statement->get_parent() != NULL);
+ name += StringUtility::numberToString(const_cast<SgFortranIncludeLine*>(statement));
+ break;
+ }
+
// Note that the case for SgVariableDeclaration is not implemented
default:
// name = "default name (default case reached: not handled)";
Modified: branches/imperial/src/frontend/SageIII/sageSupport.C
===================================================================
--- branches/imperial/src/frontend/SageIII/sageSupport.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/frontend/SageIII/sageSupport.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -500,6 +500,40 @@
p_template_instantiation_mode = e_default;
}
+ // DQ (1/13/2009): Added support for GNU -include <header_file> option (include this file before all others).
+ string tempHeaderFile;
+ iter = local_commandLineArgumentList.begin();
+ while ( iter != local_commandLineArgumentList.end() )
+ {
+ if ( *iter == "-include")
+ {
+ iter++;
+ tempHeaderFile = *iter;
+
+ // printf ("Adding tempHeaderFile = %s to p_preincludeFileList \n",tempHeaderFile.c_str());
+ p_preincludeFileList.push_back(tempHeaderFile);
+ }
+
+ iter++;
+ }
+
+ // DQ (1/13/2009): Added support for GNU -include <header_file> option (include this file before all others).
+ string tempDirectory;
+ iter = local_commandLineArgumentList.begin();
+ while ( iter != local_commandLineArgumentList.end() )
+ {
+ if ( *iter == "-isystem")
+ {
+ iter++;
+ tempDirectory = *iter;
+
+ // printf ("Adding tempHeaderFile = %s to p_preincludeDirectoryList \n",tempDirectory.c_str());
+ p_preincludeDirectoryList.push_back(tempDirectory);
+ }
+
+ iter++;
+ }
+
// DQ (10/16/2005):
// Build versions of argc and argv that are separate from the input_argc and input_argv
// (so that we can be clear that there are no side-effects to the original argc and argv
@@ -508,6 +542,11 @@
vector<string> argv = get_originalCommandLineArgumentList();
ROSE_ASSERT(argv.size() > 0);
+ // DQ (12/22/2008): This should only be called once (outside of the loop over all command line arguments!
+ // DQ (12/8/2007): This leverages existing support in commandline processing
+ // printf ("In SgProject::processCommandLine(): Calling CommandlineProcessing::generateSourceFilenames(argv) \n");
+ p_sourceFileNameList = CommandlineProcessing::generateSourceFilenames(argv);
+
// Build a list of source, object, and library files on the command line
// int sourceFileNameCounter = 0;
for (unsigned int i = 1; i < argv.size(); i++)
@@ -521,7 +560,7 @@
// ROSE_ASSERT (ROSE::sourceFileNamesWithoutPath[sourceFileNameCounter] != NULL);
// DQ (12/8/2007): This leverages existing support in commandline processing
- p_sourceFileNameList = CommandlineProcessing::generateSourceFilenames(argv);
+ // p_sourceFileNameList = CommandlineProcessing::generateSourceFilenames(argv);
// printf ("In SgProject::processCommandLine(): p_sourceFileNameList.size() = %zu \n",p_sourceFileNameList.size());
@@ -570,14 +609,14 @@
// look only for -I include directories (directories where #include<filename> will be found)
if ( (length > 2) && (argv[i][0] == '-') && (argv[i][1] == 'I') )
{
- //AS Changed source code to support absolute paths
- std::string includeDirectorySpecifier = argv[i].substr(2);
- includeDirectorySpecifier = StringUtility::getAbsolutePathFromRelativePath(includeDirectorySpecifier );
- p_includeDirectorySpecifierList.push_back("-I"+includeDirectorySpecifier);
+ // AS Changed source code to support absolute paths
+ std::string includeDirectorySpecifier = argv[i].substr(2);
+ includeDirectorySpecifier = StringUtility::getAbsolutePathFromRelativePath(includeDirectorySpecifier );
+ p_includeDirectorySpecifierList.push_back("-I"+includeDirectorySpecifier);
}
}
-#if 0
+#if 1
if ( get_verbose() > 1 )
{
// Find out what file we are doing transformations upon
@@ -1362,6 +1401,17 @@
set_visualize_dwarf_only(true);
}
+ // DQ (1/10/2009): The C language ASM statements are providing significant trouble, they are
+ // frequently machine specific and we are compiling then on architectures for which they were
+ // not designed. This option allows then to be read, constructed in the AST to support analysis
+ // but not unparsed in the code given to the backend compiler, since this can fail. (See
+ // test2007_20.C from Linux Kernel for an example).
+ if ( CommandlineProcessing::isOption(argv,"-rose:","(skip_unparse_asm_commands)",true) == true )
+ {
+ // printf ("option -rose:skip_unparse_asm_commands found \n");
+ set_skip_unparse_asm_commands(true);
+ }
+
// DQ (9/2/2008): This is now set in the new SgBinaryFile IR node.
// DQ (8/26/2008): support for optional more agressive mode of disassembly of binary from all
// executable segments instead of just section based.
@@ -1658,6 +1708,8 @@
optionCount = sla(argv, "-rose:", "($)", "(visualize_executable_file_format_skip_symbols)",1);
optionCount = sla(argv, "-rose:", "($)", "(visualize_dwarf_only)",1);
+ optionCount = sla(argv, "-rose:", "($)", "(skip_unparse_asm_commands)",1);
+
// DQ (8/26/2007): Disassembly support from segments (true) instead of sections (false, default).
optionCount = sla(argv, "-rose:", "($)", "(aggressive)",1);
@@ -1777,18 +1829,120 @@
return returnValue;
}
+void
+SgFile::initializeSourcePosition( const std::string & sourceFilename )
+ {
+ ROSE_ASSERT(this != NULL);
+ // printf ("Inside of SgFile::initializeSourcePosition() \n");
+
+ Sg_File_Info* fileInfo = new Sg_File_Info(sourceFilename,1,1);
+ ROSE_ASSERT(fileInfo != NULL);
+
+ // set_file_info(fileInfo);
+ set_startOfConstruct(fileInfo);
+ fileInfo->set_parent(this);
+ ROSE_ASSERT(get_startOfConstruct() != NULL);
+ ROSE_ASSERT(get_file_info() != NULL);
+ }
+
+void
+SgSourceFile::initializeGlobalScope()
+ {
+ ROSE_ASSERT(this != NULL);
+
+ // printf ("Inside of SgSourceFile::initializeGlobalScope() \n");
+
+ // Note that SgFile::initializeSourcePosition() should have already been called.
+ ROSE_ASSERT(get_startOfConstruct() != NULL);
+
+ string sourceFilename = get_startOfConstruct()->get_filename();
+
+ // DQ (8/31/2006): Generate a NULL_FILE (instead of SgFile::SgFile) so that we can
+ // enforce that the filename is always an absolute path (starting with "/").
+ // Sg_File_Info* globalScopeFileInfo = new Sg_File_Info("SgGlobal::SgGlobal",0,0);
+ Sg_File_Info* globalScopeFileInfo = new Sg_File_Info(sourceFilename,0,0);
+ ROSE_ASSERT (globalScopeFileInfo != NULL);
+
+ // printf ("&&&&&&&&&& In SgSourceFile::initializeGlobalScope(): Building SgGlobal (with empty filename) &&&&&&&&&& \n");
+
+ set_globalScope( new SgGlobal( globalScopeFileInfo ) );
+ ROSE_ASSERT (get_globalScope() != NULL);
+
+ // DQ (2/15/2006): Set the parent of the SgGlobal IR node
+ get_globalScope()->set_parent(this);
+
+ // DQ (8/21/2008): Set the end of the global scope (even if it is updated later)
+ // printf ("In SgFile::initialization(): p_root->get_endOfConstruct() = %p \n",p_root->get_endOfConstruct());
+ ROSE_ASSERT(get_globalScope()->get_endOfConstruct() == NULL);
+ get_globalScope()->set_endOfConstruct(new Sg_File_Info(sourceFilename,0,0));
+ ROSE_ASSERT(get_globalScope()->get_endOfConstruct() != NULL);
+
+ // DQ (1/21/2008): Set the filename in the SgGlobal IR node so that the traversal to add CPP directives and comments will succeed.
+ ROSE_ASSERT (get_globalScope() != NULL);
+ ROSE_ASSERT(get_globalScope()->get_startOfConstruct() != NULL);
+
+ // DQ (8/21/2008): Modified to make endOfConstruct consistant (avoids warning in AST consistancy check).
+ // ROSE_ASSERT(p_root->get_endOfConstruct() == NULL);
+ ROSE_ASSERT(get_globalScope()->get_endOfConstruct() != NULL);
+
+ // p_root->get_file_info()->set_filenameString(p_sourceFileNameWithPath);
+ // ROSE_ASSERT(p_root->get_file_info()->get_filenameString().empty() == false);
+
+#if 0
+ Sg_File_Info::display_static_data("Resetting the SgGlobal startOfConstruct and endOfConstruct");
+ printf ("Resetting the SgGlobal startOfConstruct and endOfConstruct filename (p_sourceFileNameWithPath = %s) \n",p_sourceFileNameWithPath.c_str());
+#endif
+
+ // DQ (12/22/2008): Added to support CPP preprocessing of Fortran files.
+ string filename = p_sourceFileNameWithPath;
+ if (get_requires_C_preprocessor() == true)
+ {
+ // This must be a Fortran source file (requiring the use of CPP to process its directives.
+ filename = generate_C_preprocessor_intermediate_filename(filename);
+ }
+
+ // printf ("get_requires_C_preprocessor() = %s filename = %s \n",get_requires_C_preprocessor() ? "true" : "false",filename.c_str());
+
+ // get_globalScope()->get_startOfConstruct()->set_filenameString(p_sourceFileNameWithPath);
+ get_globalScope()->get_startOfConstruct()->set_filenameString(filename);
+ ROSE_ASSERT(get_globalScope()->get_startOfConstruct()->get_filenameString().empty() == false);
+
+ // DQ (8/21/2008): Uncommented to make the endOfConstruct consistant (avoids warning in AST consistancy check).
+ // get_globalScope()->get_endOfConstruct()->set_filenameString(p_sourceFileNameWithPath);
+ get_globalScope()->get_endOfConstruct()->set_filenameString(filename);
+ ROSE_ASSERT(get_globalScope()->get_endOfConstruct()->get_filenameString().empty() == false);
+
+#if 0
+ printf ("DONE: Resetting the SgGlobal startOfConstruct and endOfConstruct filename (filename = %s) \n",filename.c_str());
+ Sg_File_Info::display_static_data("DONE: Resetting the SgGlobal startOfConstruct and endOfConstruct");
+#endif
+
+ // DQ (12/23/2008): These should be in the Sg_File_Info map already.
+ ROSE_ASSERT(Sg_File_Info::getIDFromFilename(get_file_info()->get_filename()) >= 0);
+ if (get_requires_C_preprocessor() == true)
+ {
+ ROSE_ASSERT(Sg_File_Info::getIDFromFilename(generate_C_preprocessor_intermediate_filename(get_file_info()->get_filename())) >= 0);
+ }
+ }
+
+
SgFile*
determineFileType ( vector<string> argv, int nextErrorCode, SgProject* project )
{
SgFile* file = NULL;
+
// DQ (4/21/2006): New version of source file name handling (set the source file name early)
+ // printf ("In determineFileType(): Calling CommandlineProcessing::generateSourceFilenames(argv) \n");
Rose_STL_Container<string> fileList = CommandlineProcessing::generateSourceFilenames(argv);
// this->display("In SgFile::setupSourceFilename()");
- // printf ("listToString(argv) = %s \n",StringUtility::listToString(argv).c_str());
- // printf ("listToString(fileList) = %s \n",StringUtility::listToString(fileList).c_str());
+ // printf ("listToString(argv) = %s \n",StringUtility::listToString(argv).c_str());
+ // printf ("listToString(fileList) = %s \n",StringUtility::listToString(fileList).c_str());
+ // DQ (12/23/2008): I think that we may be able to assert this is true, if so then we can simplify the code below.
+ ROSE_ASSERT(fileList.empty() == false);
+
if (fileList.empty() == false)
{
ROSE_ASSERT(fileList.size() == 1);
@@ -1825,13 +1979,19 @@
// ROSE_ASSERT(false);
// DQ (5/18/2008): Set this to true (redundant, since the default already specified as true)
- //file->set_requires_C_preprocessor(true);
+ // file->set_requires_C_preprocessor(true);
// DQ (11/17/2007): Mark this as a file using a Fortran file extension (else this turns off options down stream).
if (CommandlineProcessing::isFortranFileNameSuffix(filenameExtension) == true)
{
- file = new SgSourceFile ( argv, project );
+ SgSourceFile* sourceFile = new SgSourceFile ( argv, project );
+ file = sourceFile;
+ // printf ("----------- Great location to set the sourceFilename = %s \n",sourceFilename.c_str());
+
+ // DQ (12/23/2008): Moved initialization of source position (call to initializeSourcePosition())
+ // to earliest position in setup of SgFile.
+
// printf ("Calling file->set_sourceFileUsesFortranFileExtension(true) \n");
file->set_sourceFileUsesFortranFileExtension(true);
@@ -1840,9 +2000,18 @@
file->set_Fortran_only(true);
- // DQ (5/18/2008): Set this to true (redundant, since the default already specified as true)
+ // DQ (5/18/2008): Set this to true (redundant, since the default already specified as true).
+ // DQ (12/23/2008): Actually this is not redundant since the SgFile::initialization sets it to "false".
+ // Note: This is a little bit inconsistnat with the default set in ROSETTA.
file->set_requires_C_preprocessor(CommandlineProcessing::isFortranFileNameSuffixRequiringCPP(filenameExtension));
+ // printf ("Called set_requires_C_preprocessor(%s) \n",file->get_requires_C_preprocessor() ? "true" : "false");
+
+ // DQ (12/23/2008): This needs to be called after the set_requires_C_preprocessor() function is called.
+ // If CPP processing is required then the global scope should have a source position using the intermediate
+ // file name (generated by generate_C_preprocessor_intermediate_filename()).
+ sourceFile->initializeGlobalScope();
+
// Now set the specific types of Fortran file extensions
if (CommandlineProcessing::isFortran77FileNameSuffix(filenameExtension) == true)
{
@@ -1905,103 +2074,136 @@
file->set_backendCompileFormat(SgFile::e_free_form_output_format);
}
}
- else if (CommandlineProcessing::isPHPFileNameSuffix(filenameExtension) == true)
+ else
{
+ if (CommandlineProcessing::isPHPFileNameSuffix(filenameExtension) == true)
+ {
+ // file = new SgSourceFile ( argv, project );
+ SgSourceFile* sourceFile = new SgSourceFile ( argv, project );
+ file = sourceFile;
- file = new SgSourceFile ( argv, project );
-
file->set_sourceFileUsesPHPFileExtension(true);
file->set_outputLanguage(SgFile::e_PHP_output_language);
file->set_PHP_only(true);
- }
- else
- {
- // printf ("Calling file->set_sourceFileUsesFortranFileExtension(false) \n");
-
- // if (StringUtility::isCppFileNameSuffix(filenameExtension) == true)
- if (CommandlineProcessing::isCppFileNameSuffix(filenameExtension) == true)
- {
- file = new SgSourceFile ( argv, project );
- // This is a C++ file (so define __cplusplus, just like GNU gcc would)
- // file->set_requires_cplusplus_macro(true);
- file->set_sourceFileUsesCppFileExtension(true);
+ // DQ (12/23/2008): We don't handle CPP directives and comments for PHP yet.
+ // file->get_skip_commentsAndDirectives(true);
- // Use the filename suffix as a default means to set this value
- file->set_outputLanguage(SgFile::e_Cxx_output_language);
-
- file->set_Cxx_only(true);
-
+ // DQ (12/23/2008): This is the eariliest point where the global scope can be set.
+ // Note that file->get_requires_C_preprocessor() should be false.
+ ROSE_ASSERT(file->get_requires_C_preprocessor() == false);
+ sourceFile->initializeGlobalScope();
}
else
{
-
- // Liao, 6/6/2008, Assume AST with UPC will be unparsed using the C unparser
- if ( ( CommandlineProcessing::isCFileNameSuffix(filenameExtension) == true ) ||
- ( CommandlineProcessing::isUPCFileNameSuffix(filenameExtension) == true ) )
+ // printf ("Calling file->set_sourceFileUsesFortranFileExtension(false) \n");
+
+ // if (StringUtility::isCppFileNameSuffix(filenameExtension) == true)
+ if (CommandlineProcessing::isCppFileNameSuffix(filenameExtension) == true)
{
+ // file = new SgSourceFile ( argv, project );
+ SgSourceFile* sourceFile = new SgSourceFile ( argv, project );
+ file = sourceFile;
- file = new SgSourceFile ( argv, project );
+ // This is a C++ file (so define __cplusplus, just like GNU gcc would)
+ // file->set_requires_cplusplus_macro(true);
+ file->set_sourceFileUsesCppFileExtension(true);
- // This a not a C++ file (assume it is a C file and don't define the __cplusplus macro, just like GNU gcc would)
- file->set_sourceFileUsesCppFileExtension(false);
-
// Use the filename suffix as a default means to set this value
- file->set_outputLanguage(SgFile::e_C_output_language);
+ file->set_outputLanguage(SgFile::e_Cxx_output_language);
- file->set_C_only(true);
- // Liao 6/6/2008 Set the newly introduced p_UPC_only flag.
- //
- if (CommandlineProcessing::isUPCFileNameSuffix(filenameExtension) == true)
- file->set_UPC_only(true);
+ file->set_Cxx_only(true);
+
+ // DQ (12/23/2008): This is the eariliest point where the global scope can be set.
+ // Note that file->get_requires_C_preprocessor() should be false.
+ ROSE_ASSERT(file->get_requires_C_preprocessor() == false);
+ sourceFile->initializeGlobalScope();
}
else
{
- // printf ("This still might be a binary file (can not be an object file, since these are not accepted into the fileList by CommandlineProcessing::generateSourceFilenames()) \n");
+ // Liao, 6/6/2008, Assume AST with UPC will be unparsed using the C unparser
+ if ( ( CommandlineProcessing::isCFileNameSuffix(filenameExtension) == true ) ||
+ ( CommandlineProcessing::isUPCFileNameSuffix(filenameExtension) == true ) )
+ {
+ // file = new SgSourceFile ( argv, project );
+ SgSourceFile* sourceFile = new SgSourceFile ( argv, project );
+ file = sourceFile;
- // Detect if this is a binary (executable) file!
- bool isBinaryExecutable = isBinaryExecutableFile(sourceFilename);
+ // This a not a C++ file (assume it is a C file and don't define the __cplusplus macro, just like GNU gcc would)
+ file->set_sourceFileUsesCppFileExtension(false);
- if (isBinaryExecutable == true)
- {
+ // Use the filename suffix as a default means to set this value
+ file->set_outputLanguage(SgFile::e_C_output_language);
- file = new SgBinaryFile ( argv, project );
+ file->set_C_only(true);
- file->set_sourceFileUsesBinaryFileExtension(true);
- file->set_binary_only(true);
+ // Liao 6/6/2008 Set the newly introduced p_UPC_only flag.
+ if (CommandlineProcessing::isUPCFileNameSuffix(filenameExtension) == true)
+ file->set_UPC_only(true);
- // DQ (5/18/2008): Set this to false (since binaries are never preprocessed using the C preprocessor).
- file->set_requires_C_preprocessor(false);
+ // DQ (12/23/2008): This is the eariliest point where the global scope can be set.
+ // Note that file->get_requires_C_preprocessor() should be false.
+ ROSE_ASSERT(file->get_requires_C_preprocessor() == false);
+ sourceFile->initializeGlobalScope();
}
else
{
+ // This is not a source file recognized by ROSE, so it is either a binary executable or something that we can't process.
- file = new SgUnknownFile ( argv, project );
+ // printf ("This still might be a binary file (can not be an object file, since these are not accepted into the fileList by CommandlineProcessing::generateSourceFilenames()) \n");
- ROSE_ASSERT(file->get_parent() != NULL);
- ROSE_ASSERT(file->get_parent() == project);
+ // Detect if this is a binary (executable) file!
+ bool isBinaryExecutable = isBinaryExecutableFile(sourceFilename);
+ if (isBinaryExecutable == true)
+ {
+ file = new SgBinaryFile ( argv, project );
- // If all else fails, then output the type of file and exit.
- file->set_sourceFileTypeIsUnknown(true);
- file->set_requires_C_preprocessor(false);
+ // This should have already been setup!
+ // file->initializeSourcePosition();
- // file->set_parent(project);
- // outputTypeOfFileAndExit(sourceFilename);
+ file->set_sourceFileUsesBinaryFileExtension(true);
+ file->set_binary_only(true);
+
+ // DQ (5/18/2008): Set this to false (since binaries are never preprocessed using the C preprocessor).
+ file->set_requires_C_preprocessor(false);
+
+ ROSE_ASSERT(file->get_file_info() != NULL);
+ }
+ else
+ {
+ file = new SgUnknownFile ( argv, project );
+
+ // This should have already been setup!
+ // file->initializeSourcePosition();
+
+ ROSE_ASSERT(file->get_parent() != NULL);
+ ROSE_ASSERT(file->get_parent() == project);
+
+ // If all else fails, then output the type of file and exit.
+ file->set_sourceFileTypeIsUnknown(true);
+ file->set_requires_C_preprocessor(false);
+
+ ROSE_ASSERT(file->get_file_info() != NULL);
+ // file->set_parent(project);
+ // outputTypeOfFileAndExit(sourceFilename);
+ }
}
}
}
+
file->set_sourceFileUsesFortranFileExtension(false);
-
}
-
}
else
{
+ // DQ (12/22/2008): Make any error message from this branch more clear for debugging!
+ // AS Is this option possible?
+ printf ("Is this branch reachable? \n");
+ ROSE_ASSERT(false);
+ // abort();
- //AS Is this option possible?
- abort();
// ROSE_ASSERT (p_numberOfSourceFileNames == 0);
ROSE_ASSERT (file->get_sourceFileNameWithPath().empty() == true);
// If no source code file name was found then likely this is a link command
@@ -2010,22 +2212,21 @@
// printf ("No source file found on command line, assuming to be linker command line \n");
}
- //The frontend is called exlicitly outside the constructor since that allows for a cleaner
- //control flow. The callFrontEnd() relies on all the "set_" flags to be already called therefore
- //it was placed here.
- if( isSgUnknownFile(file) == NULL && file != NULL )
- {
+ // The frontend is called exlicitly outside the constructor since that allows for a cleaner
+ // control flow. The callFrontEnd() relies on all the "set_" flags to be already called therefore
+ // it was placed here.
+ if ( isSgUnknownFile(file) == NULL && file != NULL )
+ {
+ nextErrorCode = file->callFrontEnd() ;
+ ROSE_ASSERT ( nextErrorCode <= 3);
+ }
- nextErrorCode = file->callFrontEnd() ;
- ROSE_ASSERT ( nextErrorCode <= 3);
-
- }
-
// Keep the filename stored in the Sg_File_Info consistant. Later we will want to remove this redundency
// The reason we have the Sg_File_Info object is so that we can easily support filename matching based on
- // the integer values instead of string comparisions.
-
+ // the integer values instead of string comparisions. Required for the handling co CPP directives and comments.
+
// display("SgFile::setupSourceFilename()");
+
return file;
}
@@ -2035,52 +2236,25 @@
{
// Need a mechanism to select what kind of binary we will process.
-#if 1
// printf ("Calling SgAsmExecutableFileFormat::parseBinaryFormat() \n");
SgAsmExecutableFileFormat::parseBinaryFormat(sourceFilename,asmFile);
+ }
-#else
- // JJW (7/23/2008): We are using Robb's code for this, and it crashes on PE files
- // printf ("Calling generateBinaryExecutableFileInformation_ELF() \n");
- bool handled = false;
- // DQ (13/8/2008): Skip the use of the older binary file format support (from before Robb's work).
- // if (!handled) handled = generateBinaryExecutableFileInformation_ELF( sourceFilename, asmFile );
- // if (!handled) {} // generateBinaryExecutableFileInformation_Windows ( sourceFilename, asmFile );
-
- if (!handled) {
-
- // DQ (13/8/2008): This is one of the few remaining data member in a SgAsmFile IR node.
- asmFile->set_name(sourceFilename);
-
- // Hard wire this for the moment while I work on getting Robb's work into place...
- // DQ (13/8/2008): Removed this data member (such information is now in the SgAsmGenericHeader).
- // asmFile->set_machine_architecture(SgAsmFile::e_machine_architecture_Intel_80386);
-
- handled = true;
- }
- ROSE_ASSERT (handled);
-#endif
+static void makeSysIncludeList(const Rose_STL_Container<string>& dirs, Rose_STL_Container<string>& result)
+ {
+ string includeBase = findRoseSupportPathFromBuild("include-staging", "include");
+ for (Rose_STL_Container<string>::const_iterator i = dirs.begin(); i != dirs.end(); ++i)
+ {
+ ROSE_ASSERT (!i->empty());
+ string fullPath = (*i)[0] == '/' ? *i : (includeBase + "/" + *i);
+ result.push_back("--sys_include");
+ result.push_back(fullPath);
+ }
}
-
-
-
-
-
-static void makeSysIncludeList(const Rose_STL_Container<string>& dirs, Rose_STL_Container<string>& result) {
- string includeBase = findRoseSupportPathFromBuild("include-staging", "include");
- for (Rose_STL_Container<string>::const_iterator i = dirs.begin();
- i != dirs.end(); ++i) {
- ROSE_ASSERT (!i->empty());
- string fullPath = (*i)[0] == '/' ? *i : (includeBase + "/" + *i);
- result.push_back("--sys_include");
- result.push_back(fullPath);
- }
-}
-
void
SgFile::build_EDG_CommandLine ( vector<string> & inputCommandLine, vector<string> & argv, int fileNameIndex )
{
@@ -2110,7 +2284,7 @@
// DQ (4/21/2006): I think we can now assert this!
ROSE_ASSERT(fileNameIndex == 0);
- // printf ("Inside of SgFile::build_EDG_CommandLine(): fileNameIndex = %d \n",fileNameIndex);
+ // printf ("Inside of SgFile::build_EDG_CommandLine(): fileNameIndex = %d \n",fileNameIndex);
#if !defined(CXX_SPEC_DEF)
// Output an error and exit
@@ -2124,18 +2298,23 @@
Rose_STL_Container<string> configDefs(configDefsArray, configDefsArray + sizeof(configDefsArray) / sizeof(*configDefsArray));
Rose_STL_Container<string> Cxx_ConfigIncludeDirs(Cxx_ConfigIncludeDirsRaw, Cxx_ConfigIncludeDirsRaw + sizeof(Cxx_ConfigIncludeDirsRaw) / sizeof(const char*));
Rose_STL_Container<string> C_ConfigIncludeDirs(C_ConfigIncludeDirsRaw, C_ConfigIncludeDirsRaw + sizeof(C_ConfigIncludeDirsRaw) / sizeof(const char*));
- SgProject* myProject = isSgProject(this->get_parent());
- ROSE_ASSERT (myProject);
// Removed reference to __restrict__ so it could be placed into the preinclude vendor specific header file for ROSE.
// DQ (9/10/2004): Attept to add support for restrict (but I think this just sets it to true, using "-Dxxx=" works)
// const string roseSpecificDefs = "-DUSE_RESTRICT_POINTERS_IN_ROSE_TRANSFORMATIONS -DUSE_ROSE -D__restrict__=";
vector<string> roseSpecificDefs;
+
+ // Communicate that ROSE transformation can use the restrict keyword.
roseSpecificDefs.push_back("-DUSE_RESTRICT_POINTERS_IN_ROSE_TRANSFORMATIONS");
+
+ // Communicate to the generated program that we are using ROSE (in case there are specific options that the user wants to to invoke.
roseSpecificDefs.push_back("-DUSE_ROSE");
+
#ifdef ROSE_USE_NEW_EDG_INTERFACE
+ // Allow in internal indicator that EDG version 3.10 or 4.0 (or greater) is in use.
roseSpecificDefs.push_back("-DROSE_USE_NEW_EDG_INTERFACE");
#endif
+
ROSE_ASSERT(configDefs.empty() == false);
ROSE_ASSERT(Cxx_ConfigIncludeDirs.empty() == false);
ROSE_ASSERT(C_ConfigIncludeDirs.empty() == false);
@@ -2151,13 +2330,28 @@
vector<string> commandLine;
#ifdef ROSE_USE_NEW_EDG_INTERFACE
+
+ // Note that the new EDG/Sage interface does not require a generated set of header files specific to ROSE.
commandLine.push_back("--edg_base_dir");
+
+ // DQ (12/29/2008): Added support for EDG version 4.0 (constains design changes that break a number of things in the pre-version 4.0 work)
+#ifdef ROSE_USE_EDG_VERSION_4
+ commandLine.push_back(findRoseSupportPathFromBuild("src/frontend/CxxFrontend/EDG_4.0/lib", "share"));
+#else
commandLine.push_back(findRoseSupportPathFromBuild("src/frontend/CxxFrontend/EDG_3.10/lib", "share"));
#endif
+#endif
+ // display("Called from SgFile::build_EDG_CommandLine");
+
// AS (03/08/2006) Added support for g++ preincludes
// Rose_STL_Container<std::string> listOfPreincludes;
+#if 0
+ // This functionality has been moved to before source name extraction since the
+ // -include file will be extracted as a file and treated as a source file name
+ // and the -include will not have an option.
+
// DQ (12/1/2006): Code added by Andreas (07/03/06) and moved to a new position
// so that we could modify the string input from CXX_SPEC_DEF (configDefs).
string preinclude_string_target = "-include";
@@ -2171,8 +2365,10 @@
i++;
ROSE_ASSERT(i<argv.size());
string currentArgument(argv[i]);
-
+
+ // Note that many new style C++ header files don't have a ".h" suffix
string headerSuffix = ".h";
+
int jlength = headerSuffix.size();
int length = currentArgument.size();
ROSE_ASSERT( length > jlength);
@@ -2191,10 +2387,60 @@
commandLine.push_back(currentArgument);
}
}
+#else
+ SgProject* project = isSgProject(this->get_parent());
+ ROSE_ASSERT (project != NULL);
+ // DQ (1/13/2009): The preincludeFileList was built if the -include <file> option was used
+ for (SgStringList::iterator i = project->get_preincludeFileList().begin(); i != project->get_preincludeFileList().end(); i++)
+ {
+ // Build the preinclude file list
+ ROSE_ASSERT(project->get_preincludeFileList().empty() == false);
+
+ // printf ("Building commandline: --preinclude %s \n",(*i).c_str());
+ commandLine.push_back("--preinclude");
+ commandLine.push_back(*i);
+ }
+#endif
+
+#if 0
+ // This functionality has been moved to before source name extraction since the
+ // -isystem dir will be extracted as a file name and treated as a source file name
+ // and the -isystem will not have an option.
+
+ // AS(02/24/06) Add support for the gcc "-isystem" option (this added a specified directory
+ // to the start of the system include path). This maps to the "--sys_include" in EDG.
+ string isystem_string_target = "-isystem";
+ for (unsigned int i=1; i < argv.size(); i++)
+ {
+ // AS (070306) Handle g++ --include directives
+ std::string stack_arg(argv[i]);
+ // std::cout << "stack arg is: " << stack_arg << std::endl;
+ if( stack_arg.find(isystem_string_target) <= 2){
+ i++;
+ ROSE_ASSERT(i<argv.size());
+ std::string currentArgument(argv[i]);
+ // std::cout << "Current argument " << currentArgument << std::endl;
+
+ currentArgument = StringUtility::getAbsolutePathFromRelativePath(currentArgument);
+ commandLine.push_back("--sys_include");
+ commandLine.push_back(currentArgument);
+ }
+ }
+#else
+ // DQ (1/13/2009): The preincludeDirectoryList was built if the -isystem <dir> option was used
+ for (SgStringList::iterator i = project->get_preincludeDirectoryList().begin(); i != project->get_preincludeDirectoryList().end(); i++)
+ {
+ // Build the preinclude directory list
+ // printf ("Building commandline: --sys_include %s \n",(*i).c_str());
+ commandLine.push_back("--sys_include");
+ commandLine.push_back(*i);
+ }
+#endif
+
commandLine.insert(commandLine.end(), configDefs.begin(), configDefs.end());
- // DQ (12/2/2006): Both GNU and EDG determin the language mode from the source file name extension.
+ // DQ (12/2/2006): Both GNU and EDG determine the language mode from the source file name extension.
// In ROSE we also require that C files be explicitly specified to use the C language mode. Thus
// C++ source files will be treated as C++ even if the C language rules are specified, however they
// are restricted to the C subset of C++.
@@ -2204,6 +2450,11 @@
// Find the C++ sys include path for the rose_edg_required_macros_and_functions.h
vector<string> roseHeaderDirCPP(1, "--sys_include");
+ // This includes a generated header file that defines the __builtin functions and a number
+ // of predefined macros obtained from the backend compiler. The new EDG/Sage interface
+ // does not require this function and I think that the file is not generated in this case
+ // which is why there is a test for it's existance to see if it should be include. I would
+ // rather see a more direct test.
for (Rose_STL_Container<string>::iterator i = Cxx_ConfigIncludeDirs.begin(); i != Cxx_ConfigIncludeDirs.end(); i++)
{
string file = (*i) + "/rose_edg_required_macros_and_functions.h";
@@ -2216,7 +2467,7 @@
}
}
- // Find the C sys include path for the rose_edg_required_macros_and_functions.h
+ // Find the C sys include path for the rose_edg_required_macros_and_functions.h (see comment above for --sys_include use in CPP).
vector<string> roseHeaderDirC(1, "--sys_include");
for (Rose_STL_Container<string>::iterator i = C_ConfigIncludeDirs.begin(); i != C_ConfigIncludeDirs.end(); i++)
@@ -2304,26 +2555,6 @@
commandLine.push_back("-DROSE_CPP_MODE=1");
}
- // AS(02/24/06) Add support for the gcc "-isystem" option (this added a specified directory
- // to the start of the system include path). This maps to the "--sys_include" in EDG.
- string isystem_string_target = "-isystem";
- for (unsigned int i=1; i < argv.size(); i++)
- {
- // AS (070306) Handle g++ --include directives
- std::string stack_arg(argv[i]);
- // std::cout << "stack arg is: " << stack_arg << std::endl;
- if( stack_arg.find(isystem_string_target) <= 2){
- i++;
- ROSE_ASSERT(i<argv.size());
- std::string currentArgument(argv[i]);
- // std::cout << "Current argument " << currentArgument << std::endl;
-
- currentArgument = StringUtility::getAbsolutePathFromRelativePath(currentArgument);
- commandLine.push_back("--sys_include");
- commandLine.push_back(currentArgument);
- }
- }
-
commandLine.insert(commandLine.end(), roseSpecificDefs.begin(), roseSpecificDefs.end());
// DQ (9/17/2006): We should be able to build a version of this code which hands a std::string to StringUtility::splitStringIntoStrings()
@@ -2769,6 +3000,7 @@
// display("at base of build_EDG_CommandLine()");
}
+
//FMZ(5/19/2008):
#ifdef USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
extern void jserver_init();
@@ -2882,9 +3114,9 @@
set_globalScope(NULL);
- // This constructor actually makes the call to EDG to build the AST (via callFrontEnd()).
+ // This constructor actually makes the call to EDG/OFP to build the AST (via callFrontEnd()).
+ // printf ("In SgSourceFile::SgSourceFile(): Calling doSetupForConstructor() \n");
doSetupForConstructor(argv, project);
-
}
#if 0
@@ -2945,11 +3177,15 @@
// : SgFile (argv,errorCode,fileNameIndex,project)
{
p_binaryFile = NULL;
+
+ // Assume a binary generated from a compiler for now since this
+ // is easier, the more aggressive modes are still in development.
p_aggressive = false;
// printf ("In the SgBinaryFile constructor \n");
// This constructor actually makes the call to EDG to build the AST (via callFrontEnd()).
+ // printf ("In SgBinaryFile::SgBinaryFile(): Calling doSetupForConstructor() \n");
doSetupForConstructor(argv, project);
}
@@ -2990,9 +3226,11 @@
// printf ("currentFileName = %s \n",currentFileName.c_str());
// DQ (11/13/2008): Removed overly complex logic here!
+ // printf ("+++++++++++++++ Calling determineFileType() currentFileName = %s \n",currentFileName.c_str());
SgFile* newFile = determineFileType(argv, nextErrorCode, this);
ROSE_ASSERT (newFile != NULL);
+ // printf ("+++++++++++++++ DONE: Calling determineFileType() currentFileName = %s \n",currentFileName.c_str());
// printf ("In SgProject::parse(): newFile = %p = %s \n",newFile,newFile->class_name().c_str());
ROSE_ASSERT (newFile->get_startOfConstruct() != NULL);
@@ -3003,7 +3241,7 @@
// newFile->set_parent(this);
// This just adds the new file to the list of files stored internally
- set_file ( *newFile );
+ set_file ( *newFile );
// newFile->display("Called from SgProject::parse()");
@@ -3282,60 +3520,81 @@
delete currStks ;
#endif // USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
}
-
-
#endif
void
SgSourceFile::doSetupForConstructor(const vector<string>& argv, SgProject* project)
{
+ // Call the base class implementation!
+ SgFile::doSetupForConstructor(argv, project);
- SgFile::doSetupForConstructor(argv, project);
-
- // DQ (1/21/2008): Set the filename in the SgGlobal IR node so that the traversal to add CPP directives and comments will succeed.
+#if 0
+ // DQ (12/23/2008): This code has been moved to the function initializeGlobalScope()
+
+ // DQ (1/21/2008): Set the filename in the SgGlobal IR node so that the traversal to add CPP directives and comments will succeed.
ROSE_ASSERT (get_globalScope() != NULL);
ROSE_ASSERT(get_globalScope()->get_startOfConstruct() != NULL);
- // DQ (8/21/2008): Modified to make endOfConstruct consistant (avoids warning in AST consistancy check).
- // ROSE_ASSERT(p_root->get_endOfConstruct() == NULL);
+ // DQ (8/21/2008): Modified to make endOfConstruct consistant (avoids warning in AST consistancy check).
+ // ROSE_ASSERT(p_root->get_endOfConstruct() == NULL);
ROSE_ASSERT(get_globalScope()->get_endOfConstruct() != NULL);
- // p_root->get_file_info()->set_filenameString(p_sourceFileNameWithPath);
- // ROSE_ASSERT(p_root->get_file_info()->get_filenameString().empty() == false);
+ // p_root->get_file_info()->set_filenameString(p_sourceFileNameWithPath);
+ // ROSE_ASSERT(p_root->get_file_info()->get_filenameString().empty() == false);
+ Sg_File_Info::display_static_data("Resetting the SgGlobal startOfConstruct and endOfConstruct");
+ printf ("Resetting the SgGlobal startOfConstruct and endOfConstruct filename (p_sourceFileNameWithPath = %s) \n",p_sourceFileNameWithPath.c_str());
- get_globalScope()->get_startOfConstruct()->set_filenameString(p_sourceFileNameWithPath);
+ // DQ (12/22/2008): Added to support CPP preprocessing of Fortran files.
+ string filename = p_sourceFileNameWithPath;
+ if (get_requires_C_preprocessor() == true)
+ {
+ filename = generate_C_preprocessor_intermediate_filename(filename);
+ }
+
+ printf ("get_requires_C_preprocessor() = %s filename = %s \n",get_requires_C_preprocessor() ? "true" : "false",filename.c_str());
+
+ // get_globalScope()->get_startOfConstruct()->set_filenameString(p_sourceFileNameWithPath);
+ get_globalScope()->get_startOfConstruct()->set_filenameString(filename);
ROSE_ASSERT(get_globalScope()->get_startOfConstruct()->get_filenameString().empty() == false);
- // DQ (8/21/2008): Uncommented to make the endOfConstruct consistant (avoids warning in AST consistancy check).
- get_globalScope()->get_endOfConstruct()->set_filenameString(p_sourceFileNameWithPath);
- ROSE_ASSERT(get_globalScope()->get_endOfConstruct()->get_filenameString().empty() == false);
+ // DQ (8/21/2008): Uncommented to make the endOfConstruct consistant (avoids warning in AST consistancy check).
+ // get_globalScope()->get_endOfConstruct()->set_filenameString(p_sourceFileNameWithPath);
+ get_globalScope()->get_endOfConstruct()->set_filenameString(filename);
+ ROSE_ASSERT(get_globalScope()->get_endOfConstruct()->get_filenameString().empty() == false);
-
+ printf ("DONE: Resetting the SgGlobal startOfConstruct and endOfConstruct filename (filename = %s) \n",filename.c_str());
+ Sg_File_Info::display_static_data("DONE: Resetting the SgGlobal startOfConstruct and endOfConstruct");
+
+ // DQ (12/23/2008): These should be in the Sg_File_Info map already.
+ ROSE_ASSERT(Sg_File_Info::getIDFromFilename(get_file_info()->get_filename()) >= 0);
+ if (get_requires_C_preprocessor() == true)
+ {
+ ROSE_ASSERT(Sg_File_Info::getIDFromFilename(generate_C_preprocessor_intermediate_filename(get_file_info()->get_filename())) >= 0);
+ }
+#endif
}
void
SgBinaryFile::doSetupForConstructor(const vector<string>& argv, SgProject* project)
{
- SgFile::doSetupForConstructor(argv, project);
-
+ SgFile::doSetupForConstructor(argv, project);
}
void
SgUnknownFile::doSetupForConstructor(const vector<string>& argv, SgProject* project)
{
- SgFile::doSetupForConstructor(argv, project);
-
+ SgFile::doSetupForConstructor(argv, project);
}
void
SgFile::doSetupForConstructor(const vector<string>& argv, SgProject* project)
{
-
// JJW 10-26-2007 ensure that this object is not on the stack
preventConstructionOnStack(this);
+ // printf ("!!!!!!!!!!!!!!!!!! Inside of SgFile::doSetupForConstructor() !!!!!!!!!!!!!!! \n");
// Set the project early in the construction phase so that we can access data in
// the parent if needed (useful for template handling but also makes sure the parent is
@@ -3344,45 +3603,42 @@
if (project != NULL)
set_parent(project);
- ROSE_ASSERT (project != NULL);
-
+ ROSE_ASSERT(project != NULL);
ROSE_ASSERT(get_parent() != NULL);
-
// initalize all local variables to default values
initialization();
ROSE_ASSERT(get_parent() != NULL);
// DQ (4/21/2006): Setup the source filename as early as possible
- //setupSourceFilename(argv);
-
+ // setupSourceFilename(argv);
Rose_STL_Container<string> fileList = CommandlineProcessing::generateSourceFilenames(argv);
+ // DQ (12/23/2008): Use of this assertion will simplify the code below!
+ ROSE_ASSERT (fileList.empty() == false);
+ string sourceFilename = *(fileList.begin());
- if (fileList.empty() == false)
- {
+ // printf ("Before conversion to absolute path: sourceFilename = %s \n",sourceFilename.c_str());
+ // sourceFilename = StringUtility::getAbsolutePathFromRelativePath(sourceFilename);
+ sourceFilename = StringUtility::getAbsolutePathFromRelativePath(sourceFilename, true);
- string sourceFilename = *(fileList.begin());
+ set_sourceFileNameWithPath(sourceFilename);
- // printf ("Before conversion to absolute path: sourceFilename = %s \n",sourceFilename.c_str());
+ // printf ("In SgFile::setupSourceFilename(const vector<string>& argv): p_sourceFileNameWithPath = %s \n",get_sourceFileNameWithPath().c_str());
- // sourceFilename = StringUtility::getAbsolutePathFromRelativePath(sourceFilename);
- sourceFilename = StringUtility::getAbsolutePathFromRelativePath(sourceFilename, true);
+ set_sourceFileNameWithoutPath( ROSE::stripPathFromFileName(get_sourceFileNameWithPath().c_str()) );
- set_sourceFileNameWithPath(sourceFilename);
+#if 1
+ initializeSourcePosition(sourceFilename);
+ ROSE_ASSERT(get_file_info() != NULL);
- //printf ("In SgFile::setupSourceFilename(const vector<string>& argv): p_sourceFileNameWithPath = %s \n",get_sourceFileNameWithPath().c_str());
+ // printf ("In SgFile::doSetupForConstructor(): source position set for sourceFilename = %s \n",sourceFilename.c_str());
+#else
+ ROSE_ASSERT(get_file_info() != NULL);
+ get_file_info()->set_filenameString( get_sourceFileNameWithPath() );
+#endif
-
- set_sourceFileNameWithoutPath( ROSE::stripPathFromFileName(get_sourceFileNameWithPath().c_str()) );
- get_file_info()->set_filenameString( get_sourceFileNameWithPath() );
- }else{
- //A file should never be created without a filename so this branch should be impossible
- abort();
- }
-
-
// DQ (5/9/2007): Moved this call from above to where the file name is available so that we could include
// the filename in the label. This helps to identify the performance data with individual files where
// multiple source files are specificed on the command line.
@@ -3402,16 +3658,17 @@
// error checking
ROSE_ASSERT (argv.size() > 1);
+#if 0
// DQ (1/18/2006): Set the filename in the SgFile::p_file_info
ROSE_ASSERT(get_file_info() != NULL);
get_file_info()->set_filenameString(p_sourceFileNameWithPath);
+#endif
+ // DQ (12/23/2008): Added assertion.
+ ROSE_ASSERT(get_file_info() != NULL);
-
// DQ (5/3/2007): Added assertion.
ROSE_ASSERT (get_startOfConstruct() != NULL);
-
-
}
@@ -3568,7 +3825,10 @@
// DQ (1/6/2008): Added another test for a rose option that takes a filename
if ( argument == "-o" || // Used to specify output file to compiler
argument == "-opt" || // Used in loopProcessor
- argument == "--include" || // Used for preinclude list (to include some header files before all others, common requirement for compiler)
+ // DQ (1/13/2009): This option should only have a single leading "-", not two.
+ // argument == "--include" || // Used for preinclude list (to include some header files before all others, common requirement for compiler)
+ argument == "-include" || // Used for preinclude file list (to include some header files before all others, common requirement for compiler)
+ argument == "-isystem" || // Used for preinclude directory list (to specify include paths to be search before all others, common requirement for compiler)
argument == "-rose:output" || // Used to specify output file to ROSE
argument == "-rose:o" || // Used to specify output file to ROSE (alternative to -rose:output)
argument == "-rose:compilationPerformanceFile" || // Use to output performance information about ROSE compilation phases
@@ -3640,6 +3900,8 @@
Rose_STL_Container<string>::iterator i = argList.begin();
+ // printf ("######################### Inside of CommandlineProcessing::generateSourceFilenames() ############################ \n");
+
// skip the 0th entry since this is just the name of the program (e.g. rose)
ROSE_ASSERT(argList.size() > 0);
i++;
@@ -3722,6 +3984,8 @@
i++;
}
+ // printf ("######################### Leaving of CommandlineProcessing::generateSourceFilenames() ############################ \n");
+
return sourceFileList;
}
#endif
@@ -4098,11 +4362,9 @@
// file I/O we make this optional (selected from the command line).
// bool collectAllCommentsAndDirectives = get_collectAllCommentsAndDirectives();
- // DQ (4/19/2006): attachAllPreprocessingInfo() is now merged into the attachPreprocessingInfo() function.
- // DQ (4/6/2006): This is also the correct function to call to use Wave.
- // Markus Kowarschik: attach preprocessor directives to AST nodes
- // This uses the AST traversal and so needs to be done after the
- // call to temporaryAstFixes(), above.
+ // DQ (12/17/2008): The merging of CPP directives and comments from either the
+ // source file or including all the include files is not implemented as a single
+ // traversal and has been rewritten.
if (get_skip_commentsAndDirectives() == false)
{
if (get_verbose() > 1)
@@ -4110,8 +4372,42 @@
printf ("In SgFile::callFrontEnd(): calling attachAllPreprocessingInfo() \n");
}
- attachPreprocessingInfo(this);
+ // printf ("Secondary pass over source file = %s to comment comments and CPP directives \n",this->get_file_info()->get_filenameString().c_str());
+ // SgSourceFile* sourceFile = const_cast<SgSourceFile*>(this);
+ SgSourceFile* sourceFile = isSgSourceFile(this);
+ ROSE_ASSERT(sourceFile != NULL);
+ // Save the state of the requirement fo CPP processing (fortran only)
+ bool requiresCPP = false;
+ if (get_Fortran_only() == true)
+ {
+ requiresCPP = get_requires_C_preprocessor();
+ if (requiresCPP == true)
+ set_requires_C_preprocessor(false);
+ }
+#if 1
+ // Debugging code (eliminate use of CPP directives from source file so that we
+ // can debug the insertion of linemarkers from first phase of CPP processing.
+ if (requiresCPP == false)
+ {
+ attachPreprocessingInfo(sourceFile);
+
+ // printf ("Exiting as a test (should not be called for Fortran CPP source files) \n");
+ // ROSE_ASSERT(false);
+ }
+#else
+ // Normal path calling attachPreprocessingInfo()
+ attachPreprocessingInfo(sourceFile);
+#endif
+
+ // Reset the saved state (might not really be required at this point).
+ if (requiresCPP == true)
+ set_requires_C_preprocessor(false);
+
+#if 0
+ printf ("In SgFile::callFrontEnd(): exiting after attachPreprocessingInfo() \n");
+ ROSE_ASSERT(false);
+#endif
if (get_verbose() > 1)
{
printf ("In SgFile::callFrontEnd(): Done with attachAllPreprocessingInfo() \n");
@@ -4119,17 +4415,6 @@
}
}
- // DQ (4/11/2006): This is Lingxiao's work (new patch, since the first and second attempts didn't work)
- // to support attaching comments from all header files to the AST. It seems that both
- // attachPreprocessingInfo() and attachAllPreprocessingInfo() can be run as a mechanism to test
- // Lingxiao's work on at least the source file. Note that performance associated with collecting
- // all comments and CPP directives from header files might be a problem.
- // DQ (4/1/2006): This will have to be fixed a little later (next release)
- // DQ (3/29/2006): This is Lingxiao's work to support attaching comments from all header files to the
- // AST (the previous mechanism only extracted comments from the source file and atted them to the AST,
- // the part of the AST representing the input source file).
- // attachAllPreprocessingInfo(this,collectAllCommentsAndDirectives);
-
// display("At bottom of SgFile::callFrontEnd()");
// return the error code associated with the call to the C++ Front-end
@@ -4170,6 +4455,11 @@
bool requires_C_preprocessor = get_requires_C_preprocessor();
if (requires_C_preprocessor == true)
{
+ // If we detect that the input file requires processing via CPP (e.g. filename of form *.F??) then
+ // we generate the command to run CPP on the input file and collect the results in a file with
+ // the suffix "_postprocessed.f??". Note: instead of using CPP we use the target backend fortran
+ // compiler with the "-E" option.
+
vector<string> fortran_C_preprocessor_commandLine;
// Note: The `-traditional' and `-undef' flags are supplied to cpp by default [when used with cpp is used by gfortran],
@@ -4209,7 +4499,6 @@
printf ("Error in running cpp on Fortran code: errorCode = %d \n",errorCode);
ROSE_ASSERT(false);
}
-
#if 0
printf ("Exiting as a test ... (after calling C preprocessor)\n");
@@ -4353,12 +4642,17 @@
if (requires_C_preprocessor == true)
{
// If C preprocessing was required then we have to provide the generated filename of the preprocessed file!
+
+ // Note that since we are using gfortran to do the syntax checking, we could just
+ // hand the original file to gfortran instead of the one that we generate using CPP.
string sourceFilename = get_sourceFileNameWithPath();
string sourceFileNameOutputFromCpp = generate_C_preprocessor_intermediate_filename(sourceFilename);
fortranCommandLine.push_back(sourceFileNameOutputFromCpp);
}
else
{
+ // This will cause the original file to be used for syntax checking (instead of
+ // the CPP generated one, if one was generated).
fortranCommandLine.push_back(get_sourceFileNameWithPath());
}
#endif
@@ -4396,6 +4690,7 @@
// Build the classpath list for Java support.
const string classpath = build_classpath();
+ // This is part of debugging output to call OFP and output ehe list of parser actions that WOULD be called.
// printf ("get_output_parser_actions() = %s \n",get_output_parser_actions() ? "true" : "false");
if (get_output_parser_actions() == true)
{
@@ -4418,12 +4713,14 @@
if (requires_C_preprocessor == true)
{
// If C preprocessing was required then we have to provide the generated filename of the preprocessed file!
+ // Note that OFP has no support for CPP directives and will ignore them all.
string sourceFilename = get_sourceFileNameWithPath();
string sourceFileNameOutputFromCpp = generate_C_preprocessor_intermediate_filename(sourceFilename);
OFPCommandLine.push_back(sourceFileNameOutputFromCpp);
}
else
{
+ // Build the command line using the original file (to be used by OFP).
OFPCommandLine.push_back(get_sourceFileNameWithPath());
}
@@ -4449,7 +4746,8 @@
#endif
}
#else
- // This fails, I think because we can't call the openFortranParser_main twice.
+ // This fails, I think because we can't call the openFortranParser_main twice.
+ // DQ (11/30/2008): Does the work by Rice fix this now?
int openFortranParser_dump_argc = 0;
char** openFortranParser_dump_argv = NULL;
CommandlineProcessing::generateArgcArgvFromList(OFPCommandLine,openFortranParser_dump_argc,openFortranParser_dump_argv);
@@ -4462,6 +4760,8 @@
printf ("Exiting after parsing... \n");
exit(0);
}
+
+ // End of option handling to generate list of OPF parser actions.
}
// Option to just run the parser (not constructing the AST) and quit.
@@ -4551,12 +4851,19 @@
if (requires_C_preprocessor == true)
{
// If C preprocessing was required then we have to provide the generated filename of the preprocessed file!
- string sourceFilename = get_sourceFileNameWithPath();
+
+ // Note that the filename referenced in the Sg_File_Info objects will use the original file name and not
+ // the generated file name of the CPP generated file. This is because it gets the filename from the
+ // SgSourceFile IR node and not from the filename provided on the internal command line generated for call OFP.
+
+ string sourceFilename = get_sourceFileNameWithPath();
string sourceFileNameOutputFromCpp = generate_C_preprocessor_intermediate_filename(sourceFilename);
+
frontEndCommandLine.push_back(sourceFileNameOutputFromCpp);
}
else
{
+ // If not being preprocessed, the fortran filename is just the original input source file name.
frontEndCommandLine.push_back(get_sourceFileNameWithPath());
}
@@ -4589,22 +4896,216 @@
// Reset this global pointer after we are done (just to be safe and avoid it being used later and causing strange bugs).
OpenFortranParser_globalFilePointer = NULL;
+ // Now read the CPP directives such as "# <number> <filename> <optional numeric code>", in the generated file from CPP.
+ if (requires_C_preprocessor == true)
+ {
+ // If this was part of the processing of a CPP generated file then read the preprocessed file
+ // to get the CPP directives (different from those of the original *.F?? file) which will
+ // indicate line numbers and files where text was inserted as part of CPP processing. We
+ // mostly want to read CPP declarations of the form "# <number> <filename> <optional numeric code>".
+ // these are the only directives that will be in the CPP generated file (as I recall).
+
+ string sourceFilename = get_sourceFileNameWithPath();
+ string sourceFileNameOutputFromCpp = generate_C_preprocessor_intermediate_filename(sourceFilename);
+#if 0
+ printf ("Need to preprocess the CPP generated fortran file so that we can attribute source code statements to files: sourceFileNameOutputFromCpp = %s \n",sourceFileNameOutputFromCpp.c_str());
+#endif
+#if 1
+ // Note that the collection of CPP linemarker directives from the CPP generated file
+ // (and their insertion into the AST), should be done before the collection and
+ // insertion of the Comments and more general CPP directives from the original source
+ // file and their insertion. This will allow the correct representation of source
+ // position information to be used in the final insertion of comments and CPP directives
+ // from the original file.
+
+#if 0
+ // DQ (12/19/2008): This is now done by the AttachPreprocessingInfoTreeTrav
+
+ // List of all comments and CPP directives (collected from the generated CPP file so that we can collect the
+ // CPP directives that indicate source file boundaries of included regions of source code.
+ // E.g. # 42 "foobar.f" 2
+ ROSEAttributesList* currentListOfAttributes = new ROSEAttributesList();
+ ROSE_ASSERT(currentListOfAttributes != NULL);
+
+ // DQ (11/28/2008): This will collect the CPP directives from the generated CPP file so that
+ // we can associate parts of the AST included from different files with the correct file.
+ // Without this processing all the parts of the AST will be associated with the same generated file.
+ currentListOfAttributes->collectPreprocessorDirectivesAndCommentsForAST(sourceFileNameOutputFromCpp,ROSEAttributesList::e_C_language);
+#endif
+
+#if 0
+ printf ("Secondary pass over Fortran source file = %s to comment comments and CPP directives (might still be referencing the original source file) \n",sourceFileNameOutputFromCpp.c_str());
+ printf ("Calling attachPreprocessingInfo() \n");
+#endif
+
+ attachPreprocessingInfo(this);
+
+ // printf ("DONE: calling attachPreprocessingInfo() \n");
+
+ // DQ (12/19/2008): Now we have to do an analysis of the AST to interpret the linemarkers.
+ processCppLinemarkers();
+
+#endif
+#if 0
+ printf ("Exiting as a test ... (collect the CPP directives from the CPP generated file after building the AST)\n");
+ ROSE_ASSERT(false);
+#endif
+ }
+
+ // printf ("######################### Leaving SgSourceFile::build_Fortran_AST() ############################ \n");
+
return frontendErrorLevel;
}
#else // for !USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
-string SgSourceFile::build_classpath() {
- fprintf(stderr, "Fortran parser not supported\n");
- abort();
-}
+// DQ (11/26/2008): I am unclear why this is required (I think it was added by Rice).
+string
+SgSourceFile::build_classpath()
+ {
+ fprintf(stderr, "Fortran parser not supported \n");
+ ROSE_ASSERT(false);
+ // abort();
+ }
+
int
-SgSourceFile::build_Fortran_AST( vector<string> argv, vector<string> inputCommandLine ) {
- fprintf(stderr, "Fortran parser not supported\n");
- abort();
-}
+SgSourceFile::build_Fortran_AST( vector<string> argv, vector<string> inputCommandLine )
+ {
+ fprintf(stderr, "Fortran parser not supported \n");
+ ROSE_ASSERT(false);
+ // abort();
+ }
#endif // USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
+
+namespace SgSourceFile_processCppLinemarkers
+ {
+ // This class (AST traversal) supports the traversal of the AST required
+ // to translate the source position using the CPP linemarkers.
+
+ class LinemarkerTraversal : public AstSimpleProcessing
+ {
+ public:
+ // list<PreprocessingInfo*> preprocessingInfoStack;
+ list< pair<int,int> > sourcePositionStack;
+
+ LinemarkerTraversal( const string & sourceFilename );
+
+ void visit ( SgNode* astNode );
+ };
+ }
+
+
+SgSourceFile_processCppLinemarkers::LinemarkerTraversal::LinemarkerTraversal( const string & sourceFilename )
+ {
+ // Build an initial element on the stack so that the original source file name will be used to
+ // set the global scope (which will be traversed before we visit any statements that might have
+ // CPP directives attached (or which are CPP direcitve IR nodes).
+
+ // Get the fileId of the assocated filename
+ int fileId = Sg_File_Info::getIDFromFilename(sourceFilename);
+
+ // Assume this is line 1 (I forget why zero is not a great idea here,
+ // I expect that it causes a consstancy test to fail somewhere).
+ int line = 1;
+
+ printf ("In LinemarkerTraversal::LinemarkerTraversal(): Push initial stack entry for line = %d fileId = %d sourceFilename = %s \n",line,fileId,sourceFilename.c_str());
+
+ // Push an entry onto the stack before doing the traversal over the whole AST.
+ sourcePositionStack.push_front( pair<int,int>(line,fileId) );
+ }
+
+void
+SgSourceFile_processCppLinemarkers::LinemarkerTraversal::visit ( SgNode* astNode )
+ {
+ SgStatement* statement = isSgStatement(astNode);
+
+ // printf ("LinemarkerTraversal::visit(): statement = %p = %s \n",statement,(statement != NULL) ? statement->class_name().c_str() : "NULL");
+
+ if (statement != NULL)
+ {
+ printf ("LinemarkerTraversal::visit(): statement = %p = %s \n",statement,statement->class_name().c_str());
+
+ AttachedPreprocessingInfoType *commentOrDirectiveList = statement->getAttachedPreprocessingInfo();
+
+ printf ("LinemarkerTraversal::visit(): commentOrDirectiveList = %p (size = %zu) \n",commentOrDirectiveList,(commentOrDirectiveList != NULL) ? commentOrDirectiveList->size() : 0);
+
+ if (commentOrDirectiveList != NULL)
+ {
+ AttachedPreprocessingInfoType::iterator i = commentOrDirectiveList->begin();
+ while(i != commentOrDirectiveList->end())
+ {
+ if ( (*i)->getTypeOfDirective() == PreprocessingInfo::CpreprocessorCompilerGeneratedLinemarker )
+ {
+ // This is a CPP linemarker
+ int line = (*i)->get_lineNumberForCompilerGeneratedLinemarker();
+
+ // DQ (12/23/2008): Note this is a quoted name, we need the unquoted version!
+ std::string quotedFilename = (*i)->get_filenameForCompilerGeneratedLinemarker();
+ ROSE_ASSERT(quotedFilename[0] == '\"');
+ ROSE_ASSERT(quotedFilename[quotedFilename.length()-1] == '\"');
+ std::string filename = quotedFilename.substr(1,quotedFilename.length()-2);
+
+ std::string options = (*i)->get_optionalflagsForCompilerGeneratedLinemarker();
+
+ // Add the new filename to the static map stored in the Sg_File_Info (no action if filename is already in the map).
+ Sg_File_Info::addFilenameToMap(filename);
+
+ int fileId = Sg_File_Info::getIDFromFilename(filename);
+
+ printf ("line = %d fileId = %d quotedFilename = %s filename = %s options = %s \n",line,fileId,quotedFilename.c_str(),filename.c_str(),options.c_str());
+
+ // Just record the first linemarker so that we can test getting the filename correct.
+ if (line == 1 && sourcePositionStack.empty() == true)
+ {
+ sourcePositionStack.push_front( pair<int,int>(line,fileId) );
+ }
+ }
+
+ i++;
+ }
+ }
+
+ // ROSE_ASSERT(sourcePositionStack.empty() == false);
+ if (sourcePositionStack.empty() == false)
+ {
+ int line = sourcePositionStack.front().first;
+ int fileId = sourcePositionStack.front().second;
+
+ printf ("Setting the source position of statement = %p = %s to line = %d fileId = %d \n",statement,statement->class_name().c_str(),line,fileId);
+
+ statement->get_file_info()->set_file_id(fileId);
+ // statement->get_file_info()->set_line(line);
+
+ Sg_File_Info::display_static_data("Setting the source position of statement");
+
+ string filename = Sg_File_Info::getFilenameFromID(fileId);
+ printf ("filename = %s \n",filename.c_str());
+
+ printf ("filename = %s \n",statement->get_file_info()->get_filenameString().c_str());
+
+ ROSE_ASSERT(statement->get_file_info()->get_filename() != NULL);
+ ROSE_ASSERT(statement->get_file_info()->get_filenameString().empty() == false);
+ }
+ }
+ }
+
+
+void
+SgSourceFile::processCppLinemarkers()
+ {
+ SgSourceFile* sourceFile = const_cast<SgSourceFile*>(this);
+
+ SgSourceFile_processCppLinemarkers::LinemarkerTraversal linemarkerTraversal(sourceFile->get_sourceFileNameWithPath());
+
+ linemarkerTraversal.traverse(sourceFile,preorder);
+
+#if 0
+ printf ("Exiting as a test ... (processing linemarkers)\n");
+ ROSE_ASSERT(false);
+#endif
+ }
+
int
SgSourceFile::build_C_and_Cxx_AST( vector<string> argv, vector<string> inputCommandLine )
{
@@ -4740,7 +5241,7 @@
#ifdef USE_ROSE_OPEN_FORTRAN_PARSER_SUPPORT
frontendErrorLevel = build_Fortran_AST(argv,inputCommandLine);
#else
- fprintf(stderr, "Trying to parse a Fortran file when Fortran is not supported\n");
+ fprintf(stderr, "Trying to parse a Fortran file when Fortran is not supported (ROSE must be configured using with Java (default)) \n");
abort();
#endif
}
@@ -4756,21 +5257,23 @@
}
}
- // Uniform processing fothe error code!
+ // Uniform processing of the error code!
if ( get_verbose() > 1 )
printf ("DONE: frontend called (frontendErrorLevel = %d) \n",frontendErrorLevel);
- bool edg_failed =
+ // DQ (12/29/2008): The newer version of EDG (version 3.10 and 4.0) use different return codes for indicating an error.
+ bool frontend_failed = false;
#ifdef ROSE_USE_NEW_EDG_INTERFACE
- frontendErrorLevel != 0
+ // Any non-zero value indicates an error.
+ frontend_failed = (frontendErrorLevel != 0);
#else
- frontendErrorLevel > 3
+ // non-zero error code can mean warnings were produced, values greater than 3 indicate errors.
+ frontend_failed = (frontendErrorLevel > 3);
#endif
- ;
// If we had any errors reported by the frontend then quite now
- if (edg_failed)
+ if (frontend_failed)
{
// cout << "Errors in Processing: (frontendErrorLevel > 3)" << endl;
if ( get_verbose() > 1 )
@@ -4790,7 +5293,7 @@
else
{
// Exit because there are errors in the input program
- cout << "Errors in Processing: (edg_failed)" << endl;
+ cout << "Errors in Processing: (frontend_failed)" << endl;
ROSE_ABORT();
}
}
@@ -4932,6 +5435,12 @@
// printf ("Selected compiler = %s \n",compilerNameString.c_str());
+#ifdef ROSE_USE_NEW_EDG_INTERFACE
+ // DQ (1/12/2009): Allow in internal indicator that EDG version 3.10 or 4.0 (or greater)
+ // is in use to be properly passed on the compilation of the generated code.
+ compilerNameString.push_back("-DROSE_USE_NEW_EDG_INTERFACE");
+#endif
+
// Since we need to do this often, support is provided in the utility_functions.C
// and we can simplify this code.
std::string currentDirectory = getWorkingDirectory();
@@ -5912,7 +6421,7 @@
return value;
}
- namespace SgNode_depthOfSubtree
+namespace SgNode_depthOfSubtree
{
// This class (AST traversal) could not be defined in the function SgNode::depthOfSubtree()
// So I have constructed a namespace for this class to be implemented outside of the function.
@@ -6012,3 +6521,75 @@
return returnList;
}
+// DQ (11/23/2008): This is a static function
+SgC_PreprocessorDirectiveStatement*
+SgC_PreprocessorDirectiveStatement::createDirective ( PreprocessingInfo* currentPreprocessingInfo )
+ {
+ // This is the new factory interface to build CPP directives as IR nodes.
+ PreprocessingInfo::DirectiveType directive = currentPreprocessingInfo->getTypeOfDirective();
+
+ // SgC_PreprocessorDirectiveStatement* cppDirective = new SgEmptyDirectiveStatement();
+ SgC_PreprocessorDirectiveStatement* cppDirective = NULL;
+
+ switch(directive)
+ {
+ case PreprocessingInfo::CpreprocessorUnknownDeclaration:
+ {
+ // I think this is an error...
+ // locatedNode->addToAttachedPreprocessingInfo(currentPreprocessingInfoPtr);
+ printf ("Error: directive == PreprocessingInfo::CpreprocessorUnknownDeclaration \n");
+ ROSE_ASSERT(false);
+ break;
+ }
+
+ case PreprocessingInfo::C_StyleComment:
+ case PreprocessingInfo::CplusplusStyleComment:
+ case PreprocessingInfo::FortranStyleComment:
+ case PreprocessingInfo::CpreprocessorBlankLine:
+ case PreprocessingInfo::ClinkageSpecificationStart:
+ case PreprocessingInfo::ClinkageSpecificationEnd:
+ {
+ printf ("Error: these cases chould not generate a new IR node (directiveTypeName = %s) \n",PreprocessingInfo::directiveTypeName(directive).c_str());
+ ROSE_ASSERT(false);
+ break;
+ }
+
+ case PreprocessingInfo::CpreprocessorIncludeDeclaration: { cppDirective = new SgIncludeDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorIncludeNextDeclaration: { cppDirective = new SgIncludeNextDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorDefineDeclaration: { cppDirective = new SgDefineDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorUndefDeclaration: { cppDirective = new SgUndefDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorIfdefDeclaration: { cppDirective = new SgIfdefDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorIfndefDeclaration: { cppDirective = new SgIfndefDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorIfDeclaration: { cppDirective = new SgIfDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorDeadIfDeclaration: { cppDirective = new SgDeadIfDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorElseDeclaration: { cppDirective = new SgElseDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorElifDeclaration: { cppDirective = new SgElseifDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorEndifDeclaration: { cppDirective = new SgEndifDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorLineDeclaration: { cppDirective = new SgLineDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorErrorDeclaration: { cppDirective = new SgErrorDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorWarningDeclaration: { cppDirective = new SgWarningDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorEmptyDeclaration: { cppDirective = new SgEmptyDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorIdentDeclaration: { cppDirective = new SgIdentDirectiveStatement(); break; }
+ case PreprocessingInfo::CpreprocessorCompilerGeneratedLinemarker: { cppDirective = new SgLinemarkerDirectiveStatement(); break; }
+
+ default:
+ {
+ printf ("Error: directive not handled directiveTypeName = %s \n",PreprocessingInfo::directiveTypeName(directive).c_str());
+ ROSE_ASSERT(false);
+ }
+ }
+
+ ROSE_ASSERT(cppDirective != NULL);
+
+ cppDirective->set_directiveString(currentPreprocessingInfo->getString());
+
+ // Set the defining declaration to be a self reference...
+ cppDirective->set_definingDeclaration(cppDirective);
+
+ // Build source position information...
+ cppDirective->set_startOfConstruct(new Sg_File_Info(*(currentPreprocessingInfo->get_file_info())));
+ cppDirective->set_endOfConstruct(new Sg_File_Info(*(currentPreprocessingInfo->get_file_info())));
+
+ return cppDirective;
+ }
+
Modified: branches/imperial/src/midend/astDiagnostics/AstConsistencyTests.C
===================================================================
--- branches/imperial/src/midend/astDiagnostics/AstConsistencyTests.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/midend/astDiagnostics/AstConsistencyTests.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -873,6 +873,21 @@
break;
}
+#ifdef ROSE_USE_EDG_VERSION_4
+ // DQ (12/31/2008): In EDG 4.0, the translation of a function call such as "(*callback_lookup)();"
+ // can cause the functionExpression to be a wider number of IR nodes (e.g. SgVarRefExp).
+ // See test2007_94.C for an example.
+ case V_SgVarRefExp:
+ {
+ SgVarRefExp* varRefExp = isSgVarRefExp(functionExpression);
+ ROSE_ASSERT(varRefExp != NULL);
+
+ // Unclear what should be checked here, for now allow this as an acceptable case.
+ printf ("Warning: EDG 4.0 specific case, found unusual case of SgVarRefExp returned from SgFunctionCallExp::get_function() member function \n");
+
+ break;
+ }
+#endif
default:
{
printf ("Error case default in switch (functionExpression = %s) \n",functionExpression->sage_class_name());
@@ -921,6 +936,13 @@
break;
}
+#ifdef ROSE_USE_NEW_EDG_INTERFACE
+ case V_SgPartialFunctionType:
+ {
+ // This case is only present in the new EDG/Sage interface (demonstrated by gzip.c)
+ break;
+ }
+#endif
default:
{
printf ("Error case default in switch (callType = %s) \n",callType->sage_class_name());
Modified: branches/imperial/src/midend/astProcessing/AstDOTGeneration.C
===================================================================
--- branches/imperial/src/midend/astProcessing/AstDOTGeneration.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/src/midend/astProcessing/AstDOTGeneration.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -240,6 +240,22 @@
nodelabel += string("\\n") + name;
}
+ // DQ (11/29/2008): Output the directives in the label of the IR node.
+ SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node);
+ if (preprocessorDirective != NULL)
+ {
+ string s = preprocessorDirective->get_directiveString();
+
+ // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables.
+ while (s.find("\"") != string::npos)
+ {
+ s.replace(s.find("\""),1,"\'");
+ }
+
+ if (s.empty() == false)
+ nodelabel += string("\\n") + s;
+ }
+
nodelabel += additionalNodeInfo(node);
// DQ (11/1/2003) added mechanism to add additional options (to add color, etc.)
Modified: branches/imperial/tests/CompilerOptionsTests/Makefile.am
===================================================================
--- branches/imperial/tests/CompilerOptionsTests/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/tests/CompilerOptionsTests/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -4,7 +4,7 @@
# SUBDIRS = A++Code
SUBDIRS = \
testOutputFileOption testForSpuriousOutput testCpreprocessorOption \
- testHeaderFileOutput testFileNamesAndExtensions
+ testHeaderFileOutput testFileNamesAndExtensions testGnuOptions
# This rule is run after automake's internal check rule (which we don't want to use)
check-local:
Copied: branches/imperial/tests/CompilerOptionsTests/testGnuOptions (from rev 188, trunk/tests/CompilerOptionsTests/testGnuOptions)
Deleted: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am
===================================================================
--- trunk/tests/CompilerOptionsTests/testGnuOptions/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,37 +0,0 @@
-include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs
-
-## Add bugs to this line as they are fixed so that they can be used as test problems
-## At least we should not reintroduce these fixed bugs again later.
-TESTCODES = test-includeOption.C test-isystemOption.C
-
-# Build the list of object files
-TEST_Objects = ${TESTCODES:.C=.o}
-
-TEST_TRANSLATOR = $(top_builddir)/tests/testTranslator $(ROSE_FLAGS)
-
-# This rule is run after automake's internal check rule (which we don't want to use)
-check-local:
- @echo "#################################################"
- @echo " Test use of GNU options ..."
- @echo "#################################################"
- @$(MAKE) testUseOfGnuOptions
- @echo "*****************************************************************************************************************"
- @echo "****** ROSE/tests/CompilerOptionTests/testGnuOptions: make check rule complete (terminated normally) ******"
- @echo "*****************************************************************************************************************"
-
-testUseOfGnuOptions: $(srcdir)/test-includeOption.C $(srcdir)/test-isystemOption.C
-# If -include is not handled properly by ROSE this will fail.
- $(TEST_TRANSLATOR) -rose:verbose 0 -include $(srcdir)/testOptions.h -c $(srcdir)/test-includeOption.C
-# Since the default is to search the source file directory, this is not a great test
- $(TEST_TRANSLATOR) -rose:verbose 0 -isystem $(srcdir) -c $(srcdir)/test-isystemOption.C
-# The default is to search the source file directory, so move the source file to
-# be local and specify the path to the include file using -isystem. If -isystem
-# is not handled properly by ROSE then this test will fail.
- cp $(srcdir)/test-isystemOption.C local_test-isystemOption.C
- $(TEST_TRANSLATOR) -rose:verbose 0 -isystem $(srcdir) -c local_test-isystemOption.C
-
-EXTRA_DIST = $(TESTCODES) testOptions.h
-
-clean-local:
- rm -f *.o rose_*.C *.C.pdf *.dot core local_test-isystemOption.C
-
Copied: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am (from rev 188, trunk/tests/CompilerOptionsTests/testGnuOptions/Makefile.am)
===================================================================
--- branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am (rev 0)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,37 @@
+include $(top_srcdir)/config/Makefile.for.ROSE.includes.and.libs
+
+## Add bugs to this line as they are fixed so that they can be used as test problems
+## At least we should not reintroduce these fixed bugs again later.
+TESTCODES = test-includeOption.C test-isystemOption.C
+
+# Build the list of object files
+TEST_Objects = ${TESTCODES:.C=.o}
+
+TEST_TRANSLATOR = $(top_builddir)/tests/testTranslator $(ROSE_FLAGS)
+
+# This rule is run after automake's internal check rule (which we don't want to use)
+check-local:
+ @echo "#################################################"
+ @echo " Test use of GNU options ..."
+ @echo "#################################################"
+ @$(MAKE) testUseOfGnuOptions
+ @echo "*****************************************************************************************************************"
+ @echo "****** ROSE/tests/CompilerOptionTests/testGnuOptions: make check rule complete (terminated normally) ******"
+ @echo "*****************************************************************************************************************"
+
+testUseOfGnuOptions: $(srcdir)/test-includeOption.C $(srcdir)/test-isystemOption.C
+# If -include is not handled properly by ROSE this will fail.
+ $(TEST_TRANSLATOR) -rose:verbose 0 -include $(srcdir)/testOptions.h -c $(srcdir)/test-includeOption.C
+# Since the default is to search the source file directory, this is not a great test
+ $(TEST_TRANSLATOR) -rose:verbose 0 -isystem $(srcdir) -c $(srcdir)/test-isystemOption.C
+# The default is to search the source file directory, so move the source file to
+# be local and specify the path to the include file using -isystem. If -isystem
+# is not handled properly by ROSE then this test will fail.
+ cp $(srcdir)/test-isystemOption.C local_test-isystemOption.C
+ $(TEST_TRANSLATOR) -rose:verbose 0 -isystem $(srcdir) -c local_test-isystemOption.C
+
+EXTRA_DIST = $(TESTCODES) testOptions.h
+
+clean-local:
+ rm -f *.o rose_*.C *.C.pdf *.dot core local_test-isystemOption.C
+
Deleted: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C
===================================================================
--- trunk/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,14 +0,0 @@
-
-// Put a variable into a header file and force
-// it to be included via the GNU -include option.
-// #include "testOptions.h"
-
-int
-main ()
- {
- // Note that "x" is defined in "testOptions.h" which
- // is preincluded using the GNU "-include" option.
- x = 0;
-
- return 0;
- }
Copied: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C (from rev 188, trunk/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C)
===================================================================
--- branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C (rev 0)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-includeOption.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,14 @@
+
+// Put a variable into a header file and force
+// it to be included via the GNU -include option.
+// #include "testOptions.h"
+
+int
+main ()
+ {
+ // Note that "x" is defined in "testOptions.h" which
+ // is preincluded using the GNU "-include" option.
+ x = 0;
+
+ return 0;
+ }
Deleted: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C
===================================================================
--- trunk/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -1,15 +0,0 @@
-
-// Put a variable into a header file and force
-// it to be included via the GNU -isystem option.
-#include "testOptions.h"
-
-int
-main ()
- {
- // Note that "x" is defined in "testOptions.h" which
- // is explicitly included above but for which the include
- // path is specified using the GNU "-isystem" option.
- x = 0;
-
- return 0;
- }
Copied: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C (from rev 188, trunk/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C)
===================================================================
--- branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C (rev 0)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/test-isystemOption.C 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1,15 @@
+
+// Put a variable into a header file and force
+// it to be included via the GNU -isystem option.
+#include "testOptions.h"
+
+int
+main ()
+ {
+ // Note that "x" is defined in "testOptions.h" which
+ // is explicitly included above but for which the include
+ // path is specified using the GNU "-isystem" option.
+ x = 0;
+
+ return 0;
+ }
Deleted: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h
===================================================================
--- trunk/tests/CompilerOptionsTests/testGnuOptions/testOptions.h 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -1 +0,0 @@
-int x;
Copied: branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h (from rev 188, trunk/tests/CompilerOptionsTests/testGnuOptions/testOptions.h)
===================================================================
--- branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h (rev 0)
+++ branches/imperial/tests/CompilerOptionsTests/testGnuOptions/testOptions.h 2009-01-14 15:08:15 UTC (rev 189)
@@ -0,0 +1 @@
+int x;
Modified: branches/imperial/tests/roseTests/astQueryTests/Makefile.am
===================================================================
--- branches/imperial/tests/roseTests/astQueryTests/Makefile.am 2009-01-14 08:35:57 UTC (rev 188)
+++ branches/imperial/tests/roseTests/astQueryTests/Makefile.am 2009-01-14 15:08:15 UTC (rev 189)
@@ -42,11 +42,14 @@
TESTCODE_INCLUDES =
# DQ (7/12/2004): Modified to run with make -j4 options
+# DQ (12/24/2008): Removed use of $(INCLUDES) since this now causes
+# the -isystem option to be passed to ROSE which does not understand
+# it (processed include directory as a file).
$(TEST_Objects): $(TESTCODES) testQuery
@echo "Compiling test code using $(TEST_TRANSLATOR) ..."
- $(TEST_TRANSLATOR_1) $(INCLUDES) $(TESTCODE_INCLUDES) -c $(srcdir)/$(@:.o=.C) -o $(@:.o=)
- $(TEST_TRANSLATOR_2) $(INCLUDES) $(TESTCODE_INCLUDES) -c $(srcdir)/$(@:.o=.C) -o $(@:.o=)
- $(TEST_TRANSLATOR_3) $(INCLUDES) $(TESTCODE_INCLUDES) -c $(srcdir)/$(@:.o=.C) -o $(@:.o=)
+ $(TEST_TRANSLATOR_1) $(TESTCODE_INCLUDES) -c $(srcdir)/$(@:.o=.C) -o $(@:.o=)
+ $(TEST_TRANSLATOR_2) $(TESTCODE_INCLUDES) -c $(srcdir)/$(@:.o=.C) -o $(@:.o=)
+ $(TEST_TRANSLATOR_3) $(TESTCODE_INCLUDES) -c $(srcdir)/$(@:.o=.C) -o $(@:.o=)
@echo "Running resulting executable ..."
# ./$(@:.o=)
More information about the Rose-commits
mailing list