C++代码的符号表是否包含函数名称和类名?

use*_*750 5 c++ compiler-construction function class-names symbol-table

我一直在搜索有关C++代码的符号表是否包含函数名称和类名的各种帖子.我可以在帖子上找到的东西是它取决于编译器的类型,

如果它在一次通过中编译代码,则它不需要在符号表中存储类名和子程序名

但如果它是一个多遍编译器,它可以添加有关它遇到的类及其子例程的信息,以便它可以进行参数类型检查并发出有意义的错误消息.

我无法理解它是否真的依赖于编译器?我假设编译器(对于C++代码)会在表中放置带有类名的函数名,无论它是单通道还是多通道编译器.它如何依赖传球?我没有这么棒的知识.此外,任何人都可以显示一个简单的C++类的示例符号表,它会是什么样的(带有类名的函数名)?

Ira*_*ter 7

大多数编译器教科书都会告诉您有关符号表的信息,并经常向您展示有关适度复杂语言的详细信息,例如Pascal.您将无法在教科书中找到有关C++符号表的信息; 太神秘了.

我们为DMS Software Reengineering Toolkit提供完整的C++ 14前端.它解析C++,构建详细的AST,并执行名称和类型解析,包括构建精确的符号表.

以下是我们的教程中有关如何使用DMS的幻灯片,重点介绍C++符号表结构.

OP专门询问了关于课程会发生什么的看法.下图显示了左上角的小型C++程序.图的其余部分显示了框,它们代表我们称之为"符号空间"(或"范围"),它们本质上是将符号名称(每个框列出它拥有的符号)映射到DMS知道该符号的信息的哈希表(定义的源文件位置,引用定义的AST节点列表,以及表示类型的复杂联合,并且可能反过来指向其他类型).箭头表示符号空间是如何连接的; 从空间A到空间B的箭头表示"范围A包含在范围B内".通常是符号空间查找过程,在范围A中搜索符号x,如果在A中找不到x,将继续在范围B中搜索.您将注意到箭头用整数编号; 这会告诉搜索机器首先查看编号最小的父作用域,然后尝试使用较大数字的箭头搜索作用域.这就是范围的排序方式(注意C类继承自A和B; C类中字段的任何查找,如"b"将被强制首先查看A的范围,然后在B的范围内查找.这样,就实现了C++查找规则.

请注意,类名称记录在(唯一)全局名称空间中,因为它们是在顶级声明的.如果它们已在某个显式命名空间中定义,则命名空间将具有其自己的相应符号空间,用于记录声明的类,并且命名空间本身将记录在全局符号空间中.

C++符号表:类透视

OP没有询问函数体的符号表是什么样的,但我恰好也有一个说明性的幻灯片,下面也是如此.符号空间的工作方式相同.此幻灯片中显示的是符号空间与其表示的范围区域之间的链接.该链接实际上是通过与符号空间相关联的指针实现的,相应的AST(s,命名空间定义可以分散在多个位置).

请注意,在这种情况下,函数名称记录在全局名称空间中,因为它是在顶级声明的.如果已在类的范围内定义,则函数名称将记录在类主体的符号空间中(在上图中).

C++符号表:功能透视图

作为一般规则,符号表的组织方式的细节完全取决于编译器以及设计者的选择.在我们的例子中,我们设计了一个非常通用的符号表管理包,因为我们计划(并且已经)使用相同的包以统一的方式处理多种语言(C,C++,Java,COBOL,几种遗留语言).但是,符号空间和继承的抽象结构必须在C++编译器中以基本相同的方式实现; 毕竟,他们必须对相同的信息进行建模.我期待GCC和Clang编译器中的类似结构(好吧,整数编号的继承弧,也许不是:)

实际上,编译器有多少"通过"并不重要.它几乎具有建造这些结构来记住它知道的符号,一通,整个传递.

虽然构建C++解析器本身非常困难,但构建这样的符号表要困难得多.这项工作使构建C++解析器的工作相形见绌.我们的C++名称解析器是由DMS编译和执行的250K SLOC属性 - 语法代码.获得细节权利是一个巨大的麻烦; C++参考手册是庞大的,令人困惑的,事实分散在整个文档的各个地方,并且在各种各样的地方它是矛盾的(我们试图向委员会发送关于此的投诉)和/或编译器之间的不一致(我们有GCC的版本和Visual Studio 201x).

2017年3月更新:现在有C++ 2014的符号表.2018年6月更新:现在有C++ 2017的符号表.