How to assign a Custom Diagnostic IDs in Clang Tool

I want to create a fixed sets of IDs for error messages in Clang tool. So I can put them into tool documentation.

Is it possible to somehow assign a fixed ID for diagnostic? DiagnosticEngine::getCustomDiagID() generates ID automatically, so I have no control on IDs.

Should I probably instantiate my own DiagnosticEngine instead of using one from AstContext ?


Looks like DiagnosticEngine does not allow to be instantiated with User-supplied IDs.
The problem is that DiagnosticIDs is not an interface to IDs database, but rather a final class not designed for inheritance.

So I don’t find a way how Clang diagnostic library can be reused by 3rd party tool.

Probably I’m just thinking in wrong direction. Why do I need to have fixed IDs, instead I should probably have fixed error/warning names?

Are you trying to put the actual numerical value in the documentation? That won’t work since it’s based on the enum value that gets computed at compile time – actually via tablegen – and changes over time as diagnostics are added/removed.

Tooling may already do this, but if not, just create your own enum that starts at the first available value, clang::diag::DIAG_UPPER_LIMIT, and go from there. Then you can publish and use those enum values, e.g., MyTool::Some_Diag. Take a look at how new id numbers are generated and use the same technique, e.g.:

If you need a string you can pass on the command line, you can create your own mapping.


Btw, you still need to call DiagnosticEngine::getCustomDiagID(), but you can use your new enum to access the new id.

Thanks, this works for me!

I failed to ask what sort of tool you were writing and assumed it was standalone and didn’t include any other components that may also call DiagnosticEngine::getCustomDiagID(). If that’s not the case, e.g., plugins or clang-tidy checkers, then you shouldn’t rely on your set of id’s starting at clang::diag::DIAG_UPPER_LIMIT+1.

However, if you map them to a string anyway, there’s no need to create your own contiguous enum.

Tool is standalone. But yes, map is what I ended up with.

Approach with DIAG_UPPER_LIMIT turned out to be not nice in other way: there is no way to specify ID and FormatString in same place. So code with enum is not very readable.

So the only approach that works well is to map your own IDs to getCustomDiagID IDs.


What I’ve found out is that getCustomDiagID takes reference to C-Style array as a parameter. Not a StringRef. So it’s really inconvenient to use:
I can’t declare FormatStrings in one place, and generate IDs in another place.

It mostly seems to be used on the fly. Take a look at how it’s used in clang-tidy and see if that’ll work for you.

While I don’t quite follow your question - you might be interested in this change I’m working on (well, taken a bit of a break, but will be coming back to):