Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/build/reference/advanced-property-page.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ Specifies the full version of the MSVC toolset that's used to build the project.

Specifies the full version of the LLVM toolset that's used to build the project. This property is available when **LLVM (clang-cl)** is selected as the platform toolset, starting in Visual Studio 2019 version 16.9. For more information, see [Set a custom LLVM toolset version](..\clang-support-msbuild.md#custom_llvm_toolset).

### Enable MSVC Structured Output

Specifies whether to enable [structured SARIF output](sarif-output.md), which enables the [**Problem Details** window](/visualstudio/ide/reference/problem-details-window) and hierarchical output in the [**Output** window](/visualstudio/ide/reference/output-window) in Visual Studio.

## C++/CLI Properties

### Common Language Runtime support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ This table contains an alphabetical list of compiler options. For a list of comp
| [`/EP`](ep-preprocess-to-stdout-without-hash-line-directives.md) | Copies preprocessor output to standard output. |
| [`/errorReport`](errorreport-report-internal-compiler-errors.md) | Deprecated. [Windows Error Reporting (WER)](/windows/win32/wer/windows-error-reporting) settings control error reporting. |
| [`/execution-charset`](execution-charset-set-execution-character-set.md) | Set execution character set. |
| [`/experimental:log`](experimental-log.md) | Enables experimental structured SARIF output. |
| [`/experimental:module`](experimental-module.md) | Enables experimental module support. |
| [`/exportHeader`](module-exportheader.md) | Create the header units files (*`.ifc`*) specified by the input arguments. |
| [`/external:anglebrackets`](external-external-headers-diagnostics.md) | Treat all headers included via `<>` as external. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ Experimental options may only be supported by certain versions of the compiler.

| Option | Purpose |
|--|--|
| [`/experimental:log`](experimental-log.md) | Enables experimental structured SARIF output. |
| [`/experimental:module`](experimental-module.md) | Enables experimental module support. |

## Deprecated and removed compiler options
Expand Down
48 changes: 48 additions & 0 deletions docs/build/reference/experimental-log.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: "/experimental:log (Structured SARIF diagnostics)"
description: "Use the /experimental:log compiler option to output experimental structured SARIF output for diagnostics."
ms.date: 10/26/2023
f1_keywords: ["/experimental:log"]
helpviewer_keywords: ["/experimental:log", "SARIF", "structured diagnostics"]
---
# `/experimental:log` (Structured SARIF diagnostics)

Output [SARIF](https://sarifweb.azurewebsites.net/) diagnostics to the specified file. For more information, see [Structured SARIF Diagnostics](sarif-output.md).

## Syntax

> **`/experimental:log`** *filename*

## Arguments

*filename*

Where to output SARIF diagnostics. The `.sarif` suffix is added to *filename* to produce the final filename at which to store the resulting SARIF diagnostics. The space between `/experimental:log` and *filename* is optional. Paths that include spaces must be enclosed in double quotes. *filename* may name a relative or absolute path.

## Remarks

This option is available starting in Visual Studio 2022 version 17.8.

Diagnostics are also output as text to the console as usual.

### To set this compiler option in the Visual Studio development environment

1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).

1. Select the specific project **Configuration** and **Platform** for which you want to change the property. You can also choose **"All Configurations"** and **"All Platforms"**.

1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.

1. Modify the **Additional Options** property, and then choose **OK**.

## Example

The following command produces SARIF information for the entire compilation in the `diags.sarif` file in the current directory:

```cmd
CL /experimental:logdiags main.cpp other.cpp
```

## See also

[Structured SARIF Diagnostics](sarif-output.md)
151 changes: 151 additions & 0 deletions docs/build/reference/sarif-output.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
---
description: "How to make the compiler output diagnostics as structured SARIF"
title: "Structured SARIF Diagnostics"
ms.date: "10/26/2023"
author: tartanllama
ms.author: sybrand
manager: mluparu
helpviewer_keywords: ["SARIF", "structured diagnostics"]
---

# Structured SARIF Diagnostics

The MSVC compiler can be made to output diagnostics as [SARIF](https://sarifweb.azurewebsites.net/) (Static Analysis Results Interchange Format). SARIF is a machine-readable JSON-based format.

There are two ways to make the MSVC compiler produce SARIF diagnostics:

- Pass the `/experimental:log` switch on the command line. See the [documentation for `/experimental:log`](experimental-log.md) for details.
- Launch `cl.exe` programatically and set the `SARIF_OUTPUT_PIPE` environment variable to retrieve SARIF blocks through a pipe.

## Retrieving SARIF through a pipe

Tools that consume SARIF from the MSVC compiler while a compilation is in progress use a pipe. See the documentation for [`CreatePipe`](/windows/win32/api/namedpipeapi/nf-namedpipeapi-createpipe) for details about creating Windows pipes.

To retrieve SARIF through a pipe, set the `SARIF_OUTPUT_PIPE` environment variable to be the UTF-16-encoded integer representation of the `HANDLE` to the write end of the pipe, then launch `cl.exe`. SARIF is sent along the pipe as follows:

- When a new diagnostic is available, it is written to this pipe.
- Diagnostics are written to the pipe one-at-a-time rather than as an entire SARIF object.
- Each diagnostic is represented by a [JSON-RPC 2.0](https://www.jsonrpc.org/) message of type [Notification](https://www.jsonrpc.org/specification#notification:~:text=as%20binary%20fractions.-,4.1%20Notification,-A%20Notification%20is).
- The JSON-RPC message is prefixed with a `Content-Length` header with the form `Content-Length: <N>` followed by two newlines, where `<N>` is the length of the following JSON-RPC message in bytes.
- The JSON-RPC message and header are both encoded in UTF-8.
- This JSON-RPC-with-header format is compatible with [vs-streamjsonrpc](https://github.com/microsoft/vs-streamjsonrpc).
- The method name for the JSON-RPC call is `OnSarifResult`.
- The call has a single parameter that is encoded [by-name](https://www.jsonrpc.org/specification#parameter_structures) with the parameter name `result`.
- The value of the argument is a single `result` object as specified by the [SARIF Version 2.1 standard](https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790888).

### Example

Here's an example of a JSON-RPC SARIF result produced by `cl.exe`:

```json
Content-Length: 334

{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}{"jsonrpc":"2.0","method":"OnSarifResult","params":{"result":{"ruleId":"C1034","level":"fatal","message":{"text":"iostream: no include path set"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"file:///C:/Users/sybrand/source/repos/cppcon-diag/cppcon-diag/cppcon-diag.cpp"},"region":{"startLine":1,"startColumn":10}}}]}}}
```

## SARIF result data

The compiler outputs SARIF that may include additional information to represent the nested structure of some diagnostics. A diagnostic (represented by a `result` SARIF object) may contain a "diagnostic tree" of additional information in its `relatedLocations` field. This tree is encoded using a SARIF [property bag](https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os-complete.html#_Toc141790698) as follows:

A `location` object's `properties` field may contain a `nestingLevel` property whose value is the depth of this location in the diagnostic tree. If a location doesn't have a `nestingLevel` specified, the depth is considered to be `0` and this location is a child of the root diagnostic represented by the `result` object containing it. Otherwise, if the value is greater than the depth of the location immediately preceding this location in the `relatedLocations` field, this location is a child of that location. Otherwise, this location is a sibling of the closest preceding `location` in the `relatedLocations` field with the same depth.

### Example

Consider the following code:

```cpp
struct dog {};
struct cat {};

void pet(dog);
void pet(cat);

struct lizard {};

int main() {
pet(lizard{});
}
```

When this code is compiled, the compiler produces the following `result` object (`physicalLocation` properties have been removed for brevity):

```json
{
"ruleId": "C2665",
"level": "error",
"message": {
"text": "'pet': no overloaded function could convert all the argument types"
},
"relatedLocations": [
{
"id": 0,
"message": {
"text": "could be 'void pet(cat)'"
}
},
{
"id": 1,
"message": {
"text": "'void pet(cat)': cannot convert argument 1 from 'lizard' to 'cat'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 2,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 3,
"message": {
"text": "or 'void pet(dog)'"
}
},
{
"id": 4,
"message": {
"text": "'void pet(dog)': cannot convert argument 1 from 'lizard' to 'dog'"
},
"properties": {
"nestingLevel": 1
}
},
{
"id": 5,
"message": {
"text": "No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called"
},
"properties": {
"nestingLevel": 2
}
},
{
"id": 6,
"message": {
"text": "while trying to match the argument list '(lizard)'"
}
}
]
}
```

The logical diagnostics tree produced from the messages in this `result` object is:

- 'pet': no overloaded function could convert all the argument types
- could be 'void pet(cat)'
- 'void pet(cat)': cannot convert argument 1 from 'lizard' to 'cat
- No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
- or 'void pet(dog)'
- 'void pet(dog)': cannot convert argument 1 from 'lizard' to 'dog'
- No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
- while trying to match the argument list '(lizard)'

## See also

[`/experimental:log` (Enable structured SARIF diagnostics)](experimental-log.md)
4 changes: 4 additions & 0 deletions docs/build/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ items:
href: ../build/reference/errorreport-report-internal-compiler-errors.md
- name: /execution-charset (Set execution character set)
href: ../build/reference/execution-charset-set-execution-character-set.md
- name: /experimental:log
href: ../build/reference/experimental-log.md
- name: /experimental:module
href: ../build/reference/experimental-module.md
- name: /experimental:preprocessor
Expand Down Expand Up @@ -859,6 +861,8 @@ items:
href: ../build/reference/zs-syntax-check-only.md
- name: /ZW (Windows Runtime compilation)
href: ../build/reference/zw-windows-runtime-compilation.md
- name: Structured SARIF output
href: ../build/reference/sarif-output.md
- name: Unicode support in the compiler and linker
href: ../build/reference/unicode-support-in-the-compiler-and-linker.md
- name: MSVC linker reference
Expand Down