直接从 header 文件生成的 clang AST 中缺少信息

Missing information in clang AST generated directly from a header file

Win10-64, clang v11.0.0, VS2019

我的基本问题是,为什么我的 header 文件中大部分自定义代码的 AST 信息在直接从 header 文件生成的 AST 中丢失,但存在于实现文件中其中包括 header(以及如何解决问题)。除非我在转录和简化下面的代码时打错了字,否则它会正确编译 link 和 运行。当我使用

为 MyClass.h header 文件生成 AST 时
clang.exe -Xclang -ast-dump -fsyntax-only MyClass.h

它包含通常包含的 iostream header 文件的数千行,但我的代码只有以下两行:

|-VarDecl 0xb7fd7f0 <C:\temp\MyClass.h:8:1, col:7> col:7 invalid MyClass 'int'
`-VarDecl 0xb7fd840 <line:16:1, col:13> col:13 invalid MyClass 'void'

但是,所有 MyClass.h header AST 信息都存在于为我的实现文件生成的 AST 中。作为解决方法,我暂时将 header 的扩展名从 .h 更改为 .cpp 以生成 AST。虽然这有效,但它很麻烦。是否有一些额外的命令行选项可以解决这种情况?下面是我的两个测试文件的实际代码:

在文件 main.cpp 中:

#include "MyClass.h"
int main()
{
   MyClass myObject;
   myObject.CalcResult();
   myObject.DispValue();
}

在文件 MyClass.h 中:

#ifndef MYCLASS_H
#define MYCLASS_H
#include <iostream>
const double PCT = .01;

class MyClass
{
   double value;
public:
   double CalcResult() const {return PCT * value;}
   void DispValue() const;
};
inline void MyClass::DispValue() const
{
   std::cout << value << "\n";
}
#endif

Clang(如 gcc)将扩展名为 .h 的文件视为 C 语言文件。如果您使用扩展名 .hh.hpp.H 之一,clang(和 gcc)会将文件视为 C++ 文件。如果不想更改文件名,可以使用 -x 选项告诉 clang 忽略文件扩展名并将文件视为 C++:

clang.exe -x c++ -Xclang -ast-dump -fsyntax-only MyClass.h

将其编译为 C 文件不会为 iostream 的包含产生数千行,至少在我的安装中不会。它只会产生一个错误,因为它在 C 文件的默认包含路径中没有文件 iostream。我想如果它确实找到了头文件,它会产生其他错误消息。

(我现在使用的机器上没有 clang-11,但我用一些旧版本尝试了这个,它给了我预期的结果。我会用 clang-11 试试明天。)