On 2011-10-17 15:45, Mingjie Xing wrote:
在 2011年10月17日 下午2:55,asmwarrior<asmwarrior@xxxxxxxxx> 写道:我和xunxun都试验了如下代码: http://codesynthesis.com/~boris/blog/2010/05/10/parsing-cxx-with-gcc-plugin-part-2/ 但是都是死活通不过,感觉gcc plugin的一些头文件的顺序听关键的,但是这块调整来调整去,都是不行。。你用的gcc版本是多少? 邢明杰
我的gcc是4.6.1版本(确切的说,是xunxun编译出来的gcc) 经过下午的一番折腾之后,我已经可以用啦,反正就是头文件顺序挪来挪去弄了一下,然后就行了。 附件是我修改过的代码。 然后需要做的是: \MinGW_GCC4.6.1_enable_plugin_experimental\MinGW\i686-w64-mingw32\include\c-family 里面复制一个 c-common.h 文件。 然后就行啦: 结果如下: E:\code\cb\gcc\MinGW_GCC4.6.1_enable_plugin_experimental\example>mingw32-make -f Makefile.g++ g++ -shared plugin-2.cxx -o hello.dll -lcc1plus g++ -fplugin=hello.dll main.cpp starting hello processing main.cpp type_decl ::typedefed_int_t at main.cpp:21 function_decl ::main at main.cpp:23 e:/code/cb/gcc/mingw_gcc4.6.1_enable_plugin_experimental/mingw/bin/../lib/gcc/i6 86-w64-mingw32/4.6.1/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_ libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x39): undefined reference to `Wi nMain@16' collect2: ld returned 1 exit status Makefile.g++:3: recipe for target `all' failed mingw32-make: *** [all] Error 1 首先,编译这一步已经完成了。而且似乎也可以打印出main.cpp里面的东西来。当然后面这个错误,可能是编译main.cpp的出错信息吧, 呵呵。 main.cpp如下: struct foo { int bar; int baz; void hello(int x, int y) {} void bye(char* x, char* y); }; template<class T> struct templ { T* x; }; void foo::bye(char* x, char* y) { } typedef int typedefed_int_t; int main() { return 0; }
// GCC header includes to get the parse tree declarations. The order // is important and doesn't follow any kind of logic. // #include <stdlib.h> #include <gmp.h> #include <cstdlib> // Include before GCC poison some declarations. extern "C" { #include "gcc-plugin.h" #include "plugin-version.h" #include "gcc-plugin.h" #include "cp/cp-tree.h" #include "c-common.h" #include "config.h" #include "system.h" #include "coretypes.h" #include "tree.h" #include "intl.h" #include "tm.h" #include "diagnostic.h" #include "c-pragma.h" } #include <set> #include <string> #include <iostream> using namespace std; int plugin_is_GPL_compatible; struct decl_comparator { bool operator() (tree x, tree y) const { location_t xl (DECL_SOURCE_LOCATION (x)); location_t yl (DECL_SOURCE_LOCATION (y)); return xl < yl; } }; typedef std::multiset<tree, decl_comparator> decl_set; void collect (tree ns, decl_set& set) { tree decl; cp_binding_level* level (NAMESPACE_LEVEL (ns)); // Collect declarations. // for (decl = level->names; decl != 0; decl = TREE_CHAIN (decl)) { if (DECL_IS_BUILTIN (decl)) continue; set.insert (decl); } // Traverse namespaces. // for(decl = level->namespaces; decl != 0; decl = TREE_CHAIN (decl)) { if (DECL_IS_BUILTIN (decl)) continue; collect (decl, set); } } string decl_namespace (tree decl) { string s, tmp; for (tree scope (CP_DECL_CONTEXT (decl)); scope != global_namespace; scope = CP_DECL_CONTEXT (scope)) { tree id (DECL_NAME (scope)); tmp = "::"; tmp += (id != 0 ? IDENTIFIER_POINTER (id) : "<unnamed>"); tmp += s; s.swap (tmp); } return s; } void print_decl (tree decl) { int tc (TREE_CODE (decl)); tree id (DECL_NAME (decl)); const char* name (id ? IDENTIFIER_POINTER (id) : "<unnamed>"); cerr << tree_code_name[tc] << " " << decl_namespace (decl) << "::" << name << " at " << DECL_SOURCE_FILE (decl) << ":" << DECL_SOURCE_LINE (decl) << endl; } void traverse (tree ns) { decl_set set; collect (ns, set); for (decl_set::iterator i (set.begin ()), e (set.end ()); i != e; ++i) { print_decl (*i); } } extern "C" void gate_callback (void*, void*) { // If there were errors during compilation, // let GCC handle the exit. // if (errorcount || sorrycount) return; int r (0); // // Process AST. Issue diagnostics and set r // to 1 in case of an error. // cerr << "processing " << main_input_filename << endl; traverse (global_namespace); exit (r); } extern "C" int plugin_init (plugin_name_args* info, plugin_gcc_version* ver) { int r (0); cerr << "starting " << info->base_name << endl; // // Parse options if any. // // Disable assembly output. // asm_file_name = HOST_BIT_BUCKET; // Register callbacks. // register_callback (info->base_name, PLUGIN_OVERRIDE_GATE, &gate_callback, 0); return r; }