Компания, в которой я работаю, Semantic Designs Inc. предоставляет инструменты, включающие
общая инфраструктура для анализа и преобразования программ и
специфические компоненты анализа для различных языков программирования.
Вместе они известны как DMS. В случае C ++ DMS включает
интегрированные лексеры, препроцессоры, парсеры, а также имя и тип
компоненты разрешения для каждого из GCC3, GCC4, ISO14882c1998 (ANSI),
Visual C ++ 6.0 и неуправляемая Visual Studio 2005 C ++. Для различных
диалекты С, также существуют анализ потока управления, побочные эффекты
анализатор и анализатор символьной зависимости, с помощью которого такие инструменты, как
средство проверки указателя, средство удаления неактивного кода, средство профилирования функций и программа
слайсер были реализованы.
Компоненты разрешения имени и типа предоставляют полную таблицу символов
информация и возможности поиска, так что ссылки на
идентификаторы могут быть легко связаны с их типами и другими
декларативная информация. Информация, как это захвачено и
используется компилятором, но сохраняется вместе с абстрактными синтаксическими деревьями
в форме, пригодной для адаптивного повторного использования любым инструментом, включающим
компонент.
Semantic Designs недавно создал специальный инструмент, который
связанные конкретно с типами индексных переменных в цикле
объявления, такие как в вашем примере. В этом случае проблема была
обновить код GCC2, который использовал переключатель компилятора -fno-for-scope,
который предоставил правило разрешения области для переменных цикла, которое не было
поддерживается в более поздних диалектах GCC. Инструмент должен был преобразовать петли,
перемещая объявления своих переменных цикла во внешний контекст
это сохранило правило области действия -fno-for-scope. Где такие изменения
не были необходимы, никаких изменений не было.
Таким образом, инструмент должен был различать тип, связанный с каждой ссылкой
к переменной цикла, дифференцируя в случае маскирующих областей, и
восстановить код так, чтобы разрешение имен GCC3 и GCC4
привести к той же семантической интерпретации, что и GCC2 с
-fno-для-сферы. Это требовало возможности доступа к таблице символов
информация, связанная с каждой ссылкой на переменную, и в случае
где код был перемещен, чтобы восстановить правильный синтаксис для
объявления типа для любой переменной, объявление которой было перемещено.
Таблица символов и таблица идентификаторов, предоставленная DMS
Компонент разрешения имен и типов в C ++ содержит все необходимое
информация, и модуль для восстановления синтаксиса предписанного типа
допускается обобщение правильных объявлений новых типов.
Например, рассмотрим пример:
// loop variable hides variable in global scope
// will change meaning without -fno-for-scope
// fix: move decl. of cnt before for-loop
// optionally rename globcnt loop variable
float globcnt = 0.0;
int Foo::foo3() {
for (int globcnt = 0; globcnt < 5; globcnt++) {
globalInt += globcnt;
}
globalInt += 2*globcnt + 1;
return 0;
}
GCC2-семантика -fno-for-scope указывает, что ссылки на globcnt
вне цикла находятся в переменной цикла, хотя GCC3 будет
вывести переменную цикла из области видимости и разрешить ссылки на
глобальная переменная. Инструмент преобразовал этот код в:
float globcnt = 0.0;
int Foo::foo3() {
int globcnt = 0;
for (; globcnt < 5; globcnt++) {
globalInt += globcnt;
}
globalInt += 2*globcnt + 1;
return 0;
}
Если бы код не был преобразован, GCC4 всегда возвращал бы
значение 1 из Foo: foo3. Преобразованный, однако, значение будет иметь
были подвержены влиянию итераций цикла, как изначально
Gcc2. Инструмент должен был признать, что окончательная ссылка на globcnt
для локальной переменной типа int, а не для глобальной переменной
введите float, что можно сделать с помощью поиска в таблице символов, и действовать
соответственно.
С другой стороны, инструмент распознает в следующем коде, что
не было ссылок на i вне цикла, так что это было приемлемо
(и желательно) оставить объявление переменной цикла без изменений.
int Foo::foo0() {
for (int i = 0; i < 10; i++) {
globalInt += i*i;
}
return 0;
}