Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Компилятор MSVC можно сделать для вывода диагностика как SARIF (формат обмена статическими результатами анализа). SARIF — это формат на основе JSON, доступный для машинного чтения.
Существует два способа создания ДИАГНОСТИКА компилятора MSVC:
- Передайте переключатель
/experimental:logв командной строке. Дополнительные сведения см. в документации/experimental:log. - Запустите
cl.exeпрограммно и задайтеSARIF_OUTPUT_PIPEпеременную среды для получения блоков SARIF через канал.
Извлечение SARIF через канал
Средства, использующие SARIF из компилятора MSVC во время компиляции, используют канал. Дополнительные сведения о создании каналов Windows см. в документации CreatePipe .
Чтобы получить SARIF через канал, задайте SARIF_OUTPUT_PIPE переменную среды в виде целого числа HANDLE в кодировке UTF-16 для конца записи, а затем запустите cl.exe. SARIF отправляется по каналу следующим образом:
- Когда доступна новая диагностика, она записывается в этот канал.
- Диагностика записывается в канал один раз, а не как весь объект SARIF.
- Каждая диагностика представлена сообщением JSON-RPC 2.0 типа Notification.
- Сообщение JSON-RPC префиксируется заголовком с формой
Content-LengthContent-Length: <N>, за которой следует две новые строки, где<N>длина следующего сообщения JSON-RPC в байтах. - Сообщение JSON-RPC и заголовок кодируются в UTF-8.
- Этот формат JSON-RPC-with-header совместим с vs-streamjsonrpc.
- Имя метода для вызова
OnSarifResultJSON-RPC. - Вызов имеет один параметр, закодированный по имени с именем
resultпараметра. - Значение аргумента — это один
resultобъект, указанный стандартом SARIF версии 2.1.
Пример
Ниже приведен пример результата JSON-RPC SARIF, созданного следующим cl.exeобразом:
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
Компилятор выводит SARIF, который может содержать дополнительные сведения для представления вложенной структуры некоторых диагностика. Диагностика (представленная result объектом SARIF) может содержать "дерево диагностики" дополнительных сведений в своем relatedLocations поле. Это дерево закодировано с помощью контейнера свойств SARIF следующим образом:
location Поле объекта properties может содержать nestingLevel свойство, значение которого — глубина этого расположения в дереве диагностики. Если в расположении нет nestingLevel указанного расположения, глубина считается 0 дочерней из корневой диагностики, представленной result объектом, содержащим его. В противном случае, если значение больше глубины расположения, непосредственно предшествующего этому расположению в relatedLocations поле, это расположение является дочерним элементом этого расположения. В противном случае это расположение является братом ближайшего предыдущего location в relatedLocations поле с той же глубиной.
Пример
Рассмотрим следующий код:
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
При компиляции этого кода компилятор создает следующий result объект (physicalLocation свойства были удалены для краткости):
{
"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)'"
}
}
]
}
Логическое диагностика дерево, создаваемое из сообщений в этом result объекте:
- "pet": перегруженная функция не может преобразовать все типы аргументов
- может быть "void pet(cat)"
- "void pet(cat)": не может преобразовать аргумент 1 из "ящерица" в "cat"
- Нет определяемого пользователем оператора преобразования, который может выполнять это преобразование, или не удается вызвать оператор.
- "void pet(cat)": не может преобразовать аргумент 1 из "ящерица" в "cat"
- или "void pet(dog)"
- "void pet(dog)": не может преобразовать аргумент 1 из "ящерица" в "собака"
- Нет определяемого пользователем оператора преобразования, который может выполнять это преобразование, или не удается вызвать оператор.
- "void pet(dog)": не может преобразовать аргумент 1 из "ящерица" в "собака"
- при попытке сопоставить список аргументов "(ящерица)"
- может быть "void pet(cat)"
См. также
/experimental:log(Включение структурированных диагностика SARIF)