Cross AST type comparison

Let’s say, there are two translation units called a.cpp and b.cpp, which look the following:

// old.cpp:
void f() { throw 1.2; }
// new.cpp:
void f() { throw 1.2; }

I want to check whether f() throws the same type exception in both source files.

I build the AST for both source files and extract the FunctionDecl for f() from both of them. Then I use clang::tidy::utils::ExceptionAnalyzer to extract the exception types. This utility extracts a set of Type*s, but these pointers store different addresses even though they point to the same types. So at the end I have two Type *s, which both point to double but ptr1 != ptr2 and Types aren’t comparable either.

One workaround I could find is calling QualType::getAsString() on the canonical types and comparing the strings.

What is the proper way to handle this problem?

You can use StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) to check if the two f() functions are “structurally” equivalent.
Or even better, you could use IsEquivalentExceptionSpec() from ASTStructuralEquivalence.cpp if that was exposed in the public API of the structural equivalence check.

Other than that, ODRHash might be an alternative solution, but I am not sure if that does compute the exception specifier into the hash.

You can use StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) to check if the two f() functions are “structurally” equivalent.

It seems that this method can only detect exceptions if they are the part of an exception specifier. E.g.: void f() throws(double) { throw 1.2; }.

As a result isEquivalent() returns true for these functions:

void f() { throw 1.2; }
void f() { throw 3; }

The other overload with QualTypes however works for comparing the Type *s returned by the ExceptionAnalyzer from the different ASTs.

Thank you for the answer!