Yapılandırılmış SARIF Tanılaması
MSVC derleyicisi, tanılamayı SARIF (Statik Çözümleme Sonuçları Değişim Biçimi) olarak çıktıya almak için yapılabilir. SARIF, makine tarafından okunabilir JSON tabanlı bir biçimdir.
MSVC derleyicisinin SARIF tanılaması üretmesinin iki yolu vardır:
/experimental:log
Komut satırında anahtarı geçirin. Ayrıntılar için/experimental:log
belgelere bakın.- Program aracılığıyla başlatın
cl.exe
ve ortam değişkeniniSARIF_OUTPUT_PIPE
bir boru üzerinden SARIF bloklarını alacak şekilde ayarlayın.
BIR boru üzerinden SARIF alma
Derleme devam ederken MSVC derleyicisinden SARIF kullanan araçlar bir kanal kullanır. Windows kanalları oluşturma hakkında ayrıntılı bilgi için CreatePipe
belgelere bakın.
BIR kanal üzerinden SARIF almak için ortam değişkenini SARIF_OUTPUT_PIPE
öğesinin UTF-16 kodlanmış tamsayı gösterimi HANDLE
olarak kanalın yazma sonuna ayarlayın ve başlatın cl.exe
. SARIF, boru boyunca aşağıdaki gibi gönderilir:
- Yeni bir tanılama kullanılabilir olduğunda, bu kanala yazılır.
- Tanılamalar, sarif nesnesinin tamamı yerine bir kerede bir kanala yazılır.
- Her tanılama, Notification türünde bir JSON-RPC 2.0 iletisiyle temsil edilir.
- JSON-RPC iletisine, form
Content-Length: <N>
ve ardından iki yeni çizgi eklenerekContent-Length
bir üst bilgi eklenir; burada<N>
bayt cinsinden aşağıdaki JSON-RPC iletisinin uzunluğudur. - JSON-RPC iletisi ve üst bilgisi UTF-8 ile kodlanmıştır.
- Bu JSON-RPC-with-header biçimi vs-streamjsonrpc ile uyumludur.
- JSON-RPC çağrısının yöntem adı şeklindedir
OnSarifResult
. - Çağrısı, parametre adıyla
result
ada göre kodlanmış tek bir parametreye sahiptir. - Bağımsız değişkeninin değeri, SARIF Sürüm 2.1 standardı tarafından belirtilen tek
result
bir nesnedir.
Örnek
Aşağıda tarafından üretilen bir JSON-RPC SARIF sonucu örneği verilmiştır 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 sonuç verileri
Derleyici, bazı tanılamaların iç içe yapısını temsil eden ek bilgiler içerebilen SARIF çıkışını oluşturur. Tanılama (SARIF nesnesiyle result
temsil edilir) alanında ek bilgi relatedLocations
içeren bir "tanılama ağacı" içerebilir. Bu ağaç bir SARIF özellik paketi kullanılarak aşağıdaki gibi kodlanır:
Nesnenin location
properties
alanı, değeri tanılama ağacındaki bu konumun derinliği olan bir nestingLevel
özellik içerebilir. Bir konum belirtilmemişse nestingLevel
, derinlik olarak kabul edilir 0
ve bu konum, onu içeren nesne tarafından temsil edilen kök tanılamanın result
alt öğesidir. Aksi takdirde, değer alandaki bu relatedLocations
konumdan hemen önceki konumun derinliğinden büyükse, bu konum bu konumun alt öğesidir. Aksi takdirde, bu konum aynı derinliğe sahip alanda en location
relatedLocations
yakın olanın eşdüzeyindedir.
Örnek
Aşağıdaki kodu inceleyin:
struct dog {};
struct cat {};
void pet(dog);
void pet(cat);
struct lizard {};
int main() {
pet(lizard{});
}
Bu kod derlendiğinde, derleyici aşağıdaki result
nesneyi üretir (physicalLocation
özellikler kısa süre için kaldırılmıştır):
{
"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)'"
}
}
]
}
Bu result
nesnedeki iletilerden oluşturulan mantıksal tanılama ağacı:
- 'pet': aşırı yüklenmiş hiçbir işlev tüm bağımsız değişken türlerini dönüştüremedi
- 'void pet(cat)' olabilir
- 'void pet(cat)': bağımsız değişken 1'i 'kertenkele'den 'kedi'ye dönüştüremez
- Bu dönüştürmeyi gerçekleştirebilecek kullanıcı tanımlı dönüştürme işleci yok veya işleç çağrılamıyor
- 'void pet(cat)': bağımsız değişken 1'i 'kertenkele'den 'kedi'ye dönüştüremez
- veya 'void pet(köpek)'
- 'void pet(köpek)': bağımsız değişken 1'i 'kertenkele'den 'köpeğe' dönüştüremez
- Bu dönüştürmeyi gerçekleştirebilecek kullanıcı tanımlı dönüştürme işleci yok veya işleç çağrılamıyor
- 'void pet(köpek)': bağımsız değişken 1'i 'kertenkele'den 'köpeğe' dönüştüremez
- '(kertenkele)' bağımsız değişken listesiyle eşleşmeye çalışırken
- 'void pet(cat)' olabilir
Ayrıca bkz.
/experimental:log
(Yapılandırılmış SARIF tanılamasını etkinleştirme)