当前位置: 首页 > news >正文

国内体育新闻最新消息网站做常规优化

国内体育新闻最新消息,网站做常规优化,园林在线设计平台,网站怎么弄二维码ASTImporter:合并ClangAST ASTImporter类是Clang的核心库AST库的一部分.它导入一个ASTContext的节点到另一个ASTContext中. 这里,假设你对ClangAST有基本了解.如果你想了解有关AST结构的更多信息,见ClangAST简介.匹配ClangAST在此. 介绍 ASTContext包含长期有的,可在文件的整…ASTImporter:合并ClangAST ASTImporter类是Clang的核心库AST库的一部分.它导入一个ASTContext的节点到另一个ASTContext中. 这里,假设你对ClangAST有基本了解.如果你想了解有关AST结构的更多信息,见ClangAST简介.匹配ClangAST在此. 介绍 ASTContext包含长期有的,可在文件的整个分析语义过程中引用的AST节点(如类型和声明).有时,最好使用多个ASTContext. 如,想在同一个Clang工具中,解析多个不同的文件.如果可像解析每个文件产生一个AST一样的,查看生成的AST集,就会很方便. ASTImporter提供了可从一个ASTContext复制声明或类型到另一个ASTContext的方法.从中导入的环境叫从环境或源环境; 而到环境或目标环境为导入进的环境. ASTImporter库的现有用户,是交叉翻译单元(CTU)静态分析和LLDB式解析器.如果在另一个,(TU)翻译单元中找到函数定义,则CTU静态分析导入函数定义. 这样,分析就可突破单个TU限制.LLDB的式命令解析用户定义的式,为其创建一个ASTContext,然后从从调试信息(DWARF等)的AST导入中获得缺失定义. 导入算法 导入一个AST节点,会复制该节点到目标ASTContext中.为什么必须复制节点,而不能插入该节点指针到目标环境中呢?一个原因是from环境可能比to环境更长久. 此外,如果节点有相同地址,ClangAST会认为节点(或节点的某些属性)是等效的! 导入算法必须确保不同翻译单元中,结构等效的节点,不会在合并的AST中重复.如,如果在两个翻译单元中,包含向量模板(#includevector)的定义,则合并的AST应该只有一个代表模板的节点. 此外,必须发现(ODR)一个定义规则的违规行为.如,如果两个翻译单元中,有相同名字的类定义,但其中一个定义包含不同数量的字段. 因此,要查找现有定义,然后检查这些节点上的结构等价性.以下伪代码演示了导入机制的底层: //导入的伪代码(!): ErrorOrDecl Import(Decl *FromD) {Decl *ToDecl nullptr;Found声明List 用FromD相同名,在to环境中查找所有声明for (auto FoundDecl : Found声明List) {if (StructurallyEquivalent声明(FoundDecl, FromD)) {ToDecl FoundDecl;Mark FromD as imported;break;} else {Report ODR violation;return error;}}if (Found声明List is empty) {导入依赖声明及to声明的类型ToDecl 在to环境创建新AST;Mark FromD as imported;}return ToDecl; }如果两个AST节点在结构上是等效的,则它们是等效的. 1,内置类型和引用相同类型,如int和int在结构上是等价的, 2,函数类型及其所有参数在结构上有等效类型, 3,记录类型及其所有字段(按其定义顺序)有相同的标识名和结构上等效的类型, 4,变量或函数声明,且有相同标识名,且它们的类型在结构上是等效的. 可把定义结构等价类似地扩展到模板. 应用接口 创建一个使用ASTImporter类的工具!首先,从虚文件构建两个AST;虚文件的内容是从串字面合成的: std::unique_ptrASTUnit ToUnit buildASTFromCode(, to.cc); //空文件 std::unique_ptrASTUnit FromUnit buildASTFromCode(R(class MyClass {int m1;int m2;};),from.cc);第一个AST对应(to)为空的目标环境,第二个AST对应源(from)环境.接着,定义一个匹配from环境中的MyClass的匹配器: auto Matcher cxxRecordDecl(hasName(MyClass)); auto *From getFirstDeclCXXRecordDecl(Matcher, FromUnit);现在创建导入器并导入: ASTImporter Importer(ToUnit-getASTContext(), ToUnit-getFileManager(), FromUnit-getASTContext(), FromUnit-getFileManager(), /*MinimalImport*/true); llvm::ExpectedDecl * ImportedOrErr Importer.Import(From);Import调用返回llvm::Expected,因此,必须检查是否有错误.细节,见错误处理文档. if (!ImportedOrErr) {llvm::Error Err ImportedOrErr.takeError();llvm::errs() ERROR: Err \n;consumeError(std::move(Err));return 1; }如果正确,则可得到底层值.此例中,打印to环境的AST. Decl *Imported *ImportedOrErr; Imported-getTranslationUnitDecl()-dump();因为在导入器的构造器中,设置了最小导入,因此(一旦运行测试工具)AST不包含成员声明. 要想得到成员,所以,用ImportDefinition复制MyClass的整个定义到to环境中.然后再次转储AST. if (llvm::Error Err Importer.ImportDefinition(From)) {llvm::errs() ERROR: Err \n;consumeError(std::move(Err));return 1; } llvm::errs() Imported definition.\n; Imported-getTranslationUnitDecl()-dump();这一次,AST也包含成员了. 如果把导入器设置为执行正常(非最小)导入,则可省去调用ImportDefinition. ASTImporter Importer( .... /*MinimalImport*/false);用正常导入时,会正常导入所有依赖声明.但是,在最小导入下,会不带定义的导入依赖声明,如果稍后需要,必须为每个声明导入它们的定义. 放在一起: #include clang/AST/ASTImporter.h #include clang/ASTMatchers/ASTMatchFinder.h #include clang/ASTMatchers/ASTMatchers.h #include clang/Tooling/Tooling.h using namespace clang; using namespace tooling; using namespace ast_matchers; template typename Node, typename Matcher Node *getFirstDecl(Matcher M, const std::unique_ptrASTUnit Unit) {auto MB M.bind(bindStr); //把待匹配节点绑定到串键.auto MatchRes match(MB, Unit-getASTContext());//至少应该有一个匹配.assert(MatchRes.size() 1);//取第一个匹配及绑定节点.Node *Result const_castNode *(MatchRes[0].template getNodeAsNode(bindStr));assert(Result);return Result; } int main() {std::unique_ptrASTUnit ToUnit buildASTFromCode(, to.cc);std::unique_ptrASTUnit FromUnit buildASTFromCode(R(class MyClass {int m1;int m2;};),from.cc);auto Matcher cxxRecordDecl(hasName(MyClass));auto *From getFirstDeclCXXRecordDecl(Matcher, FromUnit);ASTImporter Importer(ToUnit-getASTContext(), ToUnit-getFileManager(), FromUnit-getASTContext(), FromUnit-getFileManager(), /*MinimalImport*/true);llvm::ExpectedDecl * ImportedOrErr Importer.Import(From);if (!ImportedOrErr) {llvm::Error Err ImportedOrErr.takeError();llvm::errs() ERROR: Err \n;consumeError(std::move(Err));return 1;}Decl *Imported *ImportedOrErr;Imported-getTranslationUnitDecl()-dump();if (llvm::Error Err Importer.ImportDefinition(From)) {llvm::errs() ERROR: Err \n;consumeError(std::move(Err));return 1;}llvm::errs() Imported definition.\n;Imported-getTranslationUnitDecl()-dump();return 0; };假定clang/tools有构建和链接说明,在此扩展CMakeLists.txt: add_clang_executable(astimporter-demo ASTImporterDemo.cpp) clang_target_link_libraries(astimporter-demoPRIVATELLVMSupportclangASTclangASTMatchersclangBasicclangFrontendclangSerializationclangTooling)然后,可构建并执行新工具. $ ninja astimporter-demo ./bin/astimporter-demo导入过程中的错误 一般,源或目标环境都包含声明的定义.但是,有时,两个环境都定义了给定符号.如果这些定义不同,则就有名字冲突,在C中,叫做ODR(一个定义规则)违规. 修改之前编写的工具,并用冲突定义试导入ClassTemplateSpecializationDecl: int main() {std::unique_ptrASTUnit ToUnit buildASTFromCode(R(//主模板template typename Tstruct X {};//显式特化templatestruct Xint { int i; };),to.cc);ToUnit-enableSourceFileDiagnostics();std::unique_ptrASTUnit FromUnit buildASTFromCode(R(//主模板template typename Tstruct X {};//显式特化templatestruct Xint { int i2; };//字段不匹配:^^),from.cc);FromUnit-enableSourceFileDiagnostics();auto Matcher classTemplateSpecializationDecl(hasName(X));auto *From getFirstDeclClassTemplateSpecializationDecl(Matcher, FromUnit);auto *To getFirstDeclClassTemplateSpecializationDecl(Matcher, ToUnit);ASTImporter Importer(ToUnit-getASTContext(), ToUnit-getFileManager(), FromUnit-getASTContext(), FromUnit-getFileManager(), /*MinimalImport*/false);llvm::ExpectedDecl * ImportedOrErr Importer.Import(From);if (!ImportedOrErr) {llvm::Error Err ImportedOrErr.takeError();llvm::errs() ERROR: Err \n;consumeError(std::move(Err));To-getTranslationUnitDecl()-dump();return 1;}return 0; };运行该工具时,会收到以下警告: to.cc:7:14:警告:Xint类型在不同的翻译单元中有不兼容的定义[-Wodr]构Xint{inti;^to.cc:7:27:注意:此处的字段名叫i构Xint{inti;^from.cc:7:27:注意:此处的字段名叫i2structXint{inti2;^注意,因为这些诊断,必须在ASTUnit对象上调用enableSourceFileDiagnostics. 因为无法导入指定的(From)声明,因此返回值中出现错误.AST不包含冲突定义,因此只剩下原始AST. 错误传播 如果在导入给定节点前,有必须先导入的依赖节点,则把与依赖关系关联的导入错误传播到依赖节点.修改前例并导入FieldDecl而不是ClassTemplateSpecializationDecl. auto Matcher fieldDecl(hasName(i2)); auto *From getFirstDeclFieldDecl(Matcher, FromUnit);本例中,可见(getImportDeclErrorIfAny)错误不仅是字段,也与特化相关联: llvm::ExpectedDecl * ImportedOrErr Importer.Import(From); if (!ImportedOrErr) {llvm::Error Err ImportedOrErr.takeError();consumeError(std::move(Err));//检查是否也按错误标记ClassTemplateSpecializationDecl.auto *FromSpec getFirstDeclClassTemplateSpecializationDecl(classTemplateSpecializationDecl(hasName(X)), FromUnit);assert(Importer.getImportDeclErrorIfAny(FromSpec));//顺便,也为FieldDecl设置错误.assert(Importer.getImportDeclErrorIfAny(From));return 1; }污染的AST 可能会在导入依赖节点时,发现错误.但是,那时,已创建了依赖项.这时,不会从to环境中删除现有的错误节点,而是关联一个错误到该节点. 用另一个Y类来扩展前例.此类在to环境中有前向定义,但在from环境中定义它.要想导入定义,但它包含一个类型与to环境中的类型冲突的成员: std::unique_ptrASTUnit ToUnit buildASTFromCode(R(//主模板template typename Tstruct X {};//显式特化templatestruct Xint { int i; };class Y;),to.cc); ToUnit-enableSourceFileDiagnostics(); std::unique_ptrASTUnit FromUnit buildASTFromCode(R(//主模板template typename Tstruct X {};//显式特化templatestruct Xint { int i2; };//字段不匹配:^^class Y { void f() { Xint xi; } };),from.cc); FromUnit-enableSourceFileDiagnostics(); auto Matcher cxxRecordDecl(hasName(Y)); auto *From getFirstDeclCXXRecordDecl(Matcher, FromUnit); auto *To getFirstDeclCXXRecordDecl(Matcher, ToUnit);这一次,为ASTImporterSharedState创建一个拥有to环境关联错误的shared_ptr.注意,可能会有几个不同的ASTImporter对象,从不同的from环境导入,但导入到相同的to环境中; 它们应共享相同的ASTImporterSharedState.注意,必须包含相应的ASTImporterSharedState.h头文件. auto ImporterState std::make_sharedASTImporterSharedState(); ASTImporter Importer(ToUnit-getASTContext(), ToUnit-getFileManager(), FromUnit-getASTContext(), FromUnit-getFileManager(), /*MinimalImport*/false, ImporterState); llvm::ExpectedDecl * ImportedOrErr Importer.Import(From); if (!ImportedOrErr) {llvm::Error Err ImportedOrErr.takeError();consumeError(std::move(Err));//...但是已创建节点.auto *ToYDef getFirstDeclCXXRecordDecl(cxxRecordDecl(hasName(Y), isDefinition()), ToUnit);ToYDef-dump();//在共享状态下,已为ToYDef设置了错误.OptionalASTImportError OptErr ImporterState-getImportDeclErrorIfAny(ToYDef);assert(OptErr);return 1; }如果看一下AST,则可见创建了带定义的Decl,但缺少字段. 不会删除错误节点,因为当错误识别时,再删除节点为时已晚,可能会有对AST中已有节点的其他引用. 这与ClangAST的整体设计原则一致:ClangAST节点(类型,声明,语句,式等)一般按创建后不变设计. 因此,ASTImporter库的用户,应总是在目标环境中,检查待检查节点是否有相关错误.建议跳过有关联错误节点的处理. 使用-ast-merge的Clang前端操作 -ast-mergepch-file命令行开关,可用来从给定的表示源环境的序化AST文件合并.有此开关时,会把源环境的每个顶级AST节点都合并到目标环境中. 如果合并成功,则为声明调用ASTConsumer::HandleTopLevelDecl.这导致可在扩展的AST上执行原始前端操作. C示例 考虑以下三个文件: //bar.h #ifndef BAR_H #define BAR_H int bar(); #endif /*BAR_H*/ //bar.c #include bar.h int bar() {return 41; } //main.c #include bar.h int main() {return bar(); }为两个源文件生成AST文件: $ clang -cc1 -emit-pch -o bar.ast bar.c $ clang -cc1 -emit-pch -o main.ast main.c然后,如果只考虑bar()函数,检查一下合并AST会怎样: $ clang -cc1 -ast-merge bar.ast -ast-merge main.ast /dev/null -ast-dump可检查函数的原型和它的定义是否合并到同一个再声明链中.更重要的是,还合并了第三个原型声明到链中. 函数的合并方式是,如果原型引用相同类型,则添加原型到再声明链中,但只能有一个定义. 前两个声明是bar.ast,第三个声明是main.ast. 现在,从合并的AST创建一个目标文件: $ clang -cc1 -ast-merge bar.ast -ast-merge main.ast /dev/null -emit-obj -o main.o Next, we may call the linker and execute the created binary file. $ clang -o a.out main.o $ ./a.out $ echo $ 41 $C示例 在C时,生成AST文件及调用前端方式有点不同.假设有这三个文件: //foo.h #ifndef FOO_H #define FOO_H struct foo {virtual int fun(); }; #endif /*FOO_H*/ //foo.cpp #include foo.h int foo::fun() {return 42; } //main.cpp #include foo.h int main() {return foo().fun(); }生成AST文件,合并它们,创建可执行文件,然后运行它: $ clang -x c-header -o foo.ast foo.cpp $ clang -x c-header -o main.ast main.cpp $ clang -cc1 -x c -ast-merge foo.ast -ast-merge main.ast /dev/null -ast-dump $ clang -cc1 -x c -ast-merge foo.ast -ast-merge main.ast /dev/null -emit-obj -o main.o $ clang -o a.out main.o $ ./a.out $ echo $ 42 $
http://www.pierceye.com/news/753576/

相关文章:

  • 对电子商务网站建设与管理的理解福州市建设工程造价管理网站
  • 网站登录系统内部错误建设机械网站案例分析
  • 网络营销网站建设培训乔拓云的品牌推广方案
  • 狼雨seo网站河北省建设集团有限公司网站首页
  • 如何建双注册网站一嗨租车网站建设的功能特色
  • 陕西正天建设有限公司网站wordpress 筛选
  • 产品展示网站方案2022年国内重大新闻
  • 网站的支付接口对接怎么做深圳品牌网站建设服务
  • 哈尔滨网站快速排名网站采集被降权
  • 做网站要钱吗学校网站建设调查问卷
  • 重庆网站建设招标网站建设网站建设教程
  • 权威的广州h5网站seo网站分析工具
  • 美食网站要怎么做游戏优化大师下载安装
  • vip解析网站怎么做的做网站需要注册商标多少类
  • 一般做网站宽高多少网页调用 wordpress 图片编辑器
  • 简述网站建设的基本过程word模板免费下载网站
  • 页面好看的蛋糕网站wordpress路由插件
  • 网站建站四种方案深圳网站建设维护
  • 企业网站优化的方案游戏网页设计图片
  • 烟台html5网站建设wordpress主题 亚马逊
  • 个人网站做电商wordpress.php扩张
  • c2c电子商务网站定制开发校园网建设网站特色
  • 企业网站制作公司有哪些做手机网站公司
  • 怎么做flash网站设计惠州做网站公司哪家好
  • 网站开发文档下载餐饮vi设计一套多少钱
  • 平湖网站建设公司克正规的网店平台有哪些
  • 网站建设销售求职网络营销推广引流方法
  • 深圳网站建设官网网站背景素材
  • 建设部网站安全考核证书查询平面设计的素材网站
  • 郑州制作个人网站网站个人备案做企业网站