рдкрд╛рдпрдерди рдореЗрдВ libclang рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ C ++ рдХреЛрдб рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг

рдПрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд C ++ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░, рдореБрдЭреЗ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред C ++ рдореЗрдВ рдПрдХ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рд░рди-рдЯрд╛рдЗрдо рдкреНрд░рдХрд╛рд░ рд╕реВрдЪрдирд╛ (RTTI) рддрдВрддреНрд░ рд╣реИ, рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдкрд╣рд▓рд╛ рд╡рд┐рдЪрд╛рд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдерд╛, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рд▓рд┐рдЦрдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рдкреВрд░реЗ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рддрдВрддреНрд░ рдХреЛ рдЦреАрдВрдЪрдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдЗрд╕рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдХреЗрд╡рд▓ рдПрдХ рдЫреЛрдЯрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдЪрд╛рд╣рд┐рдП рдерд╛ред рдореИрдВ рд╕реА ++ 17 рдХреА рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХрд╛ рдЕрднреНрдпрд╛рд╕ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдореИрдВ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рдерд╛ред


рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ рдореИрдВ рдкрд╛рдпрдерди рдореЗрдВ рд▓рд┐рдмрдХрд▓рдВрдЧ рдкрд╛рд░реНрд╕рд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рд╕реНрддреБрдд рдХрд░реВрдВрдЧрд╛ред


рдореИрдВ рдЕрдкрдирд╛ RTTI рдЬрд╛рд░реА рдХрд░рдиреЗ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЛ рдЫреЛрдбрд╝ рджреВрдВрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдХреЗрд╡рд▓ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдмрд┐рдВрджреБ рд╣реИрдВ:


  • рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧ рдпрд╛ рд╕рдВрд░рдЪрдирд╛ рдЬреЛ рдЕрдкрдиреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреА рд╣реИ рдЙрд╕реЗ IRttiTypeIdProvider рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛;
  • рдкреНрд░рддреНрдпреЗрдХ рдРрд╕реЗ рд╡рд░реНрдЧ рдореЗрдВ (рдпрджрд┐ рдпрд╣ рд╕рд╛рд░ рдирд╣реАрдВ рд╣реИ), рддреЛ рдЖрдкрдХреЛ RTTI_HAS_TYPE_ID рдореИрдХреНрд░реЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдЬреЛ RttiTypeId рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЯрд╛рдЗрдк рдкреЙрдЗрдВрдЯрд░ рдХреЗ рд╕реНрдерд┐рд░ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк MyClass::__typeId рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рд░рдирдЯрд╛рдЗрдо рдкрд░ рдХрдХреНрд╖рд╛ рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрджрд╛рд╣рд░рдг getTypeId рд╡рд┐рдзрд┐ getTypeId рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдПрдХ рдЙрджрд╛рд╣рд░рдг:


 #pragma once #include <string> #include "RTTI.h" struct BaseNode : public IRttiTypeIdProvider { virtual ~BaseNode() = default; bool bypass = false; }; struct SourceNode : public BaseNode { RTTI_HAS_TYPE_ID std::string inputFilePath; }; struct DestinationNode : public BaseNode { RTTI_HAS_TYPE_ID bool includeDebugInfo = false; std::string outputFilePath; }; struct MultiplierNode : public BaseNode { RTTI_HAS_TYPE_ID double multiplier; }; struct InverterNode : public BaseNode { RTTI_HAS_TYPE_ID }; 

рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдВрднрд╡ рдерд╛, рд▓реЗрдХрд┐рди рдХреБрдЫ рд╕рдордп рдмрд╛рдж рдореБрдЭреЗ рдЗрди рд╡рд░реНрдЧреЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ: рдлрд╝реАрд▓реНрдб рдирд╛рдо, рдСрдлрд╕реЗрдЯ рдФрд░ рдЖрдХрд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред рдпрд╣ рд╕рдм рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдмреНрдпрд╛рдЬ рдХреА рд╢реНрд░реЗрдгреА рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╡рд┐рд╡рд░рдг рдХрд╣реАрдВ рди рдХрд╣реАрдВ .cpp рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╣реЛред рдХрдИ рдореИрдХреНрд░реЛрдЬрд╝ рд▓рд┐рдЦреЗ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕рдХреЗ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЗрд╕рдХреЗ рдЦреЗрддреЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рдЗрд╕ рддрд░рд╣ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛рдиреЗ рд▓рдЧрд╛:


 RTTI_PROVIDER_BEGIN_TYPE(SourceNode) ( RTTI_DEFINE_FIELD(SourceNode, bypass) RTTI_DEFINE_FIELD(SourceNode, inputFilePath) ) RTTI_PROVIDER_END_TYPE() RTTI_PROVIDER_BEGIN_TYPE(DestinationNode) ( RTTI_DEFINE_FIELD(DestinationNode, bypass) RTTI_DEFINE_FIELD(DestinationNode, includeDebugInfo) RTTI_DEFINE_FIELD(DestinationNode, outputFilePath) ) RTTI_PROVIDER_END_TYPE() RTTI_PROVIDER_BEGIN_TYPE(MultiplierNode) ( RTTI_DEFINE_FIELD(MultiplierNode, bypass) RTTI_DEFINE_FIELD(MultiplierNode, multiplier) ) RTTI_PROVIDER_END_TYPE() RTTI_PROVIDER_BEGIN_TYPE(InverterNode) ( RTTI_DEFINE_FIELD(InverterNode, bypass) ) 

рдФрд░ рдпрд╣ рдХреЗрд╡рд▓ 4 рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╣реИред рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреА рдкрд╣рдЪрд╛рди рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ?


  1. рдХреЛрдб рдХреЗ рдкреЗрд╕реНрдЯ рдмреНрд▓реЙрдХреЛрдВ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдХреЙрдкреА рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдлрд╝реАрд▓реНрдб рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╕рдордп рд╡рд░реНрдЧ рдХреЗ рдирд╛рдо рдХреА рджреГрд╖реНрдЯрд┐ рдЦреЛ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рдордиреЗ рдмреНрд▓реЙрдХ рдХреЛ SourceNode рд╕реЗ DestinationNode рдкрд░ рдХреЙрдкреА рдХрд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди SourceNode рдХреЛ рдЧрдВрддрд╡реНрдп рдлрд╝реАрд▓реНрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреВрд▓ рдЧрдП)ред рдХрдВрдкрд╛рдЗрд▓рд░ рд╕рдмрдХреБрдЫ рдЫреЛрдбрд╝ рджреЗрдЧрд╛, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЧрд┐рд░ рднреА рдирд╣реАрдВ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд╝реАрд▓реНрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЧрд▓рдд рд╣реЛрдЧреАред рдФрд░ рдпрджрд┐ рдЖрдк рдРрд╕реЗ рдХреНрд╖реЗрддреНрд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдбреЗрдЯрд╛ рд░рд┐рдХреЙрд░реНрдб рдХрд░рддреЗ рд╣реИрдВ рдпрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ, рддреЛ рд╕рдм рдХреБрдЫ рд╡рд┐рд╕реНрдлреЛрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ (рд╡реЗ рдРрд╕рд╛ рдХрд╣рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЦреБрдж рдЗрд╕рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛)ред
  2. рдпрджрд┐ рдЖрдк рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝реАрд▓реНрдб рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рддреЛ рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЬрд╛рдиреЗ рдЪрд╛рд╣рд┐рдПред
  3. рдпрджрд┐ рдЖрдк рдХрдХреНрд╖рд╛ рдореЗрдВ рдлрд╝реАрд▓реНрдб рдХреЗ рдирд╛рдо рдпрд╛ рдХреНрд░рдо рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рдХреЛрдб рдХреЗ рдЗрд╕ рдлрд╝реБрдЯрдХреНрд▓реЙрде рдореЗрдВ рдирд╛рдо рдФрд░ рдСрд░реНрдбрд░ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдпрд╛рдж рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд▓реЗрдХрд┐рди рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд▓рд┐рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЬрдм рдЗрд╕ рддрд░рд╣ рдХреЗ рдиреАрд░рд╕ рдХреЛрдб рдХреА рдмрд╛рдд рдЖрддреА рд╣реИ, рддреЛ рдореИрдВ рдмрд╣реБрдд рдЖрд▓рд╕реА рд╣реЛ рдЬрд╛рддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХрд╛ рддрд░реАрдХрд╛ рдЦреЛрдЬрддрд╛ рд╣реВрдВ, рднрд▓реЗ рд╣реА рдЗрд╕реЗ рдореИрдиреБрдЕрд▓ рд▓реЗрдЦрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рдФрд░ рдкреНрд░рдпрд╛рд╕ рд▓рдЧреЗред


рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╛рдпрдерди рдореЗрд░реА рдорджрдж рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдо рд╕рд┐рд░реНрдл рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ C ++ рд╕реЛрд░реНрд╕ рдХреЛрдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдирд┐рд░реНрдорд┐рдд рдЯреЗрдХреНрд╕реНрдЯ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реИрдВред рд╣рдореЗрдВ C ++ рдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ libclang рд╣рдореЗрдВ рдЗрд╕рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред


рд▓рд┐рдВрдмрд╛рдВрдЧ рдХреНрд▓реИрдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рд╕реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИред рд╕рд╛рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЯреНрд░реА (рдПрдПрд╕рдЯреА) рдореЗрдВ рд╕реНрд░реЛрдд рдХреЛрдб рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдкреАрдЖрдИ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдкрд╣рд▓реЗ рд╕реЗ рдкрд╛рд░реНрд╕ рдПрдПрд╕рдЯреАрдПрд╕ рд▓реЛрдб рдХрд░рдирд╛, рдПрдПрд╕рдЯреАрдПрд╕ рдХреЛ рд▓реЛрдб рдХрд░рдирд╛, рдПрдПрд╕рдЯреА рдХреЗ рднреАрддрд░ рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП рднреМрддрд┐рдХ рд╕реНрд░реЛрдд рд╕реНрдерд╛рдиреЛрдВ рдХреА рдореИрдкрд┐рдВрдЧ, рдФрд░ рдЕрдиреНрдп рдХреНрд▓реИрдВрдЧ рдЯреВрд▓рд╕реЗрдЯред

рд╡рд┐рд╡рд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд▓рд┐рдмрдХреНрд▓реИрдВрдЧ рдПрдХ рд╕реА-рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдкрд╛рдпрдерди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдПрдХ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдкреБрд╕реНрддрдХрд╛рд▓рдп (рдмрд╛рдЗрдВрдбрд┐рдВрдЧ) рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рд╕рдордп рдкрд╛рдпрдерди рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреМрдкрдЪрд╛рд░рд┐рдХ рд╕реЗ рдпрд╣ https://github.com/ethanhs/clang рд╣реИ ред


рдкреИрдХреЗрдЬ рдкреНрд░рдмрдВрдзрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:


 pip install clang 

рд╕реНрд░реЛрдд рдХреЛрдб рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреБрд╕реНрддрдХрд╛рд▓рдп рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди libclang рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ libclang рдкреНрд░рд▓реЗрдЦрди рдХреЛ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдХрдИ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдпрд╣ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЯрд┐рдкреНрдкрдгреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕рдм рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреНрдпреЛрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдиреНрдпрдерд╛ рдирд╣реАрдВред рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдХреЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдмрдХреНрд▓рд╛рдВрдЧ рдХрд╛ рдЕрдиреБрднрд╡ рдерд╛, рдЙрдирдХреЗ рдкрд╛рд╕ рдХрдо рд╕рд╡рд╛рд▓ рд╣реЛрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдореЗрд░реЗ рдкрд╛рд╕ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдРрд╕рд╛ рдЕрдиреБрднрд╡ рдирд╣реАрдВ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдХреЛрдб рдореЗрдВ рдЧрд╣рд░реА рдЦреБрджрд╛рдИ рдХрд░рдирд╛ рдФрд░ рдбрд┐рдмрдЧрд░ рдореЗрдВ рдЪрд╛рд░реЛрдВ рдУрд░ рдкреНрд░рд╣рд╛рд░ рдХрд░рдирд╛ рдерд╛ред


рдЖрдЗрдП рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ:


 import clang.cindex index = clang.cindex.Index.create() translation_unit = index.parse('my_source.cpp', args=['-std=c++17']) for i in translation_unit.get_tokens(extent=translation_unit.cursor.extent): print (i.kind) 

рдпрд╣рд╛рдВ рдПрдХ рдкреНрд░рдХрд╛рд░ рдХрд╛ Index рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ C ++ рдХреЛрдб рд╡рд╛рд▓реА рдлрд╛рдЗрд▓ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИред parse рд╡рд┐рдзрд┐ TranslationUnit рдпреВрдирд╛рдЗрдЯ рдХреА рдПрдХ рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рддреА рд╣реИ, рдпрд╣ рдХреЛрдб рдЯреНрд░рд╛рдВрд╕рд▓реЗрд╢рди рдХреА рдПрдХ рдЗрдХрд╛рдИ рд╣реИред TranslUnit рдПрдХ AST рдиреЛрдб рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ AST рдиреЛрдб рд╕реНрд░реЛрдд рдХреЛрдб (рд╕реАрдорд╛) рдореЗрдВ рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рд╣рдо TranslUnit рдореЗрдВ рд╕рднреА рдЯреЛрдХрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд▓реВрдк рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрди рдЯреЛрдХрди рдХреЗ рдкреНрд░рдХрд╛рд░ (рдкреНрд░реЙрдкрд░реНрдЯреА) рдХреЛ рдкреНрд░рд┐рдВрдЯ рдХрд░рддреЗ рд╣реИрдВред


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд C ++ рдХреЛрдб рд▓реЗрдВ:


 class X {}; class Y {}; class Z : public X {}; 

рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдирд┐рд╖реНрдкрд╛рджрди рдкрд░рд┐рдгрд╛рдо
 TokenKind.KEYWORD TokenKind.IDENTIFIER TokenKind.PUNCTUATION TokenKind.PUNCTUATION TokenKind.PUNCTUATION TokenKind.KEYWORD TokenKind.IDENTIFIER TokenKind.PUNCTUATION TokenKind.PUNCTUATION TokenKind.PUNCTUATION TokenKind.KEYWORD TokenKind.IDENTIFIER TokenKind.PUNCTUATION TokenKind.KEYWORD TokenKind.IDENTIFIER TokenKind.PUNCTUATION TokenKind.PUNCTUATION TokenKind.PUNCTUATION 

рдЕрдм рдЖрдЗрдП AST рдХреЛ рд╕рдВрднрд╛рд▓реЗрдВред рдкрд╛рдпрдерди рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рджреЗрдЦреЗрдВ рдХрд┐ рд╣рдореЗрдВ рдХреНрд▓реИрдВрдЧ рдкрд╛рд░реНрд╕рд░ рд╕реЗ рдХреНрдпрд╛ рдЙрдореНрдореАрдж рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред рдПрдПрд╕рдЯреА рдбрдВрдк рдореЛрдб рдореЗрдВ рдХреНрд▓реИрдВрдЧ рдЪрд▓рд╛рдПрдБ:


 clang++ -cc1 -ast-dump my_source.cpp 

рдЖрдЬреНрдЮрд╛ рдХрд╛ рдкрд░рд┐рдгрд╛рдо
 TranslationUnitDecl 0xaaaa9b9fa8 <<invalid sloc>> <invalid sloc> |-TypedefDecl 0xaaaa9ba880 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128' | `-BuiltinType 0xaaaa9ba540 '__int128' |-TypedefDecl 0xaaaa9ba8e8 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128' | `-BuiltinType 0xaaaa9ba560 'unsigned __int128' |-TypedefDecl 0xaaaa9bac48 <<invalid sloc>> <invalid sloc> implicit __NSConstantString '__NSConstantString_tag' | `-RecordType 0xaaaa9ba9d0 '__NSConstantString_tag' | `-CXXRecord 0xaaaa9ba938 '__NSConstantString_tag' |-TypedefDecl 0xaaaa9e6570 <<invalid sloc>> <invalid sloc> implicit __builtin_ms_va_list 'char *' | `-PointerType 0xaaaa9e6530 'char *' | `-BuiltinType 0xaaaa9ba040 'char' |-TypedefDecl 0xaaaa9e65d8 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list 'char *' | `-PointerType 0xaaaa9e6530 'char *' | `-BuiltinType 0xaaaa9ba040 'char' |-CXXRecordDecl 0xaaaa9e6628 <my_source.cpp:1:1, col:10> col:7 referenced class X definition | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param | | |-MoveConstructor exists simple trivial needs_implicit | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param | | |-MoveAssignment exists simple trivial needs_implicit | | `-Destructor simple irrelevant trivial needs_implicit | `-CXXRecordDecl 0xaaaa9e6748 <col:1, col:7> col:7 implicit class X |-CXXRecordDecl 0xaaaa9e6800 <line:3:1, col:10> col:7 class Y definition | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param | | |-MoveConstructor exists simple trivial needs_implicit | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param | | |-MoveAssignment exists simple trivial needs_implicit | | `-Destructor simple irrelevant trivial needs_implicit | `-CXXRecordDecl 0xaaaa9e6928 <col:1, col:7> col:7 implicit class Y `-CXXRecordDecl 0xaaaa9e69e0 <line:5:1, col:21> col:7 class Z definition |-DefinitionData pass_in_registers empty standard_layout trivially_copyable trivial literal has_constexpr_non_copy_move_ctor can_const_default_init | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param | |-MoveConstructor exists simple trivial needs_implicit | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param | |-MoveAssignment exists simple trivial needs_implicit | `-Destructor simple irrelevant trivial needs_implicit |-public 'X' `-CXXRecordDecl 0xaaaa9e6b48 <col:1, col:7> col:7 implicit class Z 

рдпрд╣рд╛рдБ CXXRecordDecl рдиреЛрдб рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдЬреЛ рд╡рд░реНрдЧ рдШреЛрд╖рдгрд╛ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИред рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдРрд╕реЗ рдиреЛрдб рд╣реИрдВред рдРрд╕рд╛ рдЗрд╕рд▓рд┐рдП рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╕рдВрджрд░реНрдн рдиреЛрдбреНрд╕ рдХреЛ рдЙрд╕реА рдкреНрд░рдХрд╛рд░ рд╕реЗ рджрд░реНрд╢рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдиреЛрдбреНрд╕ рдЬреЛ рдЕрдиреНрдп рдиреЛрдбреНрд╕ рдХреЗ рд▓рд┐рдВрдХ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмреЗрд╕ рдХреНрд▓рд╛рд╕ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╕рдВрджрд░реНрдн рд╣реИред рдЗрд╕ рдкреЗрдбрд╝ рдХреЛ рдЕрд▓рдЧ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдПрдХ рд╡рд┐рд╢реЗрд╖ рдзреНрд╡рдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрджрд░реНрдн рдиреЛрдб рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЕрдм рд╣рдо рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░реЗрдЧреА:


 import clang.cindex import typing index = clang.cindex.Index.create() translation_unit = index.parse('my_source.cpp', args=['-std=c++17']) def filter_node_list_by_node_kind( nodes: typing.Iterable[clang.cindex.Cursor], kinds: list ) -> typing.Iterable[clang.cindex.Cursor]: result = [] for i in nodes: if i.kind in kinds: result.append(i) return result all_classes = filter_node_list_by_node_kind(translation_unit.cursor.get_children(), [clang.cindex.CursorKind.CLASS_DECL, clang.cindex.CursorKind.STRUCT_DECL]) for i in all_classes: print (i.spelling) 

рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо spelling рд╕рдВрдкрддреНрддрд┐ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИред рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдиреЛрдбреНрд╕ рдХреЗ рд▓рд┐рдП, spelling рдореВрд▓реНрдп рдореЗрдВ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрд╢реЛрдзрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╡рд░реНрдЧ рдпрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреА рдШреЛрд╖рдгрд╛ рдХреЗ рд▓рд┐рдП, рдЗрд╕рдореЗрдВ рд╕рдВрд╢реЛрдзрдХ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдирд╛рдо рд╣реЛрддрд╛ рд╣реИред


рдирд┐рд╖реНрдкрд╛рджрди рдкрд░рд┐рдгрд╛рдо:


 X Y Z 

рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХрд░рддреЗ рд╕рдордп, рдПрдПрд╕рдЯреА рдХреНрд▓реИрдВрдЧ рднреА #include рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреБрдбрд╝реА рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИред рд╕реНрд░реЛрдд рдореЗрдВ #include <string> рдЬреЛрдбрд╝рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВ, рдФрд░ рдбрдВрдк рдореЗрдВ рдЖрдкрдХреЛ 84 рд╣рдЬрд╛рд░ рд▓рд╛рдЗрдиреЗрдВ рдорд┐рд▓реЗрдВрдЧреА, рдЬреЛ рдЬрд╛рд╣рд┐рд░ рддреМрд░ рдкрд░ рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рдмрд╣реБрдд рд╣реИред


рдХрдорд╛рдВрдб рд▓рд╛рдЗрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдРрд╕реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдПрдПрд╕рдЯреА рдбрдВрдк рдХреЛ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП, рд╕рднреА #include рдХреЛ рд╣рдЯрд╛рдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдЬрдм рдЖрдк рдПрдПрд╕рдЯреА рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдмреНрдпрд╛рдЬ рдХреА рдлрд╛рдЗрд▓ рдореЗрдВ рдкрджрд╛рдиреБрдХреНрд░рдо рдФрд░ рдкреНрд░рдХрд╛рд░реЛрдВ рдХрд╛ рдПрдХ рд╡рд┐рдЪрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЙрдиреНрд╣реЗрдВ рд╡рд╛рдкрд╕ рд▓рд╛рдПрдВред


рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдореЗрдВ, рдХреЗрд╡рд▓ рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд AST рдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдФрд░ #include рдорд╛рдзреНрдпрдо рд╕реЗ рдХрдиреЗрдХреНрдЯ рдирд╣реАрдВ рд╣реЛрдиреЗ рдкрд░, рдЖрдк рдлрд╝рд╛рдЗрд▓ рджреНрд╡рд╛рд░рд╛ рдирд┐рдореНрди рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ:


 def filter_node_list_by_file( nodes: typing.Iterable[clang.cindex.Cursor], file_name: str ) -> typing.Iterable[clang.cindex.Cursor]: result = [] for i in nodes: if i.location.file.name == file_name: result.append(i) return result ... filtered_ast = filter_by_file(translation_unit.cursor, translation_unit.spelling) 

рдЕрдм рдЖрдк рдЦреЗрддреЛрдВ рдХреА рдирд┐рдХрд╛рд╕реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдЧрд▓рд╛, рдореИрдВ рдкреВрд░реНрдг рдХреЛрдб рджреВрдВрдЧрд╛ рдЬреЛ рдХрд┐ рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдлрд╝реАрд▓реНрдб рдХреА рдПрдХ рд╕реВрдЪреА рддреИрдпрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкрд╛рда рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдХреЛрдИ рд╡рд┐рд╢реЗрд╖ рдмрд╛рдд рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреЛрдИ рдЯрд┐рдкреНрдкрдгреА рдирд╣реАрдВред


рдкреВрд░реНрдг рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛрдб
 import clang.cindex import typing index = clang.cindex.Index.create() translation_unit = index.parse('Input.h', args=['-std=c++17']) def filter_node_list_by_file( nodes: typing.Iterable[clang.cindex.Cursor], file_name: str ) -> typing.Iterable[clang.cindex.Cursor]: result = [] for i in nodes: if i.location.file.name == file_name: result.append(i) return result def filter_node_list_by_node_kind( nodes: typing.Iterable[clang.cindex.Cursor], kinds: list ) -> typing.Iterable[clang.cindex.Cursor]: result = [] for i in nodes: if i.kind in kinds: result.append(i) return result def is_exposed_field(node): return node.access_specifier == clang.cindex.AccessSpecifier.PUBLIC def find_all_exposed_fields( cursor: clang.cindex.Cursor ): result = [] field_declarations = filter_node_list_by_node_kind(cursor.get_children(), [clang.cindex.CursorKind.FIELD_DECL]) for i in field_declarations: if not is_exposed_field(i): continue result.append(i.displayname) return result source_nodes = filter_node_list_by_file(translation_unit.cursor.get_children(), translation_unit.spelling) all_classes = filter_node_list_by_node_kind(source_nodes, [clang.cindex.CursorKind.CLASS_DECL, clang.cindex.CursorKind.STRUCT_DECL]) class_inheritance_map = {} class_field_map = {} for i in all_classes: bases = [] for node in i.get_children(): if node.kind == clang.cindex.CursorKind.CXX_BASE_SPECIFIER: referenceNode = node.referenced bases.append(node.referenced) class_inheritance_map[i.spelling] = bases for i in all_classes: fields = find_all_exposed_fields(i) class_field_map[i.spelling] = fields def populate_field_list_recursively(class_name: str): field_list = class_field_map.get(class_name) if field_list is None: return [] baseClasses = class_inheritance_map[class_name] for i in baseClasses: field_list = populate_field_list_recursively(i.spelling) + field_list return field_list rtti_map = {} for class_name, class_list in class_inheritance_map.items(): rtti_map[class_name] = populate_field_list_recursively(class_name) for class_name, field_list in rtti_map.items(): wrapper_template = """\ RTTI_PROVIDER_BEGIN_TYPE(%s) ( %s ) RTTI_PROVIDER_END_TYPE() """ rendered_fields = [] for f in field_list: rendered_fields.append(" RTTI_DEFINE_FIELD(%s, %s)" % (class_name, f)) print (wrapper_template % (class_name, ",\n".join(rendered_fields))) 

рдпрд╣ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЗрд╕ рдмрд╛рдд рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░рддреА рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдХреНрд▓рд╛рд╕ рдореЗрдВ рдЖрд░рдЯреАрдЯреАрдЖрдИ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдЖрд░рдЯреАрдЯреАрдЖрдИ рдХреЗ рдмрд┐рдирд╛ рд╡рд░реНрдЧреЛрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдмреНрд▓реЙрдХ рдХреЛ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╣рдЯрд╛рдирд╛ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рддрд┐рдкрд╣рд┐рдпрд╛ рд╣реИред


рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдХреЛрдИ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдФрд░ рд╕рдордп рдмрдЪрд╛рдПрдЧрд╛ред рд╕рднреА рдХреЛрдб GitHub рдкрд░ рдкреЛрд╕реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред

Source: https://habr.com/ru/post/hi439270/


All Articles