diff --git a/.gitignore b/.gitignore index 09559f81..76f523fe 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ gcc-c-api/gcc-tree.h gcc-c-api/gcc-type.h gcc-c-api/gcc-variable.h gcc-with-python.1.gz -print-gcc-version # Generated by Sphinx docs/_build diff --git a/Makefile b/Makefile index 6ad5ff40..6838ebd4 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ .PHONY: all clean debug dump_gimple plugin show-ssa tarball \ test-suite testcpychecker testcpybuilder \ - man + man install PLUGIN_SOURCE_FILES= \ gcc-python.c \ @@ -55,12 +55,14 @@ PLUGIN_GENERATED_SOURCE_FILES:= \ autogenerated-tree.c \ autogenerated-variable.c +TARGET_GCC:=$(CC) + PLUGIN_OBJECT_SOURCE_FILES:= $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES)) PLUGIN_OBJECT_GENERATED_FILES:= $(patsubst %.c,%.o,$(PLUGIN_GENERATED_SOURCE_FILES)) PLUGIN_OBJECT_FILES:= $(PLUGIN_OBJECT_SOURCE_FILES) $(PLUGIN_OBJECT_GENERATED_FILES) -GCCPLUGINS_DIR:= $(shell $(CC) --print-file-name=plugin) +GCCPLUGINS_DIR:= $(shell $(TARGET_GCC) --print-file-name=plugin) -GENERATOR_DEPS=cpybuilder.py wrapperbuilder.py print-gcc-version +GENERATOR_DEPS=cpybuilder.py wrapperbuilder.py autogenerated-gcc-version # The plugin supports both Python 2 and Python 3 # @@ -102,7 +104,7 @@ PYTHON_LIBS=$(shell $(PYTHON_CONFIG) --libs) # Support having multiple named plugins # e.g. "python2.7" "python3.2mu" "python 3.2dmu" etc: -PLUGIN_NAME := python +PLUGIN_NAME := $(PYTHON) PLUGIN_DSO := $(PLUGIN_NAME).so PLUGIN_DIR := $(PLUGIN_NAME) @@ -114,8 +116,10 @@ CPPFLAGS+= -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -I. # Allow user to pick optimization, choose whether warnings are fatal, # and choose debugging information level. CFLAGS?=-O2 -Werror -g +CXXFLAGS?=-O2 -Werror -g # Force these settings CFLAGS+= -fPIC -fno-strict-aliasing -Wall +CXXFLAGS+= -fPIC -fno-strict-aliasing -Wall LIBS+= $(PYTHON_LIBS) ifneq "$(PLUGIN_PYTHONPATH)" "" CPPFLAGS+= -DPLUGIN_PYTHONPATH='"$(PLUGIN_PYTHONPATH)"' @@ -132,7 +136,21 @@ plugin: autogenerated-config.h $(PLUGIN_DSO) # When running the plugin from a working copy, use LD_LIBARY_PATH=gcc-c-api # so that the plugin can find its libgcc-c-api.so there # -INVOCATION_ENV_VARS := LD_LIBRARY_PATH=gcc-c-api CC=$(CC) +INVOCATION_ENV_VARS := LD_LIBRARY_PATH=gcc-c-api CC="$(TARGET_GCC)" + +, := , + +define run-cc + set -- $1; \ + read gcc_cxx < "autogenerated-EXTRA_CFLAGS.txt"; \ + if [ "$$gcc_cxx" = '-x c' ]; then \ + $(if $2,$2,$(CC) $(CFLAGS)) "$$@"; \ + elif [ "$$gcc_cxx" = '-x c++' ]; then \ + $(if $3,$3,$(CXX) $(CXXFLAGS)) "$$@"; \ + else \ + false; \ + fi +endef # When installing, both the plugin and libgcc-c-api.so will be installed to # $(GCCPLUGINS_DIR), so we give the plugin an RPATH of $(GCCPLUGINS_DIR) @@ -140,41 +158,48 @@ INVOCATION_ENV_VARS := LD_LIBRARY_PATH=gcc-c-api CC=$(CC) # multiple GCCs installed) # $(PLUGIN_DSO): $(PLUGIN_OBJECT_FILES) $(LIBGCC_C_API_SO) - $(CC) \ - $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) \ + $(call run-cc, \ -shared \ $(PLUGIN_OBJECT_FILES) \ - -o $@ \ $(LIBS) \ - -lgcc-c-api -Lgcc-c-api -Wl,-rpath=$(GCCPLUGINS_DIR) + $(OUTPUT_OPTION) \ + -lgcc-c-api -Lgcc-c-api -Wl$(,)-rpath=$(GCCPLUGINS_DIR), \ + $(LINK.c), \ + $(LINK.cpp) \ + ) + +.PHONY: gcc-c-api/phony-stamp-gcc-api +gcc-c-api/phony-stamp-gcc-api: autogenerated-EXTRA_CFLAGS.txt autogenerated-gcc-version + $(MAKE) -C gcc-c-api libgcc-c-api.so CC="$(CC)" CXX="$(CXX)" TARGET_GCC="$(TARGET_GCC)" -$(LIBGCC_C_API_SO): - cd gcc-c-api && make libgcc-c-api.so CC=$(CC) +$(LIBGCC_C_API_SO): gcc-c-api/phony-stamp-gcc-api $(PLUGIN_OBJECT_GENERATED_FILES): CPPFLAGS+= $(if $(srcdir),-I$(srcdir)) # This is the standard .c->.o recipe, but it needs to be stated # explicitly to support the case that $(srcdir) is not blank. -$(PLUGIN_OBJECT_SOURCE_FILES) $(PLUGIN_OBJECT_GENERATED_FILES): %.o: $(srcdir)%.c autogenerated-config.h $(srcdir)gcc-python.h $(LIBGCC_C_API_SO) autogenerated-EXTRA_CFLAGS.txt - $(COMPILE.c) $(shell cat autogenerated-EXTRA_CFLAGS.txt) $(OUTPUT_OPTION) $< - -print-gcc-version: print-gcc-version.c autogenerated-EXTRA_CFLAGS.txt - $(CC) \ - $(CPPFLAGS) $(CFLAGS) \ - $(shell cat autogenerated-EXTRA_CFLAGS.txt) \ - -o $@ \ - $< +$(PLUGIN_OBJECT_SOURCE_FILES) $(PLUGIN_OBJECT_GENERATED_FILES): %.o: $(srcdir)%.c autogenerated-config.h $(srcdir)gcc-python.h $(LIBGCC_C_API_SO) autogenerated-EXTRA_CFLAGS.txt autogenerated-gcc-version + read gcc_version < autogenerated-gcc-version || exit 1; $(call run-cc,-DTARGET_GCC_VERSION="$$gcc_version" $< $(OUTPUT_OPTION),$(COMPILE.c),$(COMPILE.cpp)) + +# Use a long variable name to avoid unwanted matches. Add an explicit +# -x c since gcc requires a language specifier when processing stdin. +# C and C++ print the same version, so skip +# autogenerated-EXTRA_CFLAGS.txt. +autogenerated-gcc-version: + echo gcc_version_major_minor= __GNUC__ __GNUC_MINOR__ | \ + $(TARGET_GCC) -x c -E - | \ + { awk '/^gcc_version_major_minor=/ { print ($$2*1000)+$$3; exit 0; }' > "$@.part" && test -s "$@.part" && mv -f "$@.part" "$@"; } || { rc=$$?; $(RM) "$@.part"; exit $$rc; } clean: $(RM) *.so *.o gcc-c-api/*.o autogenerated* $(RM) -r docs/_build $(RM) -f gcc-with-$(PLUGIN_NAME).1 gcc-with-$(PLUGIN_NAME).1.gz - $(RM) -f print-gcc-version - cd gcc-c-api && make clean + $(RM) -f autogenerated-gcc-version + $(MAKE) -C gcc-c-api clean CC="$(CC)" TARGET_GCC="$(TARGET_GCC)" find tests -name "*.o" -delete autogenerated-config.h: $(addprefix $(srcdir),generate-config-h.py configbuilder.py) - $(PYTHON) $< -o $@ --gcc="$(CC)" --plugindir="$(GCCPLUGINS_DIR)" + $(PYTHON) $< -o $@ --gcc="$(TARGET_GCC)" --plugindir="$(GCCPLUGINS_DIR)" autogenerated-%.txt: $(srcdir)%.txt.in $(CPP) $(CPPFLAGS) -x c-header $^ -o $@ @@ -186,11 +211,16 @@ autogenerated-EXTRA_CFLAGS.txt: autogenerated-config.h # autogenerated-casts.h is a byproduct of making autogenerated-casts.c autogenerated-casts.h: autogenerated-casts.c -$(PLUGIN_GENERATED_SOURCE_FILES): autogenerated-%.c: $(addprefix $(srcdir),generate-%-c.py $(GENERATOR_DEPS)) - $(PYTHON) $< > $@ +# Generate to a temporary name, so that a failure in the script does not +# leave behind an up-to-date incomplete file. +$(filter-out autogenerated-casts.c,$(PLUGIN_GENERATED_SOURCE_FILES)): autogenerated-%.c: $(addprefix $(srcdir),generate-%-c.py $(GENERATOR_DEPS)) + $(PYTHON) $< > "$@.part" || { rc=$$?; $(RM) "$@.part"; exit $$rc; } + mv -f "$@.part" "$@" -autogenerated-casts.c: autogenerated-gimple-types.txt autogenerated-tree-types.txt autogenerated-rtl-types.txt $(srcdir)generate-casts-c.py - $(PYTHON) $(srcdir)generate-casts-c.py autogenerated-casts.c autogenerated-casts.h +autogenerated-casts.c: GENERATED_FILES:=autogenerated-casts.c autogenerated-casts.h +autogenerated-casts.c: $(srcdir)generate-casts-c.py autogenerated-gimple-types.txt autogenerated-tree-types.txt autogenerated-rtl-types.txt + $(PYTHON) $< $(addsuffix .part,$(GENERATED_FILES)) || { rc=$$?; $(RM) $(addsuffix .part,$(GENERATED_FILES)); exit $$rc; } + : $(foreach f,$(GENERATED_FILES),&& mv -f "$f.part" "$f") autogenerated-gimple.c: autogenerated-gimple-types.txt autogenerated-tree-types.txt autogenerated-rtl-types.txt $(srcdir)maketreetypes.py autogenerated-tree.c: autogenerated-tree-types.txt $(srcdir)maketreetypes.py @@ -203,19 +233,15 @@ mandir=/usr/share/man UpperPluginName = $(shell $(PYTHON) -c"print('$(PLUGIN_NAME)'.upper())") docs/_build/man/gcc-with-python.1: docs/gcc-with-python.rst - cd docs && $(MAKE) man + $(MAKE) -C docs man gcc-with-$(PLUGIN_NAME).1: docs/_build/man/gcc-with-python.1 # Fixup the generic manpage for this build: - cp docs/_build/man/gcc-with-python.1 gcc-with-$(PLUGIN_NAME).1 sed \ - -i \ -e"s|gcc-with-python|gcc-with-$(PLUGIN_NAME)|g" \ - gcc-with-$(PLUGIN_NAME).1 - sed \ - -i \ -e"s|GCC-WITH-PYTHON|GCC-WITH-$(UpperPluginName)|g" \ - gcc-with-$(PLUGIN_NAME).1 + < $< \ + > $@ gcc-with-$(PLUGIN_NAME).1.gz: gcc-with-$(PLUGIN_NAME).1 rm -f gcc-with-$(PLUGIN_NAME).1.gz @@ -226,7 +252,7 @@ man: gcc-with-$(PLUGIN_NAME).1.gz install: $(PLUGIN_DSO) gcc-with-$(PLUGIN_NAME).1.gz mkdir -p $(DESTDIR)$(GCCPLUGINS_DIR) - cd gcc-c-api && $(MAKE) install + $(MAKE) -C gcc-c-api install cp $(PLUGIN_DSO) $(DESTDIR)$(GCCPLUGINS_DIR) @@ -236,21 +262,17 @@ install: $(PLUGIN_DSO) gcc-with-$(PLUGIN_NAME).1.gz # Create "gcc-with-" support script: mkdir -p $(DESTDIR)$(bindir) - install -m 755 gcc-with-python $(DESTDIR)/$(bindir)/gcc-with-$(PLUGIN_NAME) # Fixup the reference to the plugin in that script, from being expressed as # a DSO filename with a path (for a working copy) to a name of an installed # plugin within GCC's search directory: - sed \ - -i \ - -e"s|-fplugin=[^ ]*|-fplugin=$(PLUGIN_NAME)|" \ - $(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME) - - # Fixup the plugin name within -fplugin-arg-PLUGIN_NAME-script to match the + # Fixup the plugin name within -fplugin-arg-PLUGIN_NAME-script to match the # name for this specific build: sed \ - -i \ + -e"s|-fplugin=[^ ]*|-fplugin=$(PLUGIN_NAME)|" \ -e"s|-fplugin-arg-python-script|-fplugin-arg-$(PLUGIN_NAME)-script|" \ - $(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME) + < gcc-with-python \ + > $(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME) + chmod 755 $(DESTDIR)$(bindir)/gcc-with-$(PLUGIN_NAME) mkdir -p $(DESTDIR)$(mandir)/man1 cp gcc-with-$(PLUGIN_NAME).1.gz $(DESTDIR)$(mandir)/man1 @@ -266,7 +288,7 @@ TEST_CFLAGS= \ # A catch-all test for quick experimentation with the API: test: plugin - $(INVOCATION_ENV_VARS) $(CC) -v $(TEST_CFLAGS) $(CURDIR)/test.c + $(INVOCATION_ENV_VARS) $(TARGET_GCC) -v $(TEST_CFLAGS) $(CURDIR)/test.c # Selftest for the cpychecker.py code: testcpychecker: plugin @@ -277,10 +299,10 @@ testcpybuilder: $(PYTHON) testcpybuilder.py -v dump_gimple: - $(CC) -fdump-tree-gimple $(CURDIR)/test.c + $(TARGET_GCC) -fdump-tree-gimple $(CURDIR)/test.c debug: plugin - $(INVOCATION_ENV_VARS) $(CC) -v $(TEST_CFLAGS) $(CURDIR)/test.c + $(INVOCATION_ENV_VARS) $(TARGET_GCC) -v $(TEST_CFLAGS) $(CURDIR)/test.c # A simple demo, to make it easy to demonstrate the cpychecker: demo: plugin @@ -289,14 +311,14 @@ demo: plugin json-examples: plugin $(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-cpychecker -I/usr/include/python2.7 -c libcpychecker_html/test/example1/bug.c -test-suite: plugin print-gcc-version +test-suite: plugin autogenerated-gcc-version $(INVOCATION_ENV_VARS) $(PYTHON) run-test-suite.py show-ssa: plugin $(INVOCATION_ENV_VARS) $(srcdir)./gcc-with-python examples/show-ssa.py test.c html: docs/tables-of-passes.rst docs/passes.svg - cd docs && $(MAKE) html + $(MAKE) -C docs $@ # We commit this generated file to SCM to allow the docs to be built without # needing to build the plugin: diff --git a/cpybuilder.py b/cpybuilder.py index 8d8cab7f..2292bfd5 100644 --- a/cpybuilder.py +++ b/cpybuilder.py @@ -32,6 +32,12 @@ def nullable_ptr(ptr): else: return 'NULL' +def nullable_strptr(s,caststr='char*'): + if s: + return '(%s)"%s"' % (caststr,s) + else: + return 'NULL' + def simple_unaryfunc(identifier, typename, c_expression): """Define a simple unaryfunc, using a specifc PyObject subclass""" self.add_defn("static PyObject *\n" + @@ -97,7 +103,7 @@ def c_defn(self): result = ' {(char*)"%s",\n' % self.name result += ' (getter)%s,\n' % nullable_ptr(self.get) result += ' (setter)%s,\n' % nullable_ptr(self.set) - result += ' (char*)"%s",\n' % nullable_ptr(self.doc) + result += ' %s,\n' % nullable_strptr(self.doc) result += ' %s},\n' % nullable_ptr(self.closure) return result diff --git a/gcc-c-api/Makefile b/gcc-c-api/Makefile index 625002dc..d2e2d623 100644 --- a/gcc-c-api/Makefile +++ b/gcc-c-api/Makefile @@ -15,7 +15,7 @@ # along with this program. If not, see # . -.PHONY: all clean check-api +.PHONY: all clean check-api install HANDWRITTEN_C_FILES = \ gcc-callgraph.c \ @@ -70,7 +70,9 @@ GENERATED_HEADERS:= \ gcc-type.h \ gcc-variable.h -GCCPLUGINS_DIR:= $(shell $(CC) --print-file-name=plugin) +TARGET_GCC:=$(CC) + +GCCPLUGINS_DIR:= $(shell $(TARGET_GCC) --print-file-name=plugin) LIBGCC_C_API_SO := libgcc-c-api.so @@ -78,18 +80,32 @@ CPPFLAGS+= -I$(GCCPLUGINS_DIR)/include -I$(GCCPLUGINS_DIR)/include/c-family -I. # Allow user to pick optimization, choose whether warnings are fatal, # and choose debugging information level. CFLAGS?=-O2 -Werror -g +CXXFLAGS?=-O2 -Werror -g # Force these settings CFLAGS+= -fPIC -fno-strict-aliasing -Wall +CXXFLAGS+= -fPIC -fno-strict-aliasing -Wall + +define run-cc + set -- $1; \ + read gcc_cxx < "../autogenerated-EXTRA_CFLAGS.txt"; \ + if [ "$$gcc_cxx" = '-x c' ]; then \ + $(if $2,$2,$(CC) $(CFLAGS)) "$$@"; \ + elif [ "$$gcc_cxx" = '-x c++' ]; then \ + $(if $3,$3,$(CXX) $(CXXFLAGS)) "$$@"; \ + else \ + false; \ + fi +endef all: $(LIBGCC_C_API_SO) $(LIBGCC_C_API_SO): $(OBJECT_FILES) - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared $^ -o $@ $(LIBS) + $(call run-cc,-shared $^ $(OUTPUT_OPTION) $(LIBS),$(LINK.c),$(LINK.cpp)) # This is the standard .c->.o recipe, but it needs to be stated # explicitly to support the case that $(srcdir) is not blank. -$(OBJECT_FILES): %.o: $(srcdir)%.c $(GENERATED_HEADERS) ../autogenerated-EXTRA_CFLAGS.txt - $(COMPILE.c) $(shell cat ../autogenerated-EXTRA_CFLAGS.txt) $(OUTPUT_OPTION) $< +$(OBJECT_FILES): %.o: $(srcdir)%.c $(GENERATED_HEADERS) ../autogenerated-EXTRA_CFLAGS.txt ../autogenerated-gcc-version + read gcc_version < ../autogenerated-gcc-version || exit 1; $(call run-cc,-DTARGET_GCC_VERSION="$$gcc_version" $< $(OUTPUT_OPTION),$(COMPILE.c),$(COMPILE.cpp)) autogenerated-casts.c: $(SOURCE_XML) xmltypes.py generate-casts-c.py $(PYTHON) generate-casts-c.py $@ @@ -104,8 +120,19 @@ install: $(LIBGCC_C_API_SO) # The python interpreter to use: PYTHON=python -$(GENERATED_HEADERS): $(SOURCE_XML) xml-to-h.py xmltypes.py +# Describe how to build the first generated header +$(firstword $(GENERATED_HEADERS)): $(PYTHON) xml-to-h.py +# Make all generated headers depend on the true inputs +$(GENERATED_HEADERS): xml-to-h.py xmltypes.py $(SOURCE_XML) + +# Add a fake dependency so that all headers other than the first will +# depend on the first. This allows the first generated header to do +# double duty as a flag file. This indirection ensures that Make will +# only run one instance of the generation rule, rather than one per +# required header file. +$(wordlist 2, $(words $(GENERATED_HEADERS)), $(GENERATED_HEADERS)): $(firstword $(GENERATED_HEADERS)) + check-api: xmllint --noout --relaxng api.rng *.xml diff --git a/gcc-c-api/gcc-callgraph.c b/gcc-c-api/gcc-callgraph.c index 625728a8..85309e98 100644 --- a/gcc-c-api/gcc-callgraph.c +++ b/gcc-c-api/gcc-callgraph.c @@ -38,7 +38,7 @@ GCC_PUBLIC_API (void) gcc_cgraph_node_mark_in_use (gcc_cgraph_node node) /* As of gcc 4.9, a cgraph_node inherits from symtab node and uses that struct's marking routine. */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) gt_ggc_mx_symtab_node (node.inner); #else gt_ggc_mx_cgraph_node (node.inner); @@ -58,11 +58,11 @@ gcc_cgraph_node_get_decl (gcc_cgraph_node node) */ tree decl; -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) /* Access decl field of parent class, symtab_node */ decl = node.inner->decl; #else -# if (GCC_VERSION >= 4008) +# if (TARGET_GCC_VERSION >= 4008) decl = node.inner->symbol.decl; # else decl = node.inner->decl; @@ -153,7 +153,7 @@ gcc_for_each_cgraph_node (bool (*cb) (gcc_cgraph_node node, void *user_data), gcc 4.8 eliminated: extern GTY(()) struct cgraph_node *cgraph_nodes; FIXME: does this only visit *defined* functions then? */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) FOR_EACH_DEFINED_FUNCTION(node) #else for (node = cgraph_nodes; node; node = node->next) diff --git a/gcc-c-api/gcc-cfg.c b/gcc-c-api/gcc-cfg.c index af869531..7e40d3e9 100644 --- a/gcc-c-api/gcc-cfg.c +++ b/gcc-c-api/gcc-cfg.c @@ -23,7 +23,7 @@ #include "function.h" #include "basic-block.h" -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "tree-ssa-alias.h" /* needed by gimple.h in 4.9 */ #include "internal-fn.h" /* needed by gimple.h in 4.9 */ #include "is-a.h" /* needed by gimple.h in 4.9 */ @@ -33,7 +33,7 @@ #include "gimple.h" /* gcc 4.9 moved gimple_stmt_iterator into this header */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "gimple-iterator.h" #endif @@ -118,7 +118,7 @@ gcc_cfg_block_get_index (gcc_cfg_block block) static bool for_each_edge ( -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) vec *vec_edges, #else VEC (edge, gc) * vec_edges, @@ -174,7 +174,7 @@ checked_get_gimple_info(gcc_cfg_block block) return NULL; } -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) return &block.inner->il.gimple; #else return block.inner->il.gimple; diff --git a/gcc-c-api/gcc-gimple.c b/gcc-c-api/gcc-gimple.c index a6313bdf..a7fc5bbb 100644 --- a/gcc-c-api/gcc-gimple.c +++ b/gcc-c-api/gcc-gimple.c @@ -24,7 +24,7 @@ #include "tree.h" #include "function.h" #include "basic-block.h" -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) //#include "alias.h" /* needed by tree-ssa-alias.h in 4.9 */ #include "tree-ssa-alias.h" /* needed by gimple.h in 4.9 */ #include "internal-fn.h" /* needed by gimple.h in 4.9 */ @@ -52,7 +52,7 @@ GCC_IMPLEMENT_PUBLIC_API (void) gcc_gimple_mark_in_use (gcc_gimple stmt) /* Mark the underlying object (recursing into its fields): */ /* GCC 4.9 converted gimple to a class hierarchy */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) gt_ggc_mx_gimple_statement_base (stmt.inner); #else gt_ggc_mx_gimple_statement_d (stmt.inner); diff --git a/gcc-c-api/gcc-private-compat.h b/gcc-c-api/gcc-private-compat.h index 4dab0a3c..9e01e352 100644 --- a/gcc-c-api/gcc-private-compat.h +++ b/gcc-c-api/gcc-private-compat.h @@ -27,7 +27,7 @@ *************************************************************************/ /* Getting the length of a vector, returning 0 if it is NULL: */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) #define GCC_COMPAT_VEC_LENGTH(KIND, V) \ ( (V) ? ( (V)->length() ) : 0 ) #else @@ -36,7 +36,7 @@ #endif /* Looking up an element by index: */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) #define GCC_COMPAT_VEC_INDEX(KIND, V, IDX) \ ( (*(V))[IDX] ) #else @@ -46,7 +46,7 @@ /* Iterating over every element in a vector, or not at all if it is NULL: */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) #define GCC_COMPAT_FOR_EACH_VEC_ELT(KIND, V, IDX_VAR, ITEM_VAR) \ if ( (V) != NULL ) \ FOR_EACH_VEC_ELT ( (*V), (IDX_VAR), (ITEM_VAR) ) diff --git a/gcc-c-api/gcc-variable.c b/gcc-c-api/gcc-variable.c index 105a154f..588e7a13 100644 --- a/gcc-c-api/gcc-variable.c +++ b/gcc-c-api/gcc-variable.c @@ -40,10 +40,10 @@ GCC_IMPLEMENT_PUBLIC_API (void) gcc_variable_mark_in_use (gcc_variable var) /* In GCC 4.8, struct varpool_node became part of union symtab_node_def, and In GCC 4.9, union symtab_node_def became class symtab_node. */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) gt_ggc_mx_symtab_node (var.inner); #else -# if (GCC_VERSION >= 4008) +# if (TARGET_GCC_VERSION >= 4008) gt_ggc_mx_symtab_node_def (var.inner); # else gt_ggc_mx_varpool_node (var.inner); @@ -63,11 +63,11 @@ GCC_IMPLEMENT_PUBLIC_API (gcc_tree) gcc_variable_get_decl (gcc_variable var) */ tree decl; -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) /* Get from base class */ decl = var.inner->decl; #else -# if (GCC_VERSION >= 4008) +# if (TARGET_GCC_VERSION >= 4008) decl = var.inner->symbol.decl; # else decl = var.inner->decl; diff --git a/gcc-python-attribute.c b/gcc-python-attribute.c index 2b528b41..0ceb9457 100644 --- a/gcc-python-attribute.c +++ b/gcc-python-attribute.c @@ -25,7 +25,7 @@ #include "diagnostic.h" #include "plugin.h" -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) /* GCC 4.9 moved debug_tree here: */ #include "print-tree.h" #endif diff --git a/gcc-python-cfg.c b/gcc-python-cfg.c index 84fc4feb..18e2cccd 100644 --- a/gcc-python-cfg.c +++ b/gcc-python-cfg.c @@ -432,7 +432,7 @@ PyGccCfg_get_block_for_label(PyObject *s, PyObject *args) if (uid < 0 || ( ( -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) vec_safe_length(self->cfg.inner->x_label_to_block_map) #else VEC_length (basic_block, self->cfg.inner->x_label_to_block_map) diff --git a/gcc-python-gimple.c b/gcc-python-gimple.c index 11a77318..ead33d53 100644 --- a/gcc-python-gimple.c +++ b/gcc-python-gimple.c @@ -26,7 +26,7 @@ /* gimple_phi_arg_def etc were in tree-flow-inline.h prior to 4.9, when they moved to gimple.h */ -#if (GCC_VERSION < 4009) +#if (TARGET_GCC_VERSION < 4009) #include "tree-flow.h" #include "tree-flow-inline.h" #endif @@ -35,7 +35,7 @@ Needed for pp_gimple_stmt_1 for gcc 4.8+; this header didn't exist in gcc 4.6: */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) #include "gimple-pretty-print.h" #endif @@ -43,7 +43,7 @@ /* GCC 4.9 moved struct walk_stmt_info into the new header gimple-walk.h, which in turn needs the new header gimple-iterator.h: */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "gimple-iterator.h" #include "gimple-walk.h" #endif @@ -109,7 +109,7 @@ do_pretty_print(struct PyGccGimple * self, int spc, int flags) gcc 4.8 renamed "dump_gimple_stmt" to "pp_gimple_stmt_1" (in r191884). Declaration is in gimple-pretty-print.h */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) pp_gimple_stmt_1(PyGccPrettyPrinter_as_pp(ppobj), self->stmt.inner, spc, flags); diff --git a/gcc-python-option.c b/gcc-python-option.c index 0f27dc85..0e6dc75e 100644 --- a/gcc-python-option.c +++ b/gcc-python-option.c @@ -86,7 +86,7 @@ PyGccOption_repr(PyGccOption * self) #define warn_format global_options.x_warn_format */ -#if (GCC_VERSION < 4008) +#if (TARGET_GCC_VERSION < 4008) /* Weakly import warn_format; it's not available in lto1 (during link-time optimization) @@ -135,7 +135,7 @@ int PyGcc_option_is_enabled(enum opt_code opt_code) /* We don't know: */ return -1; -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) case OPT_Wformat_: #else case OPT_Wformat: diff --git a/gcc-python-pass.c b/gcc-python-pass.c index a0157edd..7fb13603 100644 --- a/gcc-python-pass.c +++ b/gcc-python-pass.c @@ -23,7 +23,7 @@ #include "diagnostic.h" #include "gcc-c-api/gcc-function.h" #include "gcc-c-api/gcc-location.h" -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "context.h" #include "pass_manager.h" #endif @@ -177,7 +177,7 @@ static unsigned int impl_execute(void) return 0; } -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) /* GCC 4.9 converted passes to a C++ class hierarchy, with methods for gate and execute. @@ -243,7 +243,7 @@ class PyGccSimpleIpaPass : public simple_ipa_opt_pass opt_pass *clone() {return this; } }; -#endif /* #if (GCC_VERSION >= 4009) */ +#endif /* #if (TARGET_GCC_VERSION >= 4009) */ static int do_pass_init(PyObject *s, PyObject *args, PyObject *kwargs, @@ -267,7 +267,7 @@ do_pass_init(PyObject *s, PyObject *args, PyObject *kwargs, return -1; } -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) pass_data pass_data; memset(&pass_data, 0, sizeof(pass_data)); pass_data.type = pass_type; @@ -364,7 +364,7 @@ PyGccPass_repr(struct PyGccPass *self) self->pass->name); } -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) static struct dump_file_info * get_dump_file_info(int phase) { @@ -383,7 +383,7 @@ get_dump_file_info(int phase) static bool is_dump_enabled(struct opt_pass *pass) { -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) struct dump_file_info *dfi = get_dump_file_info(pass->static_pass_number); return dfi->pstate || dfi->alt_state; #else @@ -398,7 +398,7 @@ PyGccPass_get_dump_enabled(struct PyGccPass *self, void *closure) } /* In GCC 4.8, this field became "pstate" */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) #define DFI_STATE(dfi) (dfi)->pstate #else #define DFI_STATE(dfi) (dfi)->state @@ -454,7 +454,7 @@ PyGccPass_set_dump_enabled(struct PyGccPass *self, PyObject *value, void *closur /* In GCC 4.9, passes moved from being globals to fields of the pass_manager. */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #define GET_PASS_LIST(PASS_NAME) (g->get_passes()->PASS_NAME) #else #define GET_PASS_LIST(PASS_NAME) (PASS_NAME) @@ -486,7 +486,7 @@ PyGccPass_get_roots(PyObject *cls, PyObject *noargs) SET_PASS(2, all_regular_ipa_passes); /* all_late_ipa_passes appeared in r175336 */ /* r204984 eliminated all_lto_gen_passes */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) SET_PASS(3, all_late_ipa_passes); #else SET_PASS(3, all_lto_gen_passes); @@ -552,7 +552,7 @@ PyGccPass_get_by_name(PyObject *cls, PyObject *args, PyObject *kwargs) SEARCH_WITHIN_LIST(all_regular_ipa_passes); /* all_late_ipa_passes appeared in r175336 */ /* r204984 eliminated all_lto_gen_passes */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) SEARCH_WITHIN_LIST(all_late_ipa_passes); #else SEARCH_WITHIN_LIST(all_lto_gen_passes); diff --git a/gcc-python-plugin.spec b/gcc-python-plugin.spec index 14573b7f..ebc58f77 100644 --- a/gcc-python-plugin.spec +++ b/gcc-python-plugin.spec @@ -145,7 +145,7 @@ BuildPlugin() { PYTHON=$PythonExe \ PYTHON_CONFIG=$PythonConfig \ PLUGIN_PYTHONPATH=%{gcc_plugins_dir}/$PluginName \ - plugin print-gcc-version + plugin autogenerated-gcc-version popd } diff --git a/gcc-python-pretty-printer.c b/gcc-python-pretty-printer.c index 48c7b79f..348b5ecd 100644 --- a/gcc-python-pretty-printer.c +++ b/gcc-python-pretty-printer.c @@ -20,7 +20,7 @@ #include #include "gcc-python.h" #include "gcc-python-wrappers.h" -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) /* Needed for placement new */ #include #endif @@ -41,7 +41,7 @@ PyGccPrettyPrinter_New(void) obj->buf[0] = '\0'; obj->file_ptr = fmemopen(obj->buf, sizeof(obj->buf), "w"); -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) /* GCC 4.9 eliminated pp_construct in favor of a C++ ctor. Use placement new to run it on obj->pp. */ new ((void*)&obj->pp) pretty_printer(NULL, 0); diff --git a/gcc-python-rtl.c b/gcc-python-rtl.c index d63dfe86..a9609a6b 100644 --- a/gcc-python-rtl.c +++ b/gcc-python-rtl.c @@ -28,7 +28,7 @@ PyObject * PyGccRtl_get_location(struct PyGccRtl *self, void *closure) { /* In gcc 4.8, INSN_LOCATOR was replaced by INSN_LOCATION (in r191494) */ -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) return PyGccLocation_New(gcc_private_make_location(INSN_LOCATION(self->insn.inner))); #else int locator = INSN_LOCATOR (self->insn.inner); diff --git a/gcc-python-tree.c b/gcc-python-tree.c index 8daa6ed1..357d4a03 100644 --- a/gcc-python-tree.c +++ b/gcc-python-tree.c @@ -28,14 +28,14 @@ /* for op_symbol_code */ /* Moved to tree-pretty-print.h in gcc 4.9: */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "tree-pretty-print.h" #else #include "tree-flow.h" #endif /* "maybe_get_identifier" was moved from tree.h to stringpool.h in 4.9 */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "stringpool.h" /* for maybe_get_identifier */ #endif @@ -1152,7 +1152,7 @@ gcc_tree_list_of_pairs_from_tree_list_chain(tree t) PyObject * VEC_tree_as_PyList( -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) vec *vec_nodes #else VEC(tree,gc) *vec_nodes diff --git a/gcc-python.c b/gcc-python.c index f057e2cc..7414772f 100644 --- a/gcc-python.c +++ b/gcc-python.c @@ -42,7 +42,7 @@ int plugin_is_GPL_compatible; //#include "opts.h" /* "maybe_get_identifier" was moved from tree.h to stringpool.h in 4.9 */ -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "stringpool.h" #endif @@ -572,7 +572,7 @@ PyGcc_init_gcc_module(struct plugin_name_args *plugin_info) PyModule_AddIntMacro(PyGcc_globals.module, PROP_gimple_lcf); PyModule_AddIntMacro(PyGcc_globals.module, PROP_gimple_leh); PyModule_AddIntMacro(PyGcc_globals.module, PROP_cfg); -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) /* PROP_referenced_vars went away in GCC 4.8 (in r190067) */ #else PyModule_AddIntMacro(PyGcc_globals.module, PROP_referenced_vars); @@ -584,7 +584,7 @@ PyGcc_init_gcc_module(struct plugin_name_args *plugin_info) PyModule_AddIntMacro(PyGcc_globals.module, PROP_cfglayout); PyModule_AddIntMacro(PyGcc_globals.module, PROP_gimple_lcx); - PyModule_AddIntMacro(PyGcc_globals.module, GCC_VERSION); + PyModule_AddIntConstant(PyGcc_globals.module, "GCC_VERSION", TARGET_GCC_VERSION); /* Success: */ return 1; diff --git a/gcc-python.h b/gcc-python.h index 411db323..dc6c9f9d 100644 --- a/gcc-python.h +++ b/gcc-python.h @@ -25,7 +25,7 @@ #if 1 #include "tree.h" -#if (GCC_VERSION >= 4009) +#if (TARGET_GCC_VERSION >= 4009) #include "basic-block.h" /* needed by gimple.h in 4.9 */ #include "function.h" /* needed by gimple.h in 4.9 */ #include "tree-ssa-alias.h" /* needed by gimple.h in 4.9 */ @@ -305,7 +305,7 @@ void autogenerated_variable_add_types(PyObject *m); PyObject * PyGccStringOrNone(const char *str_or_null); -#if (GCC_VERSION >= 4008) +#if (TARGET_GCC_VERSION >= 4008) PyObject * VEC_tree_as_PyList(vec *vec_nodes); #else diff --git a/generate-config-h.py b/generate-config-h.py index c9e5c0e8..f70abaa3 100644 --- a/generate-config-h.py +++ b/generate-config-h.py @@ -89,6 +89,7 @@ def with_cplusplus(): self.extra_compilation_args += ['-x', 'c++'] def with_c(): check.okmsg = 'C' + self.extra_compilation_args += ['-x', 'c'] auto_host_h = os.path.join(self.plugindir, 'include', 'auto-host.h') with open(auto_host_h, 'r') as f: content = f.read() diff --git a/print-gcc-version.c b/print-gcc-version.c deleted file mode 100644 index 436d93d9..00000000 --- a/print-gcc-version.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright 2013 David Malcolm - Copyright 2013 Red Hat, Inc. - - This is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - . -*/ - -#include "plugin.h" - -int main(int argc, const char *argv[]) -{ - printf("%i\n", GCC_VERSION); - return 0; -} diff --git a/testcpychecker.py b/testcpychecker.py index 060f0859..b1af73e1 100644 --- a/testcpychecker.py +++ b/testcpychecker.py @@ -29,9 +29,9 @@ PLUGIN_NAME = os.environ.get('PLUGIN_NAME', 'python') def get_gcc_version(): - p = Popen(['./print-gcc-version'], - stdout=PIPE, stderr=PIPE) - out, err = p.communicate() + out = '0' + with open('autogenerated-gcc-version', 'r') as f: + out = f.read() return(int(out)) GCC_VERSION = get_gcc_version()