Search code examples
clangabstract-syntax-tree

Missing information in clang AST generated directly from a header file


Win10-64, clang v11.0.0, VS2019

My basic question is why the AST information for most of the custom code in my header file is missing from the AST generated directly from that header file, but is present in the implementation file that includes that header (and how to fix the problem). Unless I've made a typo when transcribing and simplifying the code below, it does compile, link, and run correctly. When I generate an AST for the MyClass.h header file using

clang.exe -Xclang -ast-dump -fsyntax-only MyClass.h

it contains the usual thousands of lines for the included iostream header file, but only the following two lines for my code:

|-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'

However, all of the MyClass.h header AST information is present in the AST generated for my implementation file. As a workaround I've been temporarily changing the header's extension from .h to .cpp to generate the AST. While that works, it's a kluge. Is there some additional command line option that will remedy this situation? Below is my actual code for my two test files:

In file main.cpp:

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

In file 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

Solution

  • Clang (like gcc) treats files with extension .h as C language files. If you use one of the extensions .hh, .hpp or .H, clang (and gcc) will treat the file as being in C++. If you don't want to change the filename, you could tell clang to ignore the file extension and treat the file as C++ using the -x option:

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

    Compiling it as a C file does not produce thousands of lines for the include of iostream, at least not on my installation. It just produces an error, because it doesn't have the file iostream in the default include paths for C files. I imagine that if it did find the header file, it would produce other error messages.

    (I don't have clang-11 on the machine I'm using right now, but I tried this with some older versions and it gave me the result I expected. I'll try it with clang-11 tomorrow.)