Extend #pragma clang __debug dump to support not only single identifier, but an expression as well. This makes it possible to test ADL and overload resolution directly, without being creative to make them observable via diagnostics (e.g. when over.match.best is involved). This implementation has a known limitation of not supporting dependent expressions properly, but it's quite useful even without such support.
Details
- Reviewers
aaron.ballman - Group Reviewers
Restricted Project - Commits
- rG467ed2798772: [clang] Extend pragma dump to support expressions
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thanks for this! You should add test coverage for the changes, especially around things like dependent expressions, ADL use, etc. Also, the changes need a release note and the new functionality should be explicitly documented.
clang/lib/Parse/ParsePragma.cpp | ||
---|---|---|
723–727 | I think you should have another variant of ActOnPragmaDump that does the actual dumping, instead of doing it from the parser. I think we should not try to dump a dependent expression (to support those, I think we need to create a new AST node for the pragma so that we can transform it from TreeTransform.h and perform the dump on the non-dependent expression -- not certain if we want to handle that now, or if we want it to be an error to use this pragma with a dependent expression). |
Thank you for reviewing this!
Despite having a dozen of #pragma __debug directives, none of them are tested neither mentioned in any kind of documentation, including release notes. Are you sure about this? If so, what is the right place to put them into?
clang/lib/Parse/ParsePragma.cpp | ||
---|---|---|
723–727 |
Would it be fine to do it like this: Actions.ActOnPragmaDump(E), where E is the result of ParseExpression()?
As I mentioned in summary, dependent expressions are out of scope of this patch. How can I test whether expression is dependent? |
Yeah, we've been very bad about documenting our implementation-defined behaviors and I've been on a push to change that moving forward for about the past year or so. You don't have to document all of the debug pragmas by any means, but getting some basic documentation up for the pragma being worked on is good incremental progress. I'd recommend adding the tests to clang/test/Preprocessor and adding the documentation to clang\docs\LanguageExtensions.rst.
clang/lib/Parse/ParsePragma.cpp | ||
---|---|---|
723–727 |
I think it'd make sense to do Actions.ActOnPragmaDump(Tok.getLocation(), ParseExpression()); so that we have the location of the pragma token itself in addition to the expression result for the argument.
Expr::isValueDependent() and Expr::isTypeDependent() |
- Diagnose dependent expressions
- Move AST dumping from parser to sema
- Add documentation
- Add tests
You should also add a release note to clang/docs/ReleaseNotes.rst so users know about the new functionality.
clang/docs/LanguageExtensions.rst | ||
---|---|---|
4926 | ||
4930–4937 | ||
clang/include/clang/Basic/DiagnosticLexKinds.td | ||
658–661 | We can use a select here so we only need one new diagnostic. This should be moved to DiagnosticParseKinds.td because it's emitted from the parser, not the lexer. | |
clang/lib/Parse/ParsePragma.cpp | ||
15–16 | ||
730–735 | ||
clang/test/AST/ast-dump-lookups.cpp | ||
101 | You should add the newline back to the end of the file. I'd also like to see a test case where the expression has errors, like: #pragma clang __debug dump this is nonsense and where the expression causes an instantiation: template <typename T> struct S { static constexpr const T *str = "string"; }; template <> struct S<wchar_t> { static constexpr const wchar_t *str = L"wide string"; }; void func() { #pragma clang __debug dump S<wchar_t>::str; } |
Thank you for review!
clang/lib/Parse/ParsePragma.cpp | ||
---|---|---|
15–16 | I'm using warn_pragma_debug_unexpected_argument and warn_pragma_debug_missing_argument from there as well, and not just added diagnostics. What should I do about that? Copying them over to DiagnosticParseKinds.td doesn't work. | |
730–735 | I see quite a lot of items inside ExprDependence. Are you sure we don't miss any corner cases by using isValueDependent() to select between value- and type-dependent diagnostic text? |
clang/lib/Parse/ParsePragma.cpp | ||
---|---|---|
15–16 | Ah, those should move into DiagnosticCommonKinds.td under the // Parse && Lex heading, then they should be available from here as well without the extra include. | |
730–735 | I was trying to think of a case where we'd run into problems, but I can't come up with one, so I believe we're fine here. |
clang/lib/Parse/ParsePragma.cpp | ||
---|---|---|
730–735 | Apparently, we should do it the other way round, because An id-expression is value-dependent if: — it is type-dependent (temp.dep.constexpr/2.2). I observe that in one of the tests I added, T{} is TypeValueInstantiation. |
- Handle expressions as unevaluated operands
- Numerous fixes to documentation wording
- Add release notes entry
- Prevent generic "unknown argument" diagnostic from being issued when other more specific diagnostics have been emitted
- Add more tests