================
@@ -7,108 +7,228 @@
 
//===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/SARIFDiagnostic.h"
-#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/FileManager.h"
+#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/Sarif.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/Locale.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <string>
 
 namespace clang {
 
+// In sarif mode,
+// a diagnostics 'group' have 1 top-level error/warning and several sub-level
+// notes. For example:
+//
+// error: static assertion failed.
+//   note: in instantiation of 'cat::meow'.
+//     note: because concept 'paper_tiger' would be invalid.
+// error: invalid operands to binary expression 'cat::meow' and 'dog::wolf'.
+//   note: candidate function not viable.
+//     note: no known conversion from 'tiger::meooooow' to 'cat::meow'
+//   note: candidate function ignored.
+//     note: constraints not satisfied.
+//   note: ... (candidates)
+//     note: ... (reasons)
+//   note: too many candidates.
+// error: too many errors occured, stopping now.
----------------
anonymouspc wrote:

Source file `test.cpp`:
```cpp
#include <map>
#include <ranges>
#include <vector>

int main () {
    std::vector<int>() | std::ranges::to<std::map<int,int>>(); // This stupid 
statement will produce huge diagnostics. I love it when testing sarif.
    42 + std::vector<int>(); // A simple overload failure.
}
```

Command:
```sh
clang++ -std=c++26 test.cpp -o test
```

Output:
```
In file included from test.cpp:2:
In file included from 
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/ranges:441:
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:142:19: 
error: 
      static assertion failed: ranges::to: unable to convert to the given 
container type.
  142 |     static_assert(__always_false<_Container>, "ranges::to: unable to 
convert to the given contain...
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:218:20: 
note: 
      in instantiation of function template specialization 
'std::ranges::to<std::map<int, int>,
      std::vector<int>>' requested here
  218 |   { return ranges::to<_Container>(std::forward<_Range>(__range), 
std::forward<_Tail>(__tail)...); };
      |                    ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__type_traits/invoke.h:74:47:
 note: 
      in instantiation of function template specialization 
'std::ranges::to()::(anonymous
      class)::operator()<std::vector<int>>' requested here
   74 | struct 
__invoke_result_impl<__void_t<decltype(__builtin_invoke(std::declval<_Args>()...))>,
 _Args...> {
      |                                               ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__type_traits/invoke.h:82:1:
 note: 
      during template argument deduction for class template partial 
specialization
      
'__invoke_result_impl<__void_t<decltype(__builtin_invoke(std::declval<_Args>()...))>,
 _Args...>'
      [with _Args = <(lambda at
      
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:214:20) &, 
std::vector<int>>]
   82 | using __invoke_result_t _LIBCPP_NODEBUG = typename 
__invoke_result<_Args...>::type;
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__type_traits/invoke.h:82:1:
 note: 
      in instantiation of template class 'std::__invoke_result_impl<void, 
(lambda at
      
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:214:20) &, 
std::vector<int>>'
      requested here
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__type_traits/invoke.h:387:1:
 note: 
      in instantiation of template type alias '__invoke_result_t' requested here
  387 | using invoke_result_t = __invoke_result_t<_Fn, _Args...>;
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__functional/invoke.h:27:53:
 note: 
      (skipping 17 contexts in backtrace; use -ftemplate-backtrace-limit=0 to 
see all)
   27 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 
invoke_result_t<_Fn, _Args...>
      |                                                     ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__concepts/invocable.h:27:21:
 note: 
      while substituting template arguments into constraint expression here
   27 | concept invocable = requires(_Fn&& __fn, _Args&&... __args) {
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   28 |   std::invoke(std::forward<_Fn>(__fn), std::forward<_Args>(__args)...); 
// not required to be equality preserving
      |   
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   29 | };
      | ~
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/range_adaptor.h:71:12:
 note: 
      while checking the satisfaction of concept
      'invocable<std::ranges::__pipeable<std::__bind_back_t<(lambda at
      
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:214:20), 
std::tuple<>>>,
      std::vector<int>>' requested here
   71 |   requires invocable<_Closure, _Range>
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/range_adaptor.h:71:12:
 note: 
      while substituting template arguments into constraint expression here
   71 |   requires invocable<_Closure, _Range>
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:6:24: note: while checking constraint satisfaction for template
      'operator|<std::vector<int>, 
std::ranges::__pipeable<std::__bind_back_t<(lambda at
      
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:214:20), 
std::tuple<>>>>'
      required here
    6 |     std::vector<int>() | std::ranges::to<std::map<int,int>>();
      |                        ^
test.cpp:6:24: note: while substituting deduced template arguments into function
      template 'operator|' [with _Range = std::vector<int>, _Closure =
      __pipeable<std::__bind_back_t<(lambda at
      
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:214:20), 
std::tuple<>>>]
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:142:19: 
note: 
      because 'std::map<int, int>' does not satisfy '__always_false'
  142 |     static_assert(__always_false<_Container>, "ranges::to: unable to 
convert to the given contain...
      |                   ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__ranges/to.h:76:26: 
note: 
      because 'false' evaluated to false
   76 | concept __always_false = false;
      |                          ^
test.cpp:6:24: warning: ignoring return value of function declared with 
'nodiscard'
      attribute [-Wunused-result]
    6 |     std::vector<int>() | std::ranges::to<std::map<int,int>>();
      |     ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:7:8: error: invalid operands to binary expression
      ('int' and 'std::vector<int>')
    7 |     42 + std::vector<int>();
      |     ~~ ^ ~~~~~~~~~~~~~~~~~~
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__iterator/reverse_iterator.h:303:1:
 note: 
      candidate template ignored: could not match 'reverse_iterator' against 
'std::vector'
  303 | operator+(typename reverse_iterator<_Iter>::difference_type __n, const 
reverse_iterator<_Iter>& __x) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__iterator/wrap_iter.h:228:1:
 note: 
      candidate template ignored: could not match '__wrap_iter' against 
'std::vector'
  228 | operator+(typename __wrap_iter<_Iter1>::difference_type __n, 
__wrap_iter<_Iter1> __x) _NOEXCEPT {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/__iterator/move_iterator.h:317:1:
 note: 
      candidate template ignored: could not match 'move_iterator' against 
'std::vector'
  317 | operator+(iter_difference_t<_Iter> __n, const move_iterator<_Iter>& __x)
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3735:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3735 | operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3742:1: note: 
      candidate template ignored: could not match 'const _CharT *' against 'int'
 3742 | operator+(const _CharT* __lhs, const basic_string<_CharT, _Traits, 
_Allocator>& __rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3751:1: note: 
      candidate template ignored: could not match 'basic_string' against 
'std::vector'
 3751 | operator+(_CharT __lhs, const basic_string<_CharT, _Traits, 
_Allocator>& __rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3758:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3758 | operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, const 
_CharT* __rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3764:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3764 | operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 
_CharT __rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3772:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3772 | operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs,
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3779:1: note: 
      candidate template ignored: could not match 'basic_string' against 
'std::vector'
 3779 | operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3790:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3790 | operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const 
basic_string<_CharT, _Traits, ...
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3796:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3796 | operator+(const basic_string<_CharT, _Traits, _Allocator>& __lhs, 
basic_string<_CharT, _Traits, _...
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3802:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3802 | operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, 
basic_string<_CharT, _Traits, _Alloc...
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3808:1: note: 
      candidate template ignored: could not match 'const _CharT *' against 'int'
 3808 | operator+(const _CharT* __lhs, basic_string<_CharT, _Traits, 
_Allocator>&& __rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3814:1: note: 
      candidate template ignored: could not match 'basic_string' against 
'std::vector'
 3814 | operator+(_CharT __lhs, basic_string<_CharT, _Traits, _Allocator>&& 
__rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3821:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3821 | operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, const 
_CharT* __rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3827:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3827 | operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs, _CharT 
__rhs) {
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3838:1: note: 
      candidate template ignored: could not match 'basic_string<_CharT, 
_Traits, _Allocator>' against
      'int'
 3838 | operator+(basic_string<_CharT, _Traits, _Allocator>&& __lhs,
      | ^
/opt/homebrew/Cellar/llvm/21.1.8/bin/../include/c++/v1/string:3845:1: note: 
      candidate template ignored: could not match 'basic_string' against 
'std::vector'
 3845 | operator+(type_identity_t<basic_string_view<_CharT, _Traits>> __lhs,
      | ^
1 warning and 2 errors generated
```

Treelized into:
```
error: static assertion failed
  note: in instantiation of ...
    note: in instantiation of ...
      note: (many notes and many indents)
        note: because 'std::map<int, int>' does not satisfy '__always_false'
          note: because 'false' evaluated to false
error: invalid operands to binary expression
  note: candidate 1 (reverse_iterator + std::vector)
  note: candidate 2 (__wrap_iter + std::vector)
  note: candidate 3 (...)
  note: candidate n
```

https://github.com/llvm/llvm-project/pull/174106
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to