//! \~\file picodeparser.h //! \~\ingroup Code //! \~\brief //! \~english C++ code parser //! \~russian Разбор C++ кода /* PIP - Platform Independent Primitives C++ code parser Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #ifndef PICODEPARSER_H #define PICODEPARSER_H #include "pievaluator.h" #include "pifile.h" inline bool _isCChar(const PIChar & c) { return (c.isAlpha() || (c.toAscii() == '_')); } inline bool _isCChar(const PIString & c) { if (c.isEmpty()) return false; return _isCChar(c[0]); } //! \~\ingroup Code //! \~\brief //! \~english Parser of C/C++ declarations used by the code model tools. //! \~russian Разборщик объявлений C/C++, используемый инструментами модели кода. //! \~\details //! \~english Parser for analyzing C++ source files. Extracts information about classes, structures, enums, macros, functions, and members. //! \~russian Парсер для анализа C++ исходных файлов. Извлекает информацию о классах, структурах, перечислениях, макросах, функциях и //! членах. class PIP_EXPORT PICodeParser { public: //! \~english Constructs a parser with built-in PIP macro presets. //! \~russian Создает разборщик со встроенными предустановками макросов PIP. PICodeParser(); //! \~english Visibility of a parsed declaration inside the current scope. //! \~russian Видимость разобранного объявления в текущей области. enum Visibility { Global /** \~english Global or namespace-level declaration. \~russian Глобальное объявление или объявление уровня пространства имен. */ , Public /** \~english Public class member. \~russian Открытый член класса. */, Protected /** \~english Protected class member. \~russian Защищенный член класса. */, Private /** \~english Private class member. \~russian Закрытый член класса. */ }; //! \~english Parsed declaration attributes. //! \~russian Атрибуты разобранного объявления. enum Attribute { NoAttributes = 0x0 /** \~english No attributes. \~russian Атрибуты отсутствуют. */, Const = 0x01 /** \~english \c const declaration. \~russian Объявление с \c const. */, Static = 0x02 /** \~english \c static declaration. \~russian Объявление с \c static. */, Mutable = 0x04 /** \~english \c mutable declaration. \~russian Объявление с \c mutable. */, Volatile = 0x08 /** \~english \c volatile declaration. \~russian Объявление с \c volatile. */, Inline = 0x10 /** \~english \c inline declaration. \~russian Объявление с \c inline. */, Virtual = 0x20 /** \~english \c virtual declaration. \~russian Объявление с \c virtual. */, Extern = 0x40 /** \~english \c extern declaration. \~russian Объявление с \c extern. */ }; //! \~english Bitmask of parsed declaration attributes. //! \~russian Битовая маска атрибутов разобранного объявления. typedef PIFlags Attributes; //! \~english Preprocessor define name and value. //! \~russian Имя и значение макроса \c define. typedef PIPair Define; //! \~english Typedef alias and target type. //! \~russian Псевдоним typedef и целевой тип. typedef PIPair Typedef; //! \~english Parsed metadata map. //! \~russian Карта разобранных метаданных. typedef PIMap MetaMap; //! \~english Parsed function-like macro. //! \~russian Разобранный функциональный макрос. struct PIP_EXPORT Macro { Macro(const PIString & n = PIString(), const PIString & v = PIString(), const PIStringList & a = PIStringList()) { name = n; value = v; args = a; } //! \~english Expands the macro body with arguments from \a args_. //! \~russian Разворачивает тело макроса с аргументами из \a args_. PIString expand(PIString args_, bool * ok = 0) const; //! \~english Macro name. //! \~russian Имя макроса. PIString name; //! \~english Macro replacement text. //! \~russian Текст замены макроса. PIString value; //! \~english Ordered list of macro argument names. //! \~russian Упорядоченный список имен аргументов макроса. PIStringList args; }; //! \~english Parsed member declaration or function signature. //! \~russian Разобранное объявление члена или сигнатура функции. struct PIP_EXPORT Member { Member() { visibility = Global; size = 0; bits = -1; is_type_ptr = false; attributes = NoAttributes; } //! \~english Returns whether the member is declared as a bitfield. //! \~russian Возвращает, объявлен ли член как битовое поле. bool isBitfield() const { return bits > 0; } //! \~english Parsed metadata attached to the member. //! \~russian Разобранные метаданные, привязанные к члену. MetaMap meta; //! \~english Member type or return type. //! \~russian Тип члена или возвращаемый тип. PIString type; //! \~english Member name. //! \~russian Имя члена. PIString name; //! \~english Full textual argument declarations. //! \~russian Полные текстовые объявления аргументов. PIStringList arguments_full; //! \~english Argument types only. //! \~russian Только типы аргументов. PIStringList arguments_type; //! \~english Parsed array dimensions. //! \~russian Разобранные размеры массива. PIStringList dims; //! \~english Member visibility. //! \~russian Видимость члена. Visibility visibility; //! \~english Member attributes. //! \~russian Атрибуты члена. Attributes attributes; //! \~english Indicates that the parsed type is a pointer. //! \~russian Показывает, что разобранный тип является указателем. bool is_type_ptr; //! \~english Parsed size in bytes when available. //! \~russian Разобранный размер в байтах, если он известен. int size; //! \~english Bit count for bitfields, or \c -1 otherwise. //! \~russian Количество бит для битового поля или \c -1 в остальных случаях. int bits; }; //! \~english Parsed class, struct or namespace. //! \~russian Разобранный класс, структура или пространство имен. struct PIP_EXPORT Entity { Entity() { visibility = Global; is_anonymous = false; size = 0; parent_scope = 0; } //! \~english Parsed metadata attached to the entity. //! \~russian Разобранные метаданные, привязанные к сущности. MetaMap meta; //! \~english Entity kind, for example \c class, \c struct or \c namespace. //! \~russian Вид сущности, например \c class, \c struct или \c namespace. PIString type; //! \~english Entity name. //! \~russian Имя сущности. PIString name; //! \~english Source file where the entity was parsed. //! \~russian Исходный файл, в котором была разобрана сущность. PIString file; //! \~english Entity visibility inside its parent scope. //! \~russian Видимость сущности внутри родительской области. Visibility visibility; //! \~english Parsed size in bytes when available. //! \~russian Разобранный размер в байтах, если он известен. int size; //! \~english Indicates that the entity was declared without a name. //! \~russian Показывает, что сущность объявлена без имени. bool is_anonymous; //! \~english Immediate containing entity, or \c nullptr for the root scope. //! \~russian Непосредственная содержащая сущность или \c nullptr для корневой области. Entity * parent_scope; //! \~english Direct base entities. //! \~russian Непосредственные базовые сущности. PIVector parents; //! \~english Parsed member functions. //! \~russian Разобранные функции-члены. PIVector functions; //! \~english Parsed data members. //! \~russian Разобранные поля данных. PIVector members; //! \~english Typedefs declared inside the entity. //! \~russian Typedef-объявления внутри сущности. PIVector typedefs; }; //! \~english Parsed enumerator entry. //! \~russian Разобранный элемент перечисления. struct PIP_EXPORT EnumeratorInfo { EnumeratorInfo(const PIString & n = PIString(), int v = 0, const MetaMap & m = MetaMap()) { name = n; value = v; meta = m; } //! \~english Parsed metadata attached to the enumerator. //! \~russian Разобранные метаданные, привязанные к элементу перечисления. MetaMap meta; //! \~english Enumerator name. //! \~russian Имя элемента перечисления. PIString name; //! \~english Enumerator value. //! \~russian Значение элемента перечисления. int value; }; //! \~english Parsed enumeration. //! \~russian Разобранное перечисление. struct PIP_EXPORT Enum { Enum(const PIString & n = PIString()) { name = n; } //! \~english Parsed metadata attached to the enum. //! \~russian Разобранные метаданные, привязанные к перечислению. MetaMap meta; //! \~english Enum name. //! \~russian Имя перечисления. PIString name; //! \~english Parsed enumerators. //! \~russian Разобранные элементы перечисления. PIVector members; }; //! \~english Parses one source file and optionally follows its includes. //! \~russian Разбирает один исходный файл и при необходимости следует по его include-зависимостям. void parseFile(const PIString & file, bool follow_includes = true); //! \~english Parses several source files into one parser state. //! \~russian Разбирает несколько исходных файлов в одном состоянии разборщика. void parseFiles(const PIStringList & files, bool follow_includes = true); //! \~english Parses source text provided directly in memory. //! \~russian Разбирает исходный текст, переданный напрямую из памяти. void parseFileContent(PIString fc); //! \~english Adds a directory to the include search list. //! \~russian Добавляет каталог в список поиска include-файлов. void includeDirectory(const PIString & dir) { includes << dir; } //! \~english Adds a custom preprocessor definition before parsing. //! \~russian Добавляет пользовательское препроцессорное определение перед разбором. void addDefine(const PIString & def_name, const PIString & def_value) { custom_defines << Define(def_name, def_value); } //! \~english Returns whether an enum with \a name was parsed. //! \~russian Возвращает, было ли разобрано перечисление с именем \a name. bool isEnum(const PIString & name); //! \~english Finds a parsed entity by its full name. //! \~russian Ищет разобранную сущность по ее полному имени. Entity * findEntityByName(const PIString & en); //! \~english Returns the set of files already processed by the parser. //! \~russian Возвращает набор файлов, уже обработанных разборщиком. PIStringList parsedFiles() const { return PIStringList(proc_files.toVector()); } //! \~english Returns the file detected as the main translation unit. //! \~russian Возвращает файл, определенный как основной единицей трансляции. PIString mainFile() const { return main_file; } //! \~english Returns the synthetic global scope entity. //! \~russian Возвращает синтетическую сущность глобальной области. const PICodeParser::Entity * global() const { return &root_; } //! \~english Returns the maximum number of macro substitution passes. //! \~russian Возвращает максимальное число проходов подстановки макросов. int macrosSubstitutionMaxIterations() const { return macros_iter; } //! \~english Sets the maximum number of macro substitution passes. //! \~russian Задает максимальное число проходов подстановки макросов. void setMacrosSubstitutionMaxIterations(int value) { macros_iter = value; } //! \~english Parsed \c define directives, including built-in and custom ones. //! \~russian Разобранные директивы \c define, включая встроенные и пользовательские. PIVector defines, custom_defines; //! \~english Parsed function-like macros. //! \~russian Разобранные функциональные макросы. PIVector macros; //! \~english Parsed enums from the processed files. //! \~russian Разобранные перечисления из обработанных файлов. PIVector enums; //! \~english Parsed top-level typedef declarations. //! \~russian Разобранные typedef-объявления верхнего уровня. PIVector typedefs; //! \~english Parsed entities discovered in the processed files. //! \~russian Разобранные сущности, найденные в обработанных файлах. PIVector entities; private: void clear(); bool parseFileInternal(const PIString & file, bool follow_includes); bool parseFileContent(PIString & fc, bool main); bool parseDirective(PIString d); Entity * parseClassDeclaration(const PIString & fc); Entity * parseClass(Entity * parent, PIString & fc, bool is_namespace); MetaMap parseMeta(PIString & fc); bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta); Typedef parseTypedef(PIString fc); bool parseMember(Entity * parent, PIString & fc); int extractMemberBits(PIString & fc); void restoreTmpTemp(Member * e); void restoreTmpMeta(Member * e); MetaMap maybeMeta(PIString & fc); bool macroCondition(const PIString & mif, PIString mifcond); bool isDefineExists(const PIString & dn); double defineValue(const PIString & dn); void replaceMeta(PIString & dn); PIString procMacros(PIString fc); double procMacrosCond(PIString fc); bool isDeclaration(const PIString & fc, int start, int * end); bool isMainFile(const PIString & fc); void normalizeEntityNamespace(PIString & n); int macros_iter, anon_num; bool with_includes; PIEvaluator evaluator; PISet proc_files; PIString cur_file, main_file; PIStringList includes; Entity root_; Visibility cur_def_vis; PIString cur_namespace; PIMap tmp_temp; PIMap tmp_meta; }; #endif // PICODEPARSER_H