Разрешение определений типов в C и C++

Я пытаюсь автоматически разрешить определения типов в произвольном C++ или проектах C.

Поскольку некоторые определения типов определяются в системных заголовочных файлах (например, uint32), я в настоящее время пытаюсь достигнуть этого путем выполнения gcc препроцессора на моих файлах кода и затем сканирования предварительно обработанных файлов для определений типов. Я должен затем смочь заменить определения типов в файлах кода проекта.

Я задаюсь вопросом, если существует другой, возможно, более простой путь, я отсутствую. Можно ли думать о том?

Причина, почему я хочу сделать это: я извлекаю метрики кода из проектов C/C++ с различными инструментами. Метрики основаны на методе. После извлечения метрик я должен объединить данные, которые производятся различными инструментами. Проблема, что один из инструментов разрешает определения типов, и другие не делают. Если существуют определения типов, используемые для типов параметра методов, мне отобразили метрики на различные имена методов, которые на самом деле обращаются к тому же методу в исходном коде.

Думайте об этом методе в исходном коде: int test(uint32 par1, int par2)
После выполнения моих инструментов у меня есть метрики, отображенные на названном методе int test(uint32 par1, int par2) и некоторые мои метрики отображаются на int test(unsigned int par1, int par2).

8
задан Brian Tompsett - 汤莱恩 21 February 2016 в 13:39
поделиться

3 ответа

Если вас не волнует, где они определены, вы можете использовать objdump для сброса таблицы символов C++, которая разрешает typedefs.

lorien$ objdump --demangle --syms foo

foo:     file format mach-o-i386

SYMBOL TABLE:
00001a24 g       1e SECT   01 0000 .text dyld_stub_binding_helper
00001a38 g       1e SECT   01 0000 .text _dyld_func_lookup
...
00001c7c g       0f SECT   01 0080 .text foo::foo(char const*)
...

Этот фрагмент из следующего определения структуры:

typedef char const* c_string;
struct foo {
    typedef c_string ntcstring;
    foo(ntcstring s): buf(s) {}
    std::string buf;
};

Это действительно требует, чтобы вы скомпилировали все и он будет показывать только символы в результирующем исполняемом файле, так что есть несколько ограничений. Другой вариант - дать компоновщику дамп карты символов. Для инструментов GNU добавьте -Wl,-map и -Wl,name, где name - это имя генерируемого файла (см. примечание). Такой подход не распутывает имена, но с небольшой работой вы можете переинжиниринговать конвенции компилятора. Вывод из предыдущего фрагмента будет включать что-то вроде:

0x00001CBE  0x0000005E  [  2] __ZN3fooC2EPKc
0x00001D1C  0x0000001A  [  2] __ZN3fooC1EPKc

Вы можете расшифровать их, используя C++ ABI спецификацию. Как только вы освоитесь с тем, как это работает, таблица mangling table, включенная в ABI, становится бесценной. Вывод в данном случае:

<mangled-name>           ::= '_Z' <encoding>
<encoding>               ::= <name> <bare-function-type>
  <name>                 ::= <nested-name>
    <nested-name>        ::= 'N' <source-name> <ctor-dtor-name> 'E'
      <source-name>      ::= <number> <identifier>
      <ctor-dtor-name>   ::= 'C2' # base object constructor
    <bare-function-type> ::= <type>+
      <type>             ::= 'P' <type> # pointer to
        <type>           ::= <cv-qualifier> <type>
          <cv-qualifier> ::= 'K' # constant
            <type>       ::= 'c' # character

Примечание: выглядит так, как будто GNU изменяет аргументы на ld, так что вы можете захотеть проверить ваше локальное руководство (man ld), чтобы убедиться, что команды генерации файла карты в вашей версии являются -map-именем файла . В последних версиях используйте -Wl,-M и перенаправьте stdout в файл.

5
ответ дан 5 December 2019 в 17:37
поделиться

GCC-XML может помочь с разрешением Typedefs, вам нужно следовать идентификаторам типа элементов, пока не решите их на , , или элемент.

Для замены Typedefs в ваш проект у вас есть более фундаментальные проблемы, хотя: вы не можете просто поискать и заменить, как вам придется уважать объем имен - подумайте об е. Функциональные функции Typedefs, псевдоним пространства имен или с использованием директив .

В зависимости от того, что вы на самом деле пытаетесь достичь, там должен быть лучший способ.

Обновление: На самом деле, в данном контексте фиксации данных метрик, замена тепэнисов, использующих GCC-XML, должна работать нормально, если он поддерживает вашу кодовую базу.

2
ответ дан 5 December 2019 в 17:37
поделиться

Clang (внешний интерфейс компилятора LLVM C/C + +) можно использовать для анализа кода путь, чтобы сохранить информацию о типах и даже макросах. Имеет очень хороший C++ API для чтения данных после считывания исходного кода в AST (абстрактное синтаксическое дерево). http://clang.llvm.org/

Если вместо этого вы ищете простую программу, которая уже делает для вас разрешение (вместо Clang программирования API), я думаю, что вам не повезло, так как я никогда не видел такого.

3
ответ дан 5 December 2019 в 17:37
поделиться