<div dir="ltr">Hi Douglas,<div><br></div><div>Looked into that yesterday, there's a mismatch between windows and linux paths in the output.</div><div>I'll come up with a fix today.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 24, 2017 at 9:08 PM, Yung, Douglas <span dir="ltr"><<a href="mailto:douglas.yung@sony.com" target="_blank">douglas.yung@sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Ilya,<br>
<br>
Your change seems to be causing the test 'clangd/definitions.test' to fail on the PS4 Windows bot. Can you take a look?<br>
<br>
<a href="http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/11222" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/<wbr>builders/llvm-clang-lld-x86_<wbr>64-scei-ps4-windows10pro-fast/<wbr>builds/11222</a><br>
<br>
FAIL: Clang Tools :: clangd/definitions.test (11935 of 34225)<br>
******************** TEST 'Clang Tools :: clangd/definitions.test' FAILED ********************<br>
Script:<br>
--<br>
clangd -run-synchronously < C:\ps4-buildslave2\llvm-clang-<wbr>lld-x86_64-scei-ps4-<wbr>windows10pro-fast\llvm.src\<wbr>tools\clang\tools\extra\test\<wbr>clangd\definitions.test | FileCheck C:\ps4-buildslave2\llvm-clang-<wbr>lld-x86_64-scei-ps4-<wbr>windows10pro-fast\llvm.src\<wbr>tools\clang\tools\extra\test\<wbr>clangd\definitions.test<br>
--<br>
Exit Code: 1<br>
<br>
Command Output (stdout):<br>
--<br>
$ "clangd" "-run-synchronously"<br>
# command stderr:<br>
<-- {"jsonrpc":"2.0","id":0,"<wbr>method":"initialize","params":<wbr>{"processId":123,"rootPath":"<wbr>clangd","capabilities":{},"<wbr>trace":"off"}}<br>
<br>
--> {"jsonrpc":"2.0","id":0,"<wbr>result":{"capabilities":{<br>
<br>
"textDocumentSync": 1,<br>
<br>
"documentFormattingProvider": true,<br>
<br>
"<wbr>documentRangeFormattingProvide<wbr>r": true,<br>
<br>
"<wbr>documentOnTypeFormattingProvid<wbr>er": {"firstTriggerCharacter":"}","<wbr>moreTriggerCharacter":[]},<br>
<br>
"codeActionProvider": true,<br>
<br>
"completionProvider": {"resolveProvider": false, "triggerCharacters": [".",">"]},<br>
<br>
"definitionProvider": true<br>
<br>
}}}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didOpen","params"<wbr>:{"textDocument":{"uri":"file:<wbr>///main.cpp","languageId":"<wbr>cpp","version":1,"text":"int main() {\nint a;\na;\n}\n"}}}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[{"range":{"<wbr>start": {"line": 2, "character": 1}, "end": {"line": 2, "character": 1}},"severity":2,"message":"<wbr>expression result unused"}]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>2,"character":0}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>2,"character":1}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>2},"contentChanges":[{"text":"<wbr>struct Foo {\nint x;\n};\nint main() {\n Foo bar = { x : 1 };\n}\n"}]}}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[{"range":{"<wbr>start": {"line": 4, "character": 15}, "end": {"line": 4, "character": 15}},"severity":2,"message":"<wbr>use of GNU old-style field designator extension"}]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>4,"character":14}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>3},"contentChanges":[{"text":"<wbr>struct Foo {\nint x;\n};\nint main() {\n Foo baz = { .x = 2 };\n}\n"}]}}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>4,"character":15}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 1, "character": 0}, "end": {"line": 1, "character": 5}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>4},"contentChanges":[{"text":"<wbr>int main() {\n main();\n return 0;\n}"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>1,"character":3}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 0, "character": 0}, "end": {"line": 3, "character": 1}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>5},"contentChanges":[{"text":"<wbr>struct Foo {\n};\nint main() {\n Foo bar;\n return 0;\n}\n"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>3,"character":3}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 0, "character": 0}, "end": {"line": 1, "character": 1}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>5},"contentChanges":[{"text":"<wbr>namespace n1 {\nstruct Foo {\n};\n}\nint main() {\n n1::Foo bar;\n return 0;\n}\n"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>5,"character":4}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 0, "character": 0}, "end": {"line": 3, "character": 1}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>6},"contentChanges":[{"text":"<wbr>struct Foo {\n int x;\n};\nint main() {\n Foo bar;\n bar.x;\n}\n"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[{"range":{"<wbr>start": {"line": 5, "character": 8}, "end": {"line": 5, "character": 8}},"severity":2,"message":"<wbr>expression result unused"}]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>5,"character":7}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 1, "character": 2}, "end": {"line": 1, "character": 7}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>struct Foo {\n void x();\n};\nint main() {\n Foo bar;\n bar.x();\n}\n"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>5,"character":7}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 1, "character": 2}, "end": {"line": 1, "character": 10}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>struct Foo {\n};\ntypedef Foo TypedefFoo;\nint main() {\n TypedefFoo bar;\n return 0;\n}\n"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>4,"character":10}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 0}, "end": {"line": 2, "character": 22}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>template <typename MyTemplateParam>\nvoid foo() {\n MyTemplateParam a;\n}\nint main() {\n return 0;\n}\n"}]}}<br>
<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>2,"character":13}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>namespace ns {\nstruct Foo {\nstatic void bar() {}\n};\n}\nint main() {\n ns::Foo::bar();\n return 0;\n}\n"}]}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>6,"character":4}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 0, "character": 0}, "end": {"line": 4, "character": 1}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>namespace ns {\nstruct Foo {\n int field;\n Foo(int param) : field(param) {}\n};\n}\nint main() {\n return 0;\n}\n"}]}}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>3,"character":21}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 2}, "end": {"line": 2, "character": 11}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>#define MY_MACRO 0\nint main() {\n return MY_MACRO;\n}\n"}]}}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>2,"character":9}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///C:/main.cpp", "range": {"start": {"line": 0, "character": 8}, "end": {"line": 0, "character": 18}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","method":"<wbr>textDocument/didChange","<wbr>params":{"textDocument":{"uri"<wbr>:"file:///main.cpp","version":<wbr>7},"contentChanges":[{"text":"<wbr>#define FOO 1\nint a = FOO;\n#define FOO 2\nint b = FOO;\n#undef FOO\n"}]}}<br>
<br>
--> {"jsonrpc":"2.0","method":"<wbr>textDocument/<wbr>publishDiagnostics","params":{<wbr>"uri":"file:///main.cpp","<wbr>diagnostics":[{"range":{"<wbr>start": {"line": 2, "character": 9}, "end": {"line": 2, "character": 9}},"severity":2,"message":"'<wbr>FOO' macro redefined"}]}}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>1,"character":8}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///C:/main.cpp", "range": {"start": {"line": 0, "character": 8}, "end": {"line": 0, "character": 13}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>3,"character":8}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 8}, "end": {"line": 2, "character": 13}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","id":1,"<wbr>method":"textDocument/<wbr>definition","params":{"<wbr>textDocument":{"uri":"file:///<wbr>main.cpp"},"position":{"line":<wbr>4,"character":7}}}<br>
<br>
--> {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 8}, "end": {"line": 2, "character": 13}}}]}<br>
<br>
<-- {"jsonrpc":"2.0","id":3,"<wbr>method":"shutdown"}<br>
<br>
<br>
$ "FileCheck" "C:\ps4-buildslave2\llvm-<wbr>clang-lld-x86_64-scei-ps4-<wbr>windows10pro-fast\llvm.src\<wbr>tools\clang\tools\extra\test\<wbr>clangd\definitions.test"<br>
# command stderr:<br>
C:\ps4-buildslave2\llvm-clang-<wbr>lld-x86_64-scei-ps4-<wbr>windows10pro-fast\llvm.src\<wbr>tools\clang\tools\extra\test\<wbr>clangd\definitions.test:142:<wbr>10: error: expected string not found in input<br>
<br>
# CHECK: {"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 0, "character": 8}, "end": {"line": 0, "character": 18}}}]}<br>
<br>
^<br>
<br>
<stdin>:61:150: note: scanning from here<br>
<br>
{"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 2}, "end": {"line": 2, "character": 11}}}]}Content-Length: 113<br>
<br>
^<br>
<br>
<stdin>:71:1: note: possible intended match here<br>
<br>
{"jsonrpc":"2.0","id":1,"<wbr>result":[{"uri": "file:///main.cpp", "range": {"start": {"line": 2, "character": 8}, "end": {"line": 2, "character": 13}}}]}Content-Length: 149<br>
<br>
^<br>
<br>
<br>
error: command failed with exit status: 1<br>
<br>
--<br>
<br>
********************<br>
<div><div class="h5"><br>
> -----Original Message-----<br>
> From: cfe-commits [mailto:<a href="mailto:cfe-commits-bounces@lists.llvm.org">cfe-commits-bounces@<wbr>lists.llvm.org</a>] On Behalf Of<br>
> Ilya Biryukov via cfe-commits<br>
> Sent: Friday, July 21, 2017 6:29<br>
> To: <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> Subject: [clang-tools-extra] r308738 - [clangd] Replace ASTUnit with manual<br>
> AST management.<br>
><br>
> Author: ibiryukov<br>
> Date: Fri Jul 21 06:29:29 2017<br>
> New Revision: 308738<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=308738&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=308738&view=rev</a><br>
> Log:<br>
> [clangd] Replace ASTUnit with manual AST management.<br>
><br>
> Summary:<br>
> This refactoring does not aim to introduce any significant changes to the<br>
> behaviour of clangd to keep the change as simple as possible.<br>
><br>
> Reviewers: klimek, krasimir, bkramer<br>
><br>
> Reviewed By: krasimir<br>
><br>
> Subscribers: malaperle, cfe-commits<br>
><br>
> Tags: #clang-tools-extra<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D35406" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D35406</a><br>
><br>
> Modified:<br>
> clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp<br>
> clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp<br>
> clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/<wbr>ClangdServer.cpp?rev=308738&<wbr>r1=308737&r2=308738&view=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdServer.cpp Fri Jul 21 06:29:29<br>
</div></div>> +++ 2017<br>
<div><div class="h5">> @@ -205,14 +205,11 @@ ClangdServer::codeComplete(<wbr>PathRef File,<br>
><br>
> std::vector<CompletionItem> Result;<br>
> auto TaggedFS = FSProvider.<wbr>getTaggedFileSystem(File);<br>
> - // It would be nice to use runOnUnitWithoutReparse here, but we can't<br>
> - // guarantee the correctness of code completion cache here if we don't do<br>
> the<br>
> - // reparse.<br>
> - Units.runOnUnit(File, *OverridenContents, ResourceDir, CDB, PCHs,<br>
> - TaggedFS.Value, [&](ClangdUnit &Unit) {<br>
> - Result = Unit.codeComplete(*<wbr>OverridenContents, Pos,<br>
> - TaggedFS.Value);<br>
> - });<br>
> + Units.runOnUnitWithoutReparse(<wbr>File, *OverridenContents, ResourceDir, CDB,<br>
> + PCHs, TaggedFS.Value, [&](ClangdUnit &Unit) {<br>
> + Result = Unit.codeComplete(<br>
> + *OverridenContents, Pos,<br>
> TaggedFS.Value);<br>
> + });<br>
> return make_tagged(std::move(Result), TaggedFS.Tag); }<br>
><br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/ClangdUnit.<wbr>cpp?rev=308738&r1=308737&r2=<wbr>308738&view=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.cpp Fri Jul 21 06:29:29<br>
</div></div>> +++ 2017<br>
<div><div class="h5">> @@ -9,16 +9,22 @@<br>
><br>
> #include "ClangdUnit.h"<br>
><br>
> -#include "clang/Frontend/ASTUnit.h"<br>
> #include "clang/Frontend/<wbr>CompilerInstance.h"<br>
> #include "clang/Frontend/<wbr>CompilerInvocation.h"<br>
> +#include "clang/Frontend/<wbr>FrontendActions.h"<br>
> #include "clang/Frontend/Utils.h"<br>
> -#include "clang/Index/IndexingAction.h"<br>
> #include "clang/Index/<wbr>IndexDataConsumer.h"<br>
> +#include "clang/Index/IndexingAction.h"<br>
> #include "clang/Lex/Lexer.h"<br>
> #include "clang/Lex/MacroInfo.h"<br>
> #include "clang/Lex/Preprocessor.h"<br>
> +#include "clang/Lex/<wbr>PreprocessorOptions.h"<br>
> +#include "clang/Sema/Sema.h"<br>
> +#include "clang/Serialization/<wbr>ASTWriter.h"<br>
> #include "clang/Tooling/<wbr>CompilationDatabase.h"<br>
> +#include "llvm/ADT/ArrayRef.h"<br>
> +#include "llvm/ADT/SmallVector.h"<br>
> +#include "llvm/Support/<wbr>CrashRecoveryContext.h"<br>
> #include "llvm/Support/Format.h"<br>
><br>
> #include <algorithm><br>
> @@ -26,6 +32,196 @@<br>
> using namespace clang::clangd;<br>
> using namespace clang;<br>
><br>
> +namespace {<br>
> +<br>
> +class DeclTrackingASTConsumer : public ASTConsumer {<br>
> +public:<br>
> + DeclTrackingASTConsumer(std::<wbr>vector<const Decl *> &TopLevelDecls)<br>
> + : TopLevelDecls(TopLevelDecls) {}<br>
> +<br>
> + bool HandleTopLevelDecl(<wbr>DeclGroupRef DG) override {<br>
> + for (const Decl *D : DG) {<br>
> + // ObjCMethodDecl are not actually top-level decls.<br>
> + if (isa<ObjCMethodDecl>(D))<br>
> + continue;<br>
> +<br>
> + TopLevelDecls.push_back(D);<br>
> + }<br>
> + return true;<br>
> + }<br>
> +<br>
> +private:<br>
> + std::vector<const Decl *> &TopLevelDecls; };<br>
> +<br>
</div></div><span class="">> +class ClangdFrontendAction : public SyntaxOnlyAction {<br>
> +public:<br>
> + std::vector<const Decl *> takeTopLevelDecls() {<br>
> + return std::move(TopLevelDecls);<br>
> + }<br>
> +<br>
> +protected:<br>
> + std::unique_ptr<ASTConsumer> CreateASTConsumer(<wbr>CompilerInstance &CI,<br>
> + StringRef InFile) override {<br>
> + return llvm::make_unique<<wbr>DeclTrackingASTConsumer>(/*<wbr>ref*/<br>
</span>> +TopLevelDecls);<br>
<span class="">> + }<br>
> +<br>
> +private:<br>
> + std::vector<const Decl *> TopLevelDecls; };<br>
> +<br>
</span><div><div class="h5">> +class ClangdUnitPreambleCallbacks : public PreambleCallbacks {<br>
> +public:<br>
> + std::vector<serialization::<wbr>DeclID> takeTopLevelDeclIDs() {<br>
> + return std::move(TopLevelDeclIDs);<br>
> + }<br>
> +<br>
> + void AfterPCHEmitted(ASTWriter &Writer) override {<br>
> + TopLevelDeclIDs.reserve(<wbr>TopLevelDecls.size());<br>
> + for (Decl *D : TopLevelDecls) {<br>
> + // Invalid top-level decls may not have been serialized.<br>
> + if (D->isInvalidDecl())<br>
> + continue;<br>
> + TopLevelDeclIDs.push_back(<wbr>Writer.getDeclID(D));<br>
> + }<br>
> + }<br>
> +<br>
> + void HandleTopLevelDecl(<wbr>DeclGroupRef DG) override {<br>
> + for (Decl *D : DG) {<br>
> + if (isa<ObjCMethodDecl>(D))<br>
> + continue;<br>
> + TopLevelDecls.push_back(D);<br>
> + }<br>
> + }<br>
> +<br>
> +private:<br>
> + std::vector<Decl *> TopLevelDecls;<br>
> + std::vector<serialization::<wbr>DeclID> TopLevelDeclIDs; };<br>
> +<br>
</div></div><span class="">> +/// Convert from clang diagnostic level to LSP severity.<br>
> +static int getSeverity(DiagnosticsEngine:<wbr>:Level L) {<br>
> + switch (L) {<br>
> + case DiagnosticsEngine::Remark:<br>
> + return 4;<br>
> + case DiagnosticsEngine::Note:<br>
> + return 3;<br>
> + case DiagnosticsEngine::Warning:<br>
> + return 2;<br>
> + case DiagnosticsEngine::Fatal:<br>
> + case DiagnosticsEngine::Error:<br>
> + return 1;<br>
> + case DiagnosticsEngine::Ignored:<br>
> + return 0;<br>
> + }<br>
> + llvm_unreachable("Unknown diagnostic level!"); }<br>
> +<br>
</span><span class="">> +llvm::Optional<<wbr>DiagWithFixIts> toClangdDiag(StoredDiagnostic D) {<br>
> + auto Location = D.getLocation();<br>
> + if (!Location.isValid() || !Location.getManager().<wbr>isInMainFile(Location))<br>
> + return llvm::None;<br>
> +<br>
> + Position P;<br>
</span>> + P.line = Location.<wbr>getSpellingLineNumber() - 1; P.character =<br>
> + Location.<wbr>getSpellingColumnNumber();<br>
<span class="">> + Range R = {P, P};<br>
> + clangd::Diagnostic Diag = {R, getSeverity(D.getLevel()),<br>
</span>> + D.getMessage()};<br>
<span class="">> +<br>
> + llvm::SmallVector<tooling::<wbr>Replacement, 1> FixItsForDiagnostic;<br>
> + for (const FixItHint &Fix : D.getFixIts()) {<br>
> + FixItsForDiagnostic.push_back(<wbr>clang::tooling::Replacement(<br>
> + Location.getManager(), Fix.RemoveRange, Fix.CodeToInsert));<br>
> + }<br>
> + return DiagWithFixIts{Diag, std::move(FixItsForDiagnostic)<wbr>}; }<br>
> +<br>
</span><span class="">> +class StoreDiagsConsumer : public DiagnosticConsumer {<br>
> +public:<br>
> + StoreDiagsConsumer(std::<wbr>vector<DiagWithFixIts> &Output) :<br>
</span>> +Output(Output) {}<br>
<span class="">> +<br>
> + void HandleDiagnostic(<wbr>DiagnosticsEngine::Level DiagLevel,<br>
> + const clang::Diagnostic &Info) override {<br>
> + DiagnosticConsumer::<wbr>HandleDiagnostic(DiagLevel, Info);<br>
> +<br>
> + if (auto convertedDiag = toClangdDiag(StoredDiagnostic(<wbr>DiagLevel, Info)))<br>
> + Output.push_back(std::move(*<wbr>convertedDiag));<br>
> + }<br>
> +<br>
> +private:<br>
> + std::vector<DiagWithFixIts> &Output;<br>
> +};<br>
> +<br>
> +class EmptyDiagsConsumer : public DiagnosticConsumer {<br>
> +public:<br>
> + void HandleDiagnostic(<wbr>DiagnosticsEngine::Level DiagLevel,<br>
> + const clang::Diagnostic &Info) override {} };<br>
> +<br>
</span><span class="">> +std::unique_ptr<<wbr>CompilerInvocation><br>
> +createCompilerInvocation(<wbr>ArrayRef<const char *> ArgList,<br>
> + IntrusiveRefCntPtr<<wbr>DiagnosticsEngine> Diags,<br>
> + IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
> + auto CI = createInvocationFromCommandLin<wbr>e(ArgList, std::move(Diags),<br>
> + std::move(VFS));<br>
> + // We rely on CompilerInstance to manage the resource (i.e. free them<br>
</span>> +on<br>
<span class="">> + // EndSourceFile), but that won't happen if DisableFree is set to true.<br>
> + // Since createInvocationFromCommandLin<wbr>e sets it to true, we have to<br>
</span>> +override<br>
<span class="">> + // it.<br>
> + CI->getFrontendOpts().<wbr>DisableFree = false;<br>
> + return CI;<br>
> +}<br>
> +<br>
> +/// Creates a CompilerInstance from \p CI, with main buffer overriden<br>
</span>> +to \p /// Buffer and arguments to read the PCH from \p Preamble, if \p<br>
> +Preamble is not /// null. Note that vfs::FileSystem inside returned<br>
> +instance may differ from \p /// VFS if additional file remapping were set in<br>
<span class="">> command-line arguments.<br>
> +/// On some errors, returns null. When non-null value is returned, it's<br>
</span>> +expected /// to be consumed by the FrontendAction as it will have a<br>
> +pointer to the \p /// Buffer that will only be deleted if BeginSourceFile is<br>
<span class="">> called.<br>
> +std::unique_ptr<<wbr>CompilerInstance><br>
> +prepareCompilerInstance(std::<wbr>unique_ptr<clang::<wbr>CompilerInvocation> CI,<br>
> + const PrecompiledPreamble *Preamble,<br>
> + std::unique_ptr<llvm::<wbr>MemoryBuffer> Buffer,<br>
> + std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
> + IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS,<br>
> + DiagnosticConsumer &DiagsClient) {<br>
> + assert(VFS && "VFS is null");<br>
> + assert(!CI-><wbr>getPreprocessorOpts().<wbr>RetainRemappedFileBuffers &&<br>
> + "Setting RetainRemappedFileBuffers to true will cause a memory leak<br>
> "<br>
> + "of ContentsBuffer");<br>
> +<br>
> + // NOTE: we use Buffer.get() when adding remapped files, so we have<br>
</span>> + to make // sure it will be released if no error is emitted.<br>
> + if (Preamble) {<br>
> + Preamble->AddImplicitPreamble(<wbr>*CI, Buffer.get()); } else {<br>
<span class="">> + CI->getPreprocessorOpts().<wbr>addRemappedFile(<br>
> + CI->getFrontendOpts().Inputs[<wbr>0].getFile(), Buffer.get()); }<br>
> +<br>
> + auto Clang = llvm::make_unique<<wbr>CompilerInstance>(PCHs);<br>
> + Clang->setInvocation(std::<wbr>move(CI));<br>
> + Clang->createDiagnostics(&<wbr>DiagsClient, false);<br>
> +<br>
> + if (auto VFSWithRemapping = createVFSFromCompilerInvocatio<wbr>n(<br>
> + Clang->getInvocation(), Clang->getDiagnostics(), VFS))<br>
> + VFS = VFSWithRemapping;<br>
> + Clang->setVirtualFileSystem(<wbr>VFS);<br>
> +<br>
> + Clang->setTarget(TargetInfo::<wbr>CreateTargetInfo(<br>
> + Clang->getDiagnostics(), Clang->getInvocation().<wbr>TargetOpts));<br>
> + if (!Clang->hasTarget())<br>
> + return nullptr;<br>
> +<br>
> + // RemappedFileBuffers will handle the lifetime of the Buffer<br>
</span>> +pointer,<br>
<div><div class="h5">> + // release it.<br>
> + Buffer.release();<br>
> + return Clang;<br>
> +}<br>
> +<br>
> +} // namespace<br>
> +<br>
> ClangdUnit::ClangdUnit(PathRef FileName, StringRef Contents,<br>
> StringRef ResourceDir,<br>
> std::shared_ptr<<wbr>PCHContainerOperations> PCHs, @@ -<br>
> 39,44 +235,54 @@ ClangdUnit::ClangdUnit(PathRef FileName,<br>
> Commands.front().CommandLine.<wbr>push_back("-resource-dir=" +<br>
> std::string(ResourceDir));<br>
><br>
> - IntrusiveRefCntPtr<<wbr>DiagnosticsEngine> Diags =<br>
> - CompilerInstance::<wbr>createDiagnostics(new DiagnosticOptions);<br>
> -<br>
> - std::vector<const char *> ArgStrs;<br>
> - for (const auto &S : Commands.front().CommandLine)<br>
> - ArgStrs.push_back(S.c_str());<br>
> -<br>
> - ASTUnit::RemappedFile RemappedSource(<br>
> - FileName,<br>
> - llvm::MemoryBuffer::<wbr>getMemBufferCopy(Contents, FileName).release());<br>
> -<br>
> - auto ArgP = &*ArgStrs.begin();<br>
> - Unit = std::unique_ptr<ASTUnit>(<wbr>ASTUnit::LoadFromCommandLine(<br>
> - ArgP, ArgP + ArgStrs.size(), PCHs, Diags, ResourceDir,<br>
> - /*OnlyLocalDecls=*/false, /*CaptureDiagnostics=*/true, RemappedSource,<br>
> - /*<wbr>RemappedFilesKeepOriginalName=<wbr>*/true,<br>
> - /*<wbr>PrecompilePreambleAfterNParses<wbr>=*/1, /*TUKind=*/TU_Prefix,<br>
> - /*CacheCodeCompletionResults=*<wbr>/true,<br>
> - /*<wbr>IncludeBriefCommentsInCodeComp<wbr>letion=*/true,<br>
> - /*AllowPCHWithCompilerErrors=*<wbr>/true,<br>
> - /*SkipFunctionBodies=*/false,<br>
> - /*SingleFileParse=*/false,<br>
> - /*UserFilesAreVolatile=*/<wbr>false, /*ForSerialization=*/false,<br>
> - /*ModuleFormat=*/llvm::None,<br>
> - /*ErrAST=*/nullptr, VFS));<br>
> - assert(Unit && "Unit wasn't created");<br>
</div></div>> + Command = std::move(Commands.front()); reparse(Contents, VFS);<br>
<div class="HOEnZb"><div class="h5">> }<br>
><br>
> void ClangdUnit::reparse(StringRef Contents,<br>
> IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
> - // Do a reparse if this wasn't the first parse.<br>
> - // FIXME: This might have the wrong working directory if it changed in the<br>
> - // meantime.<br>
> - ASTUnit::RemappedFile RemappedSource(<br>
> - FileName,<br>
> - llvm::MemoryBuffer::<wbr>getMemBufferCopy(Contents, FileName).release());<br>
> + std::vector<const char *> ArgStrs;<br>
> + for (const auto &S : Command.CommandLine)<br>
> + ArgStrs.push_back(S.c_str());<br>
><br>
> - Unit->Reparse(PCHs, RemappedSource, VFS);<br>
> + std::unique_ptr<<wbr>CompilerInvocation> CI;<br>
> + {<br>
> + // FIXME(ibiryukov): store diagnostics from CommandLine when we start<br>
> + // reporting them.<br>
> + EmptyDiagsConsumer CommandLineDiagsConsumer;<br>
> + IntrusiveRefCntPtr<<wbr>DiagnosticsEngine> CommandLineDiagsEngine =<br>
> + CompilerInstance::<wbr>createDiagnostics(new DiagnosticOptions,<br>
> + &CommandLineDiagsConsumer,<br>
> false);<br>
> + CI = createCompilerInvocation(<wbr>ArgStrs, CommandLineDiagsEngine, VFS);<br>
> + }<br>
> + assert(CI && "Couldn't create CompilerInvocation");<br>
> +<br>
> + std::unique_ptr<llvm::<wbr>MemoryBuffer> ContentsBuffer =<br>
> + llvm::MemoryBuffer::<wbr>getMemBufferCopy(Contents, FileName);<br>
> +<br>
> + // Rebuild the preamble if it is missing or can not be reused.<br>
> + auto Bounds =<br>
> + ComputePreambleBounds(*CI-><wbr>getLangOpts(), ContentsBuffer.get(), 0);<br>
> + if (!Preamble || !Preamble->Preamble.CanReuse(*<wbr>CI, ContentsBuffer.get(),<br>
> + Bounds, VFS.get())) {<br>
> + std::vector<DiagWithFixIts> PreambleDiags;<br>
> + StoreDiagsConsumer PreambleDiagnosticsConsumer(/*<wbr>ref*/ PreambleDiags);<br>
> + IntrusiveRefCntPtr<<wbr>DiagnosticsEngine> PreambleDiagsEngine =<br>
> + CompilerInstance::<wbr>createDiagnostics(<br>
> + &CI->getDiagnosticOpts(), &PreambleDiagnosticsConsumer, false);<br>
> + ClangdUnitPreambleCallbacks SerializedDeclsCollector;<br>
> + auto BuiltPreamble = PrecompiledPreamble::Build(<br>
> + *CI, ContentsBuffer.get(), Bounds, *PreambleDiagsEngine, VFS, PCHs,<br>
> + SerializedDeclsCollector);<br>
> + if (BuiltPreamble)<br>
> + Preamble = PreambleData(std::move(*<wbr>BuiltPreamble),<br>
> + SerializedDeclsCollector.<wbr>takeTopLevelDeclIDs(),<br>
> + std::move(PreambleDiags));<br>
> + }<br>
> + Unit = ParsedAST::Build(<br>
> + std::move(CI), Preamble ? &Preamble->Preamble : nullptr,<br>
> + Preamble ? llvm::makeArrayRef(Preamble-><wbr>TopLevelDeclIDs) : llvm::None,<br>
> + std::move(ContentsBuffer), PCHs, VFS);<br>
> }<br>
><br>
> namespace {<br>
> @@ -188,97 +394,164 @@ public:<br>
> std::vector<CompletionItem><br>
> ClangdUnit::codeComplete(<wbr>StringRef Contents, Position Pos,<br>
> IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
> - CodeCompleteOptions CCO;<br>
> - CCO.IncludeBriefComments = 1;<br>
> - // This is where code completion stores dirty buffers. Need to free after<br>
> - // completion.<br>
> - SmallVector<const llvm::MemoryBuffer *, 4> OwnedBuffers;<br>
> - SmallVector<StoredDiagnostic, 4> StoredDiagnostics;<br>
> - IntrusiveRefCntPtr<<wbr>DiagnosticsEngine> DiagEngine(<br>
> - new DiagnosticsEngine(new DiagnosticIDs, new DiagnosticOptions));<br>
> - std::vector<CompletionItem> Items;<br>
> - CompletionItemsCollector Collector(&Items, CCO);<br>
> + std::vector<const char *> ArgStrs;<br>
> + for (const auto &S : Command.CommandLine)<br>
> + ArgStrs.push_back(S.c_str());<br>
><br>
> - ASTUnit::RemappedFile RemappedSource(<br>
> - FileName,<br>
> - llvm::MemoryBuffer::<wbr>getMemBufferCopy(Contents, FileName).release());<br>
> -<br>
> - IntrusiveRefCntPtr<<wbr>FileManager> FileMgr(<br>
> - new FileManager(Unit-><wbr>getFileSystemOpts(), VFS));<br>
> - IntrusiveRefCntPtr<<wbr>SourceManager> SourceMgr(<br>
> - new SourceManager(*DiagEngine, *FileMgr));<br>
> - // CodeComplete seems to require fresh LangOptions.<br>
> - LangOptions LangOpts = Unit->getLangOpts();<br>
> - // The language server protocol uses zero-based line and column numbers.<br>
> - // The clang code completion uses one-based numbers.<br>
> - Unit->CodeComplete(FileName, Pos.line + 1, Pos.character + 1,<br>
> RemappedSource,<br>
> - CCO.IncludeMacros, CCO.IncludeCodePatterns,<br>
> - CCO.IncludeBriefComments, Collector, PCHs, *DiagEngine,<br>
> - LangOpts, *SourceMgr, *FileMgr, StoredDiagnostics,<br>
> - OwnedBuffers);<br>
> - for (const llvm::MemoryBuffer *Buffer : OwnedBuffers)<br>
> - delete Buffer;<br>
> - return Items;<br>
> -}<br>
> + std::unique_ptr<<wbr>CompilerInvocation> CI;<br>
> + EmptyDiagsConsumer DummyDiagsConsumer;<br>
> + {<br>
> + IntrusiveRefCntPtr<<wbr>DiagnosticsEngine> CommandLineDiagsEngine =<br>
> + CompilerInstance::<wbr>createDiagnostics(new DiagnosticOptions,<br>
> + &DummyDiagsConsumer, false);<br>
> + CI = createCompilerInvocation(<wbr>ArgStrs, CommandLineDiagsEngine, VFS);<br>
> + }<br>
> + assert(CI && "Couldn't create CompilerInvocation");<br>
> +<br>
> + std::unique_ptr<llvm::<wbr>MemoryBuffer> ContentsBuffer =<br>
> + llvm::MemoryBuffer::<wbr>getMemBufferCopy(Contents, FileName);<br>
> +<br>
> + // Attempt to reuse the PCH from precompiled preamble, if it was built.<br>
> + const PrecompiledPreamble *PreambleForCompletion = nullptr;<br>
> + if (Preamble) {<br>
> + auto Bounds =<br>
> + ComputePreambleBounds(*CI-><wbr>getLangOpts(), ContentsBuffer.get(), 0);<br>
> + if (Preamble->Preamble.CanReuse(*<wbr>CI, ContentsBuffer.get(), Bounds,<br>
> + VFS.get()))<br>
> + PreambleForCompletion = &Preamble->Preamble;<br>
> + }<br>
> +<br>
> + auto Clang = prepareCompilerInstance(std::<wbr>move(CI), PreambleForCompletion,<br>
> + std::move(ContentsBuffer), PCHs, VFS,<br>
> + DummyDiagsConsumer);<br>
> + auto &DiagOpts = Clang->getDiagnosticOpts();<br>
> + DiagOpts.IgnoreWarnings = true;<br>
> +<br>
> + auto &FrontendOpts = Clang->getFrontendOpts();<br>
> + FrontendOpts.<wbr>SkipFunctionBodies = true;<br>
> +<br>
> + FrontendOpts.CodeCompleteOpts.<wbr>IncludeGlobals = true;<br>
> + // we don't handle code patterns properly yet, disable them.<br>
> + FrontendOpts.CodeCompleteOpts.<wbr>IncludeCodePatterns = false;<br>
> + FrontendOpts.CodeCompleteOpts.<wbr>IncludeMacros = true;<br>
> + FrontendOpts.CodeCompleteOpts.<wbr>IncludeBriefComments = true;<br>
> +<br>
> + FrontendOpts.CodeCompletionAt.<wbr>FileName = FileName;<br>
> + FrontendOpts.CodeCompletionAt.<wbr>Line = Pos.line + 1;<br>
> + FrontendOpts.CodeCompletionAt.<wbr>Column = Pos.character + 1;<br>
><br>
> -namespace {<br>
> -/// Convert from clang diagnostic level to LSP severity.<br>
> -static int getSeverity(DiagnosticsEngine:<wbr>:Level L) {<br>
> - switch (L) {<br>
> - case DiagnosticsEngine::Remark:<br>
> - return 4;<br>
> - case DiagnosticsEngine::Note:<br>
> - return 3;<br>
> - case DiagnosticsEngine::Warning:<br>
> - return 2;<br>
> - case DiagnosticsEngine::Fatal:<br>
> - case DiagnosticsEngine::Error:<br>
> - return 1;<br>
> - case DiagnosticsEngine::Ignored:<br>
> - return 0;<br>
> + std::vector<CompletionItem> Items;<br>
> + Clang-><wbr>setCodeCompletionConsumer(<br>
> + new CompletionItemsCollector(&<wbr>Items, FrontendOpts.CodeCompleteOpts)<wbr>);<br>
> +<br>
> + SyntaxOnlyAction Action;<br>
> + if (!Action.BeginSourceFile(*<wbr>Clang, Clang->getFrontendOpts().<wbr>Inputs[0])) {<br>
> + // FIXME(ibiryukov): log errors<br>
> + return Items;<br>
> }<br>
> - llvm_unreachable("Unknown diagnostic level!");<br>
> + if (!Action.Execute()) {<br>
> + // FIXME(ibiryukov): log errors<br>
> + }<br>
> + Action.EndSourceFile();<br>
> +<br>
> + return Items;<br>
> }<br>
> -} // namespace<br>
><br>
> std::vector<DiagWithFixIts> ClangdUnit::<wbr>getLocalDiagnostics() const {<br>
> + if (!Unit)<br>
> + return {}; // Parsing failed.<br>
> +<br>
> std::vector<DiagWithFixIts> Result;<br>
> - for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),<br>
> - DEnd = Unit->stored_diag_end();<br>
> - D != DEnd; ++D) {<br>
> - if (!D->getLocation().isValid() ||<br>
> - !D->getLocation().getManager()<wbr>.isInMainFile(D->getLocation()<wbr>))<br>
> - continue;<br>
> - Position P;<br>
> - P.line = D->getLocation().<wbr>getSpellingLineNumber() - 1;<br>
> - P.character = D->getLocation().<wbr>getSpellingColumnNumber();<br>
> - Range R = {P, P};<br>
> - clangd::Diagnostic Diag = {R, getSeverity(D->getLevel()), D-<br>
> >getMessage()};<br>
> -<br>
> - llvm::SmallVector<tooling::<wbr>Replacement, 1> FixItsForDiagnostic;<br>
> - for (const FixItHint &Fix : D->getFixIts()) {<br>
> - FixItsForDiagnostic.push_back(<wbr>clang::tooling::Replacement(<br>
> - Unit->getSourceManager(), Fix.RemoveRange, Fix.CodeToInsert));<br>
> - }<br>
> - Result.push_back({Diag, std::move(FixItsForDiagnostic)<wbr>});<br>
> - }<br>
> + auto PreambleDiagsSize = Preamble ? Preamble->Diags.size() : 0;<br>
> + const auto &Diags = Unit->getDiagnostics();<br>
> + Result.reserve(<wbr>PreambleDiagsSize + Diags.size());<br>
> +<br>
> + if (Preamble)<br>
> + Result.insert(Result.end(), Preamble->Diags.begin(), Preamble-<br>
> >Diags.end());<br>
> + Result.insert(Result.end(), Diags.begin(), Diags.end());<br>
> return Result;<br>
> }<br>
><br>
> void ClangdUnit::dumpAST(llvm::raw_<wbr>ostream &OS) const {<br>
> + if (!Unit) {<br>
> + OS << "<no-ast-in-clang>";<br>
> + return; // Parsing failed.<br>
> + }<br>
> Unit->getASTContext().<wbr>getTranslationUnitDecl()-><wbr>dump(OS, true);<br>
> }<br>
><br>
> +llvm::Optional<ClangdUnit::<wbr>ParsedAST><br>
> +ClangdUnit::ParsedAST::Build(<wbr>std::unique_ptr<clang::<wbr>CompilerInvocation> CI,<br>
> + const PrecompiledPreamble *Preamble,<br>
> + ArrayRef<serialization::<wbr>DeclID> PreambleDeclIDs,<br>
> + std::unique_ptr<llvm::<wbr>MemoryBuffer> Buffer,<br>
> + std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
> + IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS) {<br>
> +<br>
> + std::vector<DiagWithFixIts> ASTDiags;<br>
> + StoreDiagsConsumer UnitDiagsConsumer(/*ref*/ ASTDiags);<br>
> +<br>
> + auto Clang =<br>
> + prepareCompilerInstance(std::<wbr>move(CI), Preamble, std::move(Buffer),<br>
> PCHs,<br>
> + VFS, /*ref*/ UnitDiagsConsumer);<br>
> +<br>
> + // Recover resources if we crash before exiting this method.<br>
> + llvm::<wbr>CrashRecoveryContextCleanupReg<wbr>istrar<CompilerInstance> CICleanup(<br>
> + Clang.get());<br>
> +<br>
> + auto Action = llvm::make_unique<<wbr>ClangdFrontendAction>();<br>
> + if (!Action->BeginSourceFile(*<wbr>Clang, Clang->getFrontendOpts().<wbr>Inputs[0])) {<br>
> + // FIXME(ibiryukov): log error<br>
> + return llvm::None;<br>
> + }<br>
> + if (!Action->Execute()) {<br>
> + // FIXME(ibiryukov): log error<br>
> + }<br>
> +<br>
> + // UnitDiagsConsumer is local, we can not store it in CompilerInstance that<br>
> + // has a longer lifetime.<br>
> + Clang->getDiagnostics().<wbr>setClient(new EmptyDiagsConsumer);<br>
> +<br>
> + std::vector<const Decl *> ParsedDecls = Action->takeTopLevelDecls();<br>
> + std::vector<serialization::<wbr>DeclID> PendingDecls;<br>
> + if (Preamble) {<br>
> + PendingDecls.reserve(<wbr>PreambleDeclIDs.size());<br>
> + PendingDecls.insert(<wbr>PendingDecls.begin(), PreambleDeclIDs.begin(),<br>
> + PreambleDeclIDs.end());<br>
> + }<br>
> +<br>
> + return ParsedAST(std::move(Clang), std::move(Action),<br>
> std::move(ParsedDecls),<br>
> + std::move(PendingDecls), std::move(ASTDiags));<br>
> +}<br>
> +<br>
> namespace {<br>
> +<br>
> +SourceLocation getMacroArgExpandedLocation(<wbr>const SourceManager &Mgr,<br>
> + const FileEntry *FE,<br>
> + unsigned Offset) {<br>
> + SourceLocation FileLoc = Mgr.translateFileLineCol(FE, 1, 1);<br>
> + return Mgr.<wbr>getMacroArgExpandedLocation(<wbr>FileLoc.getLocWithOffset(<wbr>Offset));<br>
> +}<br>
> +<br>
> +SourceLocation getMacroArgExpandedLocation(<wbr>const SourceManager &Mgr,<br>
> + const FileEntry *FE, Position Pos)<br>
> {<br>
> + SourceLocation InputLoc =<br>
> + Mgr.translateFileLineCol(FE, Pos.line + 1, Pos.character + 1);<br>
> + return Mgr.<wbr>getMacroArgExpandedLocation(<wbr>InputLoc);<br>
> +}<br>
> +<br>
> /// Finds declarations locations that a given source location refers to.<br>
> class DeclarationLocationsFinder : public index::IndexDataConsumer {<br>
> std::vector<Location> DeclarationLocations;<br>
> const SourceLocation &SearchedLocation;<br>
> - ASTUnit &Unit;<br>
> + const ASTContext &AST;<br>
> + Preprocessor &PP;<br>
> +<br>
> public:<br>
> DeclarationLocationsFinder(<wbr>raw_ostream &OS,<br>
> - const SourceLocation &SearchedLocation, ASTUnit &Unit) :<br>
> - SearchedLocation(<wbr>SearchedLocation), Unit(Unit) {}<br>
> + const SourceLocation &SearchedLocation,<br>
> + ASTContext &AST, Preprocessor &PP)<br>
> + : SearchedLocation(<wbr>SearchedLocation), AST(AST), PP(PP) {}<br>
><br>
> std::vector<Location> takeLocations() {<br>
> // Don't keep the same location multiple times.<br>
> @@ -302,17 +575,17 @@ public:<br>
><br>
> private:<br>
> bool isSearchedLocation(FileID FID, unsigned Offset) const {<br>
> - const SourceManager &SourceMgr = Unit.getSourceManager();<br>
> - return SourceMgr.getFileOffset(<wbr>SearchedLocation) == Offset<br>
> - && SourceMgr.getFileID(<wbr>SearchedLocation) == FID;<br>
> + const SourceManager &SourceMgr = AST.getSourceManager();<br>
> + return SourceMgr.getFileOffset(<wbr>SearchedLocation) == Offset &&<br>
> + SourceMgr.getFileID(<wbr>SearchedLocation) == FID;<br>
> }<br>
><br>
> - void addDeclarationLocation(const SourceRange& ValSourceRange) {<br>
> - const SourceManager& SourceMgr = Unit.getSourceManager();<br>
> - const LangOptions& LangOpts = Unit.getLangOpts();<br>
> + void addDeclarationLocation(const SourceRange &ValSourceRange) {<br>
> + const SourceManager &SourceMgr = AST.getSourceManager();<br>
> + const LangOptions &LangOpts = AST.getLangOpts();<br>
> SourceLocation LocStart = ValSourceRange.getBegin();<br>
> SourceLocation LocEnd =<br>
> Lexer::getLocForEndOfToken(<wbr>ValSourceRange.getEnd(),<br>
> - 0, SourceMgr, LangOpts);<br>
> + 0, SourceMgr,<br>
> LangOpts);<br>
> Position Begin;<br>
> Begin.line = SourceMgr.<wbr>getSpellingLineNumber(<wbr>LocStart) - 1;<br>
> Begin.character = SourceMgr.<wbr>getSpellingColumnNumber(<wbr>LocStart) - 1;<br>
> @@ -330,24 +603,24 @@ private:<br>
> void finish() override {<br>
> // Also handle possible macro at the searched location.<br>
> Token Result;<br>
> - if (!Lexer::getRawToken(<wbr>SearchedLocation, Result,<br>
> Unit.getSourceManager(),<br>
> - Unit.getASTContext().<wbr>getLangOpts(), false)) {<br>
> + if (!Lexer::getRawToken(<wbr>SearchedLocation, Result, AST.getSourceManager(),<br>
> + AST.getLangOpts(), false)) {<br>
> if (Result.is(tok::raw_<wbr>identifier)) {<br>
> - Unit.getPreprocessor().<wbr>LookUpIdentifierInfo(Result);<br>
> + PP.LookUpIdentifierInfo(<wbr>Result);<br>
> }<br>
> - IdentifierInfo* IdentifierInfo = Result.getIdentifierInfo();<br>
> + IdentifierInfo *IdentifierInfo = Result.getIdentifierInfo();<br>
> if (IdentifierInfo && IdentifierInfo-><wbr>hadMacroDefinition()) {<br>
> std::pair<FileID, unsigned int> DecLoc =<br>
> -<br>
> Unit.getSourceManager().<wbr>getDecomposedExpansionLoc(<wbr>SearchedLocation);<br>
> +<br>
> AST.getSourceManager().<wbr>getDecomposedExpansionLoc(<wbr>SearchedLocation);<br>
> // Get the definition just before the searched location so that a<br>
> macro<br>
> // referenced in a '#undef MACRO' can still be found.<br>
> - SourceLocation BeforeSearchedLocation = Unit.getLocation(<br>
> - Unit.getSourceManager().<wbr>getFileEntryForID(DecLoc.<wbr>first),<br>
> + SourceLocation BeforeSearchedLocation = getMacroArgExpandedLocation(<br>
> + AST.getSourceManager(),<br>
> + AST.getSourceManager().<wbr>getFileEntryForID(DecLoc.<wbr>first),<br>
> DecLoc.second - 1);<br>
> MacroDefinition MacroDef =<br>
> - Unit.getPreprocessor().<wbr>getMacroDefinitionAtLoc(<wbr>IdentifierInfo,<br>
> - BeforeSearchedLocation);<br>
> - MacroInfo* MacroInf = MacroDef.getMacroInfo();<br>
> + PP.getMacroDefinitionAtLoc(<wbr>IdentifierInfo,<br>
> BeforeSearchedLocation);<br>
> + MacroInfo *MacroInf = MacroDef.getMacroInfo();<br>
> if (MacroInf) {<br>
> addDeclarationLocation(<br>
> SourceRange(MacroInf-><wbr>getDefinitionLoc(),<br>
> @@ -360,30 +633,41 @@ private:<br>
> } // namespace<br>
><br>
> std::vector<Location> ClangdUnit::findDefinitions(<wbr>Position Pos) {<br>
> - const FileEntry *FE = Unit->getFileManager().<wbr>getFile(Unit-<br>
> >getMainFileName());<br>
> + if (!Unit)<br>
> + return {}; // Parsing failed.<br>
> +<br>
> + const SourceManager &SourceMgr = Unit->getASTContext().<wbr>getSourceManager();<br>
> + const FileEntry *FE =<br>
> SourceMgr.getFileEntryForID(<wbr>SourceMgr.getMainFileID());<br>
> if (!FE)<br>
> return {};<br>
><br>
> SourceLocation SourceLocationBeg = getBeginningOfIdentifier(Pos, FE);<br>
><br>
> auto DeclLocationsFinder = std::make_shared<<wbr>DeclarationLocationsFinder>(<br>
> - llvm::errs(), SourceLocationBeg, *Unit);<br>
> + llvm::errs(), SourceLocationBeg, Unit->getASTContext(),<br>
> + Unit->getPreprocessor());<br>
> index::IndexingOptions IndexOpts;<br>
> IndexOpts.SystemSymbolFilter =<br>
> index::IndexingOptions::<wbr>SystemSymbolFilterKind::All;<br>
> IndexOpts.IndexFunctionLocals = true;<br>
> - index::indexASTUnit(*Unit, DeclLocationsFinder, IndexOpts);<br>
> +<br>
> + indexTopLevelDecls(Unit-><wbr>getASTContext(), Unit->getTopLevelDecls(),<br>
> + DeclLocationsFinder, IndexOpts);<br>
><br>
> return DeclLocationsFinder-><wbr>takeLocations();<br>
> }<br>
><br>
> SourceLocation ClangdUnit::<wbr>getBeginningOfIdentifier(const Position &Pos,<br>
> - const FileEntry *FE) const {<br>
> + const FileEntry *FE)<br>
> const {<br>
> +<br>
> // The language server protocol uses zero-based line and column numbers.<br>
> // Clang uses one-based numbers.<br>
> - SourceLocation InputLocation = Unit->getLocation(FE, Pos.line + 1,<br>
> - Pos.character + 1);<br>
><br>
> + const ASTContext &AST = Unit->getASTContext();<br>
> + const SourceManager &SourceMgr = AST.getSourceManager();<br>
> +<br>
> + SourceLocation InputLocation =<br>
> + getMacroArgExpandedLocation(<wbr>SourceMgr, FE, Pos);<br>
> if (Pos.character == 0) {<br>
> return InputLocation;<br>
> }<br>
> @@ -396,20 +680,97 @@ SourceLocation ClangdUnit::getBeginningO<br>
> // token. If so, Take the beginning of this token.<br>
> // (It should be the same identifier because you can't have two adjacent<br>
> // identifiers without another token in between.)<br>
> - SourceLocation PeekBeforeLocation = Unit->getLocation(FE, Pos.line + 1,<br>
> - Pos.character);<br>
> - const SourceManager &SourceMgr = Unit->getSourceManager();<br>
> + SourceLocation PeekBeforeLocation = getMacroArgExpandedLocation(<br>
> + SourceMgr, FE, Position{Pos.line, Pos.character - 1});<br>
> Token Result;<br>
> if (Lexer::getRawToken(<wbr>PeekBeforeLocation, Result, SourceMgr,<br>
> - Unit->getASTContext().<wbr>getLangOpts(), false)) {<br>
> + AST.getLangOpts(), false)) {<br>
> // getRawToken failed, just use InputLocation.<br>
> return InputLocation;<br>
> }<br>
><br>
> if (Result.is(tok::raw_<wbr>identifier)) {<br>
> return Lexer::GetBeginningOfToken(<wbr>PeekBeforeLocation, SourceMgr,<br>
> - Unit->getASTContext().<wbr>getLangOpts());<br>
> + Unit->getASTContext().<wbr>getLangOpts());<br>
> }<br>
><br>
> return InputLocation;<br>
> }<br>
> +<br>
> +void ClangdUnit::ParsedAST::<wbr>ensurePreambleDeclsDeserialize<wbr>d() {<br>
> + if (PendingTopLevelDecls.empty())<br>
> + return;<br>
> +<br>
> + std::vector<const Decl *> Resolved;<br>
> + Resolved.reserve(<wbr>PendingTopLevelDecls.size());<br>
> +<br>
> + ExternalASTSource &Source = *getASTContext().<wbr>getExternalSource();<br>
> + for (serialization::DeclID TopLevelDecl : PendingTopLevelDecls) {<br>
> + // Resolve the declaration ID to an actual declaration, possibly<br>
> + // deserializing the declaration in the process.<br>
> + if (Decl *D = Source.GetExternalDecl(<wbr>TopLevelDecl))<br>
> + Resolved.push_back(D);<br>
> + }<br>
> +<br>
> + TopLevelDecls.reserve(<wbr>TopLevelDecls.size() + PendingTopLevelDecls.size());<br>
> + TopLevelDecls.insert(<wbr>TopLevelDecls.begin(), Resolved.begin(),<br>
> Resolved.end());<br>
> +<br>
> + PendingTopLevelDecls.clear();<br>
> +}<br>
> +<br>
> +ClangdUnit::ParsedAST::<wbr>ParsedAST(ParsedAST &&Other) = default;<br>
> +<br>
> +ClangdUnit::ParsedAST &ClangdUnit::ParsedAST::<br>
> +operator=(ParsedAST &&Other) = default;<br>
> +<br>
> +ClangdUnit::ParsedAST::~<wbr>ParsedAST() {<br>
> + if (Action) {<br>
> + Action->EndSourceFile();<br>
> + }<br>
> +}<br>
> +<br>
> +ASTContext &ClangdUnit::ParsedAST::<wbr>getASTContext() {<br>
> + return Clang->getASTContext();<br>
> +}<br>
> +<br>
> +const ASTContext &ClangdUnit::ParsedAST::<wbr>getASTContext() const {<br>
> + return Clang->getASTContext();<br>
> +}<br>
> +<br>
> +Preprocessor &ClangdUnit::ParsedAST::<wbr>getPreprocessor() {<br>
> + return Clang->getPreprocessor();<br>
> +}<br>
> +<br>
> +const Preprocessor &ClangdUnit::ParsedAST::<wbr>getPreprocessor() const {<br>
> + return Clang->getPreprocessor();<br>
> +}<br>
> +<br>
> +ArrayRef<const Decl *> ClangdUnit::ParsedAST::<wbr>getTopLevelDecls() {<br>
> + ensurePreambleDeclsDeserialize<wbr>d();<br>
> + return TopLevelDecls;<br>
> +}<br>
> +<br>
> +const std::vector<DiagWithFixIts> &<br>
> +ClangdUnit::ParsedAST::<wbr>getDiagnostics() const {<br>
> + return Diags;<br>
> +}<br>
> +<br>
> +ClangdUnit::ParsedAST::<wbr>ParsedAST(<br>
> + std::unique_ptr<<wbr>CompilerInstance> Clang,<br>
> + std::unique_ptr<<wbr>FrontendAction> Action,<br>
> + std::vector<const Decl *> TopLevelDecls,<br>
> + std::vector<serialization::<wbr>DeclID> PendingTopLevelDecls,<br>
> + std::vector<DiagWithFixIts> Diags)<br>
> + : Clang(std::move(Clang)), Action(std::move(Action)),<br>
> + Diags(std::move(Diags)), TopLevelDecls(std::move(<wbr>TopLevelDecls)),<br>
> + PendingTopLevelDecls(std::<wbr>move(PendingTopLevelDecls)) {<br>
> + assert(this->Clang);<br>
> + assert(this->Action);<br>
> +}<br>
> +<br>
> +ClangdUnit::PreambleData::<wbr>PreambleData(<br>
> + PrecompiledPreamble Preamble,<br>
> + std::vector<serialization::<wbr>DeclID> TopLevelDeclIDs,<br>
> + std::vector<DiagWithFixIts> Diags)<br>
> + : Preamble(std::move(Preamble)),<br>
> + TopLevelDeclIDs(std::move(<wbr>TopLevelDeclIDs)), Diags(std::move(Diags)) {}<br>
><br>
> Modified: clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/clang-tools-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/clang-tools-</a><br>
> extra/trunk/clangd/ClangdUnit.<wbr>h?rev=308738&r1=308737&r2=<wbr>308738&view=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h (original)<br>
> +++ clang-tools-extra/trunk/<wbr>clangd/ClangdUnit.h Fri Jul 21 06:29:29 2017<br>
> @@ -13,6 +13,9 @@<br>
> #include "Path.h"<br>
> #include "Protocol.h"<br>
> #include "clang/Frontend/ASTUnit.h"<br>
> +#include "clang/Frontend/<wbr>PrecompiledPreamble.h"<br>
> +#include "clang/Serialization/<wbr>ASTBitCodes.h"<br>
> +#include "clang/Tooling/<wbr>CompilationDatabase.h"<br>
> #include "clang/Tooling/Core/<wbr>Replacement.h"<br>
> #include <memory><br>
><br>
> @@ -70,11 +73,82 @@ public:<br>
> void dumpAST(llvm::raw_ostream &OS) const;<br>
><br>
> private:<br>
> + /// Stores and provides access to parsed AST.<br>
> + class ParsedAST {<br>
> + public:<br>
> + /// Attempts to run Clang and store parsed AST. If \p Preamble is non-<br>
> null<br>
> + /// it is reused during parsing.<br>
> + static llvm::Optional<ParsedAST><br>
> + Build(std::unique_ptr<clang::<wbr>CompilerInvocation> CI,<br>
> + const PrecompiledPreamble *Preamble,<br>
> + ArrayRef<serialization::<wbr>DeclID> PreambleDeclIDs,<br>
> + std::unique_ptr<llvm::<wbr>MemoryBuffer> Buffer,<br>
> + std::shared_ptr<<wbr>PCHContainerOperations> PCHs,<br>
> + IntrusiveRefCntPtr<vfs::<wbr>FileSystem> VFS);<br>
> +<br>
> + ParsedAST(ParsedAST &&Other);<br>
> + ParsedAST &operator=(ParsedAST &&Other);<br>
> +<br>
> + ~ParsedAST();<br>
> +<br>
> + ASTContext &getASTContext();<br>
> + const ASTContext &getASTContext() const;<br>
> +<br>
> + Preprocessor &getPreprocessor();<br>
> + const Preprocessor &getPreprocessor() const;<br>
> +<br>
> + /// This function returns all top-level decls, including those that come<br>
> + /// from Preamble. Decls, coming from Preamble, have to be deserialized,<br>
> so<br>
> + /// this call might be expensive.<br>
> + ArrayRef<const Decl *> getTopLevelDecls();<br>
> +<br>
> + const std::vector<DiagWithFixIts> &getDiagnostics() const;<br>
> +<br>
> + private:<br>
> + ParsedAST(std::unique_ptr<<wbr>CompilerInstance> Clang,<br>
> + std::unique_ptr<<wbr>FrontendAction> Action,<br>
> + std::vector<const Decl *> TopLevelDecls,<br>
> + std::vector<serialization::<wbr>DeclID> PendingTopLevelDecls,<br>
> + std::vector<DiagWithFixIts> Diags);<br>
> +<br>
> + private:<br>
> + void ensurePreambleDeclsDeserialize<wbr>d();<br>
> +<br>
> + // We store an "incomplete" FrontendAction (i.e. no EndSourceFile was<br>
> called<br>
> + // on it) and CompilerInstance used to run it. That way we don't have to<br>
> do<br>
> + // complex memory management of all Clang structures on our own. (They<br>
> are<br>
> + // stored in CompilerInstance and cleaned up by<br>
> + // FrontendAction.EndSourceFile).<br>
> + std::unique_ptr<<wbr>CompilerInstance> Clang;<br>
> + std::unique_ptr<<wbr>FrontendAction> Action;<br>
> +<br>
> + // Data, stored after parsing.<br>
> + std::vector<DiagWithFixIts> Diags;<br>
> + std::vector<const Decl *> TopLevelDecls;<br>
> + std::vector<serialization::<wbr>DeclID> PendingTopLevelDecls;<br>
> + };<br>
> +<br>
> + // Store Preamble and all associated data<br>
> + struct PreambleData {<br>
> + PreambleData(<wbr>PrecompiledPreamble Preamble,<br>
> + std::vector<serialization::<wbr>DeclID> TopLevelDeclIDs,<br>
> + std::vector<DiagWithFixIts> Diags);<br>
> +<br>
> + PrecompiledPreamble Preamble;<br>
> + std::vector<serialization::<wbr>DeclID> TopLevelDeclIDs;<br>
> + std::vector<DiagWithFixIts> Diags;<br>
> + };<br>
> +<br>
> + SourceLocation getBeginningOfIdentifier(const Position &Pos,<br>
> + const FileEntry *FE) const;<br>
> +<br>
> Path FileName;<br>
> - std::unique_ptr<ASTUnit> Unit;<br>
> - std::shared_ptr<<wbr>PCHContainerOperations> PCHs;<br>
> + tooling::CompileCommand Command;<br>
><br>
> - SourceLocation getBeginningOfIdentifier(const Position& Pos, const<br>
> FileEntry* FE) const;<br>
> + llvm::Optional<PreambleData> Preamble;<br>
> + llvm::Optional<ParsedAST> Unit;<br>
> +<br>
> + std::shared_ptr<<wbr>PCHContainerOperations> PCHs;<br>
> };<br>
><br>
> } // namespace clangd<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Regards,</div><div>Ilya Biryukov</div></div></div></div></div>
</div>