[analyzer] Treat analyzer-synthesized function bodies like implicit bodies.

When generating path notes, implicit function bodies are shown at the call
site, so that, say, copying a POD type in C++ doesn't jump you to a header
file. This is especially important when the synthesized function itself
calls another function (or block), in which case we should try to jump the
user around as little as possible.

By checking whether a called function has a body in the AST, we can tell
if the analyzer synthesized the body, and if we should therefore collapse
the call down to the call site like a true implicitly-defined function.

<rdar://problem/13978414>

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182677 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jordan Rose 2013-05-24 21:43:11 +00:00
Родитель 5a6fb20841
Коммит d474da0625
4 изменённых файлов: 123 добавлений и 98 удалений

Просмотреть файл

@ -210,6 +210,13 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
return containsSomethingInteresting;
}
/// Returns true if the given decl has been implicitly given a body, either by
/// the analyzer or by the compiler proper.
static bool hasImplicitBody(const Decl *D) {
assert(D);
return D->isImplicit() || !D->hasBody();
}
/// Recursively scan through a path and make sure that all call pieces have
/// valid locations. Note that all other pieces with invalid locations should
/// have already been pruned out.
@ -224,11 +231,10 @@ static void adjustCallLocations(PathPieces &Pieces,
}
if (LastCallLocation) {
if (!Call->callEnter.asLocation().isValid() ||
Call->getCaller()->isImplicit())
bool CallerIsImplicit = hasImplicitBody(Call->getCaller());
if (CallerIsImplicit || !Call->callEnter.asLocation().isValid())
Call->callEnter = *LastCallLocation;
if (!Call->callReturn.asLocation().isValid() ||
Call->getCaller()->isImplicit())
if (CallerIsImplicit || !Call->callReturn.asLocation().isValid())
Call->callReturn = *LastCallLocation;
}
@ -236,7 +242,7 @@ static void adjustCallLocations(PathPieces &Pieces,
// it contains any informative diagnostics.
PathDiagnosticLocation *ThisCallLocation;
if (Call->callEnterWithin.asLocation().isValid() &&
!Call->getCallee()->isImplicit())
!hasImplicitBody(Call->getCallee()))
ThisCallLocation = &Call->callEnterWithin;
else
ThisCallLocation = &Call->callEnter;

Просмотреть файл

@ -982,7 +982,7 @@ IntrusiveRefCntPtr<PathDiagnosticEventPiece>
PathDiagnosticCallPiece::getCallEnterWithinCallerEvent() const {
if (!callEnterWithin.asLocation().isValid())
return 0;
if (Callee->isImplicit())
if (Callee->isImplicit() || !Callee->hasBody())
return 0;
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Callee))
if (MD->isDefaulted())

Просмотреть файл

@ -85,10 +85,10 @@ int testDispatchSyncInlining() {
// expected-note@+2 {{Calling 'dispatch_sync'}}
// expected-note@+1 {{Returning from 'dispatch_sync'}}
dispatch_sync(globalQueue, ^{
// expected-note@7 {{Calling anonymous block}}
// expected-note@-1 {{Calling anonymous block}}
// expected-note@-2 {{Returning to caller}}
x = 0;
// expected-note@-1 {{The value 0 is assigned to 'x'}}
// expected-note@7 {{Returning to caller}}
});
return 1 / x; // expected-warning{{Division by zero}}
@ -105,7 +105,7 @@ int testDispatchSyncInliningNoPruning(int coin) {
// expected-note@+1 {{Calling 'dispatch_sync'}}
dispatch_sync(globalQueue, ^{
// expected-note@7 {{Calling anonymous block}}
// expected-note@-1 {{Calling anonymous block}}
int x;
// expected-note@-1 {{'x' declared without an initial value}}
^{ y = x; }(); // expected-warning{{Variable 'x' is uninitialized when captured by block}}
@ -582,12 +582,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -599,7 +599,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -607,7 +607,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -628,24 +628,25 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Entered call from &apos;testDispatchSyncInlining&apos;</string>
// CHECK-NEXT: <key>message</key>
// CHECK-NEXT: <string>Entered call from &apos;testDispatchSyncInlining&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>92</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Calling anonymous block</string>
@ -656,7 +657,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -674,12 +675,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -687,12 +688,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>line</key><integer>90</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>line</key><integer>90</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -704,7 +705,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>line</key><integer>90</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -712,12 +713,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>line</key><integer>90</integer>
// CHECK-NEXT: <key>col</key><integer>5</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>line</key><integer>90</integer>
// CHECK-NEXT: <key>col</key><integer>9</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -733,10 +734,25 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>92</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Returning to caller</string>
@ -747,7 +763,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -755,7 +771,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -780,12 +796,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>87</integer>
// CHECK-NEXT: <key>line</key><integer>89</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -873,12 +889,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>end</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>15</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -890,7 +906,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -898,7 +914,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -919,24 +935,25 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Entered call from &apos;testDispatchSyncInliningNoPruning&apos;</string>
// CHECK-NEXT: <key>message</key>
// CHECK-NEXT: <string>Entered call from &apos;testDispatchSyncInliningNoPruning&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>7</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>113</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Calling anonymous block</string>
@ -947,7 +964,7 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
@ -965,12 +982,12 @@ id testCreateArrayLiteral(id myNil) {
// CHECK-NEXT: <key>start</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>107</integer>
// CHECK-NEXT: <key>line</key><integer>108</integer>
// CHECK-NEXT: <key>col</key><integer>30</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>

Просмотреть файл

@ -1492,24 +1492,25 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>40</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Entered call from &apos;test_dispatch_sync&apos;</string>
// CHECK-NEXT: <key>message</key>
// CHECK-NEXT: <string>Entered call from &apos;test_dispatch_sync&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>40</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>line</key><integer>190</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>190</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>194</integer>
// CHECK-NEXT: <key>col</key><integer>4</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>1</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Calling anonymous block</string>
@ -1974,24 +1975,25 @@ void test_inline_dispatch_once() {
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>depth</key><integer>2</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Entered call from &apos;_dispatch_once&apos;</string>
// CHECK-NEXT: <key>message</key>
// CHECK-NEXT: <string>Entered call from &apos;_dispatch_once&apos;</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>kind</key><string>event</string>
// CHECK-NEXT: <key>location</key>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>39</integer>
// CHECK-NEXT: <key>col</key><integer>1</integer>
// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <key>ranges</key>
// CHECK-NEXT: <array>
// CHECK-NEXT: <array>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>3</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: <dict>
// CHECK-NEXT: <key>line</key><integer>177</integer>
// CHECK-NEXT: <key>col</key><integer>33</integer>
// CHECK-NEXT: <key>file</key><integer>0</integer>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>2</integer>
// CHECK-NEXT: <key>extended_message</key>
// CHECK-NEXT: <string>Calling anonymous block</string>