c++ refactoring llvm clang

¿Alguna herramienta de refactorización C/C++ basada en libclang?(incluso el más simple "ejemplo de juguete")



refactoring llvm (8)

Clang contiene una biblioteca llamada "CIndex" que fue desarrollada, creo, para completar el código en IDE. También se puede usar para analizar C ++ y recorrer el AST, pero no tiene nada que ver con la refactorización. Ver el artículo de Eli Bendersky here .

Recientemente comencé un proyecto como este: cmonster . Es una API basada en Python para analizar C ++ (usando libclang), analizando el AST, con una interfaz para "reescribir" (es decir, insertar / eliminar / modificar rangos de fuente). No hay una buena manera (todavía) para hacer cosas como modificar los nombres de las funciones y tener eso traducido en modificaciones de fuente, pero no sería terriblemente difícil hacerlo.

Todavía no he creado un lanzamiento con esta funcionalidad (aunque está en el repositorio github), ya que estoy esperando que llvm / clang 3.0 sea lanzado.

Además, debo señalar un par de cosas:

  • El código es muy difícil, llamarlo alfa sería quizás generoso.
  • De ninguna manera soy un experto en este tema (a diferencia, digamos, del Dr. Ira Baxter de allí).

Ajustar las expectativas apropiadamente

Actualización: se lanzó cmonster 0.2, que incluye las características descritas. Compruébalo en Github .

Como he señalado here , parece que la generación de clang debe ser excelente para implementar la tarea difícil que es el análisis y las modificaciones del código C / C ++ ( here ).

¿Conoces alguna herramienta de refactorización C / C ++ basada en libclang?

"Cualquiera" incluye incluso un proyecto de estado alfa simple, con soporte de una técnica de refactorización. Puede ser sin soporte de preprocesador. Como un ejemplo de lo funcional sobre el que estoy hablando: cambiar los nombres de los métodos, si admite varios archivos o solo un archivo a la vez. Quizás se pregunte cuál es el objetivo de solicitar incluso pequeños ejemplos de trabajo. Mi idea es que la creación de una lista de ejemplos de códigos y pequeñas herramientas que se encuentran en un solo lugar proporcionará un mejor recurso para aprender a implementar la refactorización con libclang . Creo que a partir de proyectos simples podrían crecer proyectos más grandes, de una manera apropiada de fuente abierta :).


Esto puede ser un poco ''meta'', pero hay un ejemplo que está escrito en clang como una herramienta para ejecutar en clang (aunque, hay más que eso solo eso).

RemoveCStrCalls.cpp

// This file implements a tool that prints replacements that remove redundant // calls of c_str() on strings. // // Usage: // remove-cstr-calls <cmake-output-dir> <file1> <file2> ... // // Where <cmake-output-dir> is a CMake build directory in which a file named // compile_commands.json exists (enable -DCMAKE_EXPORT_COMPILE_COMMANDS in // CMake to get this output). // // <file1> ... specify the paths of files in the CMake source tree. This path // is looked up in the compile command database. If the path of a file is // absolute, it needs to point into CMake''s source tree. If the path is // relative, the current working directory needs to be in the CMake source // tree and the file must be in a subdirectory of the current working // directory. "./" prefixes in the relative files will be automatically // removed, but the rest of a relative path must be a suffix of a path in // the compile command line database. // // For example, to use remove-cstr-calls on all files in a subtree of the // source tree, use: // // /path/in/subtree $ find . -name ''*.cpp''| // xargs remove-cstr-calls /path/to/source


Google creó una herramienta de refactorización basada en Clang para su base de código C ++ y planea lanzarla. No conozco el estado actual del proyecto, pero puede ver este demo presentado en la Reunión de desarrolladores de LLVM 2011: https://www.youtube.com/watch?v=mVbDzTM21BQ .

Además, las funciones integradas de autocompletado y refactorización de XCode (4+) se basan en libclang.


Google ha estado trabajando en una biblioteca de herramientas para Clang. En desde la versión 3.2 . Incluye una biblioteca ASTMatchers para que pueda crear una consulta y no tenga que recorrer el AST.

Hay una gran charla en video sobre el tema que recorre un simple ejemplo de cambio de nombre. (Esto es del mismo tipo que la charla de MapReduce publicada anteriormente, pero es más reciente y más sobre una implementación práctica simple en lugar del diseño interno y las cosas de escala empresarial que Google tiene en marcha).

La fuente para ese ejemplo que cambia el nombre de un método está disponible en la rama de herramientas . Puede estar en algún lugar del maletero, pero no puedo encontrarlo. También cambie el nombre de la función getDeclAs a getNodesAs ya que la otra parece estar obsoleta ). Hay un ejemplo más avanzado que elimina las llamadas c_str duplicadas (que están en el enlace troncal y alguien publicado anteriormente).

Aquí hay documentación para LibASTMatchers y LibTooling .

EDITAR: Algunos documentos mejores para ASTMatcher. LibASTMatchers y here .

EDITAR: Google ahora está trabajando en algo llamado Clangd que pretende ser algún tipo de servidor Clang para refactorizar.


No es de código abierto, pero se ha utilizado para llevar a cabo una refacturación automatizada masiva de programas en C ++ que no sea de juguete: nuestro DMS Software Reengineering Toolkit . DMS es una "biblioteca" (lo llamamos "kit de herramientas") de las instalaciones que puede redactar para lograr un análisis y / o traducción automática.

Relevante para C ++, DMS proporciona en este momento:

  • Analizador completo de C ++ 11, construyendo el AST y capaz de regenerar el código fuente con precisión incluyendo comentarios, con un preprocesador completo
  • Analizador de C ++ completo con nombre y tipo de resolución para C ++ (ANSI, GNU, MS Visual C ++)
  • Control de flujo de análisis para C ++
  • Transformaciones de fuente a fuente
  • Completar parcialmente la maquinaria de "cambio de nombre" (ver discusión a continuación)

Lo que puedo decir de la experiencia es que C ++ es una perra de un lenguaje para transformar.

Seguimos trabajando en ello, y estamos completando una herramienta de cambio de nombre confiable. Incluso esto es difícil; un problema clave es el problema de sombreado de nombres. Usted tiene una variable local X y una referencia a Y dentro de ese alcance; intenta cambiar el nombre de Y a X y descubre que la variable local "captura" el acceso. Es sorprendente la cantidad de espacios de nombres y tipos de captura que tiene que preocuparse en C ++. Y esto es necesario como base para muchas otras refactorizaciones.

EDITAR Feb 2014: Analizador completo C ++ 14, análisis de flujo de control, análisis de flujo de datos local



Otra posibilidad es desarrollar su propio complemento para GCC o desarrollar una extensión GCC MELT para realizar su tarea. Pero extender GCC (o Clang) requiere comprender las representaciones internas de estos compiladores (Gimple & Tree para GCC) y esto requiere algo de trabajo. MELT es un lenguaje específico de dominio de alto nivel para extender GCC.


https://github.com/lukhnos/refactorial se basa en clang y reclamaciones

Transformaciones proporcionadas

Accesor: sintetizadores getters y setters para variables de miembro designadas

MethodMove: mueva los cuerpos de función de miembros insertados al archivo de implementación

ExtractParameter: promueve una variable de función a un parámetro para esa función

TypeRename: Renombrar tipos, incluidos los tipos de etiquetas (enum, struct, union, class), clases de plantilla, tipos Objective-C (clase y protocolo), typedefs e incluso tipos bulit-in (por ejemplo, unsigned to uint32_t)

RecordFieldRename: Cambiar el nombre de los campos de registro (estructura, unión), incluidas las variables de miembros de C ++

FunctionRename: Renombrar funciones, incluidas las funciones miembro de C ++

Funciona mediante especificaciones en un archivo de configuración YAML. No lo he probado (aún).