malaperle requested changes to this revision. malaperle added inline comments. This revision now requires changes to proceed.
================ Comment at: clangd/ClangdServer.cpp:454 + + IncludeReferenceMap IRM = std::move(AST->takeIRM()); + Result = clangd::findDefinitions(*AST, Pos, Logger, IRM.IncludeLocationMap); ---------------- IncludeReferenceMap & here? See other comment in takeIRM ================ Comment at: clangd/ClangdUnit.cpp:34 #include <chrono> +#include <iostream> ---------------- remove ================ Comment at: clangd/ClangdUnit.cpp:77 -class CppFilePreambleCallbacks : public PreambleCallbacks { +void fillRangeVector( + const SourceManager &SM, ---------------- remove ================ Comment at: clangd/ClangdUnit.cpp:96 + +void findPreambleIncludes( + const SourceManager &SM, ---------------- remove ================ Comment at: clangd/ClangdUnit.cpp:118 + CppFilePreambleCallbacks(SourceManager *SourceMgr, IncludeReferenceMap &IRM) + : SourceMgr(SourceMgr), IRM(IRM) {} + ---------------- These need to be swapped to be in the same order that they are declared below. ================ Comment at: clangd/ClangdUnit.cpp:120 + + IncludeReferenceMap takeIRM() { + fillRangeVector(*SourceMgr, IRM.DataVector, IRM.RangeVector); ---------------- I don't think we need this if we pass the map by reference (and store it as a reference, see other comment) ================ Comment at: clangd/ClangdUnit.cpp:127 + + IncludeReferenceMap getIRM() { return IRM; }; + ---------------- Remove (see previous comment) ================ Comment at: clangd/ClangdUnit.cpp:155 + } + + void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, ---------------- I tried to simply the methods introduced here: ``` void AfterExecute(CompilerInstance &CI) override { SourceMgr = &CI.getSourceManager(); for (auto InclusionLoc : TempPreambleIncludeLocations) addIncludeLocation(InclusionLoc); } void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, const Module *Imported) override { auto SR = FilenameRange.getAsRange(); if (SR.isInvalid() || !File || File->tryGetRealPathName().empty()) return; if (SourceMgr) { addIncludeLocation({SR, File->tryGetRealPathName()}); } else { // When we are processing the inclusion directives inside the preamble, // we don't have access to a SourceManager, so we cannot convert // SourceRange to Range. This is done instead in AfterExecute when a // SourceManager becomes available. TempPreambleIncludeLocations.push_back({SR, File->tryGetRealPathName()}); } } void addIncludeLocation(std::pair<SourceRange, std::string> InclusionLoc) { // Only inclusion directives in the main file make sense. The user cannot // select directives not in the main file. if (SourceMgr->getMainFileID() == SourceMgr->getFileID(InclusionLoc.first.getBegin())) IRM.insert({getRange(InclusionLoc.first), InclusionLoc.second}); } Range getRange(SourceRange SR) { Position Begin; Begin.line = SourceMgr->getSpellingLineNumber(SR.getBegin()); Begin.character = SourceMgr->getSpellingColumnNumber(SR.getBegin()); Position End; End.line = SourceMgr->getSpellingLineNumber(SR.getEnd()); End.character = SourceMgr->getSpellingColumnNumber(SR.getEnd()); return {Begin, End}; } ``` ================ Comment at: clangd/ClangdUnit.cpp:177 + Range R = {Begin, End}; + if (File && !File->tryGetRealPathName().empty()) + IRM.IncludeLocationMap.insert({R, File->tryGetRealPathName()}); ---------------- I think we need a "is main file" check here. In case this is used on a AST with no preamble. ================ Comment at: clangd/ClangdUnit.cpp:209 std::vector<serialization::DeclID> TopLevelDeclIDs; + IncludeReferenceMap IRM; + SourceManager *SourceMgr; ---------------- IncludeReferenceMap &IRM; That way, we can use the same map and pass it multiple times to different "collectors". ================ Comment at: clangd/ClangdUnit.cpp:266 +class EmptyDiagsConsumer : public DiagnosticConsumer { +public: ---------------- I don't think this change was brought back intentionally? ================ Comment at: clangd/ClangdUnit.cpp:288 IntrusiveRefCntPtr<vfs::FileSystem> VFS, - clangd::Logger &Logger) { + clangd::Logger &Logger, IncludeReferenceMap IRM) { ---------------- IncludeReferenceMap &IRM ================ Comment at: clangd/ClangdUnit.cpp:314 + + Clang->getPreprocessor().addPPCallbacks(std::move(SerializedDeclsCollector.createPPCallbacks())); + ---------------- unnecessary std::move ================ Comment at: clangd/ClangdUnit.cpp:325 + std::move(ParsedDecls), std::move(ASTDiags), + std::move(SerializedDeclsCollector.getIRM())); } ---------------- std::move(IRM) ================ Comment at: clangd/ClangdUnit.cpp:345 /// Finds declarations locations that a given source location refers to. class DeclarationLocationsFinder : public index::IndexDataConsumer { std::vector<Location> DeclarationLocations; ---------------- I think after rebase, all this code in DeclarationLocationsFinder will need to be moved around, probably inside clangd::findDefinitions? ================ Comment at: clangd/ClangdUnit.cpp:420 + + for (auto It = IncludeLocationMap.begin(); It != IncludeLocationMap.end(); + ++It) { ---------------- ``` for (auto &IncludeLoc : IncludeLocationMap) { Range R = IncludeLoc.first; if (isSameLine(R.start.line)) addLocation(URI::fromFile(IncludeLoc.second), R); } ``` ================ Comment at: clangd/ClangdUnit.cpp:427 + } + // Also handle possible macro at the searched location. ---------------- Probably if an include location was found, we don't want to continue and it should early return. ================ Comment at: clangd/ClangdUnit.cpp:707 + IncludeReferenceMap IRM; + CppFilePreambleCallbacks SerializedDeclsCollector(nullptr, IRM); std::unique_ptr<llvm::MemoryBuffer> ContentsBuffer = ---------------- I think you can put the construction of SerializedDeclsCollector back to where it was. ================ Comment at: clangd/ClangdUnit.cpp:776 + std::move(CI), std::move(NewPreamble), std::move(ContentsBuffer), + PCHs, VFS, That->Logger, SerializedDeclsCollector.getIRM()); } ---------------- You can pass just IRM, so there is no need for the getIRM. We'll have eventually to transfer ownership to ParsedAST so maybe std::move(IRM) here? ================ Comment at: clangd/ClangdUnit.h:63 +class IncludeReferenceMap { + llvm::Optional<PathRef> findIncludeTargetAtLoc(Location Loc); ---------------- With the map being the only field left (see other comments), there is no need for a class I think. Maybe make a handy type alias for this? ``` using IncludeReferenceMap = std::unordered_map<Range, Path, RangeHash>; ``` ================ Comment at: clangd/ClangdUnit.h:64 +class IncludeReferenceMap { + llvm::Optional<PathRef> findIncludeTargetAtLoc(Location Loc); + ---------------- findIncludeTargetAtLoc is never used, remove ================ Comment at: clangd/ClangdUnit.h:68 + std::unordered_map<Range, Path, RangeHash> IncludeLocationMap; + std::vector<std::pair<SourceRange, std::string>> DataVector; + std::vector<Range> RangeVector; ---------------- No need to keep this. ================ Comment at: clangd/ClangdUnit.h:69 + std::vector<std::pair<SourceRange, std::string>> DataVector; + std::vector<Range> RangeVector; +}; ---------------- No need to keep this. ================ Comment at: clangd/ClangdUnit.h:103 + IncludeReferenceMap takeIRM() { return IRM; }; + ---------------- We need to keep this copy of IRM alive for subsequent calls to "open definition" for the same ParsedAST. So it is correct to not do a std::move here. However, I think it should be changed to: ``` IncludeReferenceMap &getIRM() ``` and also the caller should assign to a reference. ================ Comment at: clangd/ClangdUnit.h:130 bool PreambleDeclsDeserialized; + std::vector<serialization::DeclID> PendingTopLevelDecls; + IncludeReferenceMap IRM; ---------------- this wrongly came back? ================ Comment at: unittests/clangd/ClangdTests.cpp:622 Position Pos{LineDist(RandGen), ColumnDist(RandGen)}; - ASSERT_TRUE(!!Server.findDefinitions(FilePaths[FileIndex], Pos)); + Server.findDefinitions(FilePaths[FileIndex], Pos); }; ---------------- why is this check removed? ================ Comment at: unittests/clangd/ClangdTests.cpp:751 +TEST_F(ClangdVFSTest, CheckDefinitionIncludes) { + MockFSProvider FS; ---------------- Need to test includes outside preamble. ================ Comment at: unittests/clangd/ClangdTests.cpp:778 + + std::vector<Location> Locations = Server.findDefinitions(FooCpp, P).get().Value; + EXPECT_TRUE(!Locations.empty()); ---------------- I get an "unchecked assertion" here before the Expected is not checked. I was able to replace it with: ``` auto ExpectedLocations = Server.findDefinitions(FooCpp, P); ASSERT_TRUE(!!ExpectedLocations); std::vector<Location> Locations = ExpectedLocations->Value; ``` ================ Comment at: unittests/clangd/ClangdTests.cpp:784 + check = check.substr(0, check.size() - 1); + ASSERT_EQ(check, FooH); + ASSERT_EQ(Locations[0].range.start.line, 0); ---------------- I get a test failure here. ``` ../tools/clang/tools/extra/unittests/clangd/ClangdTests.cpp(785): Error: Expected: check Which is: "clangd-test/foo." To be equal to: FooH Which is: { '/' (47, 0x2F), 'c' (99, 0x63), 'l' (108, 0x6C), 'a' (97, 0x61), 'n' (110, 0x6E), 'g' (103, 0x67), 'd' (100, 0x64), '-' (45, 0x2D), 't' (116, 0x74), 'e' (101, 0x65), 's' (115, 0x73), 't' (116, 0x74), '/' (47, 0x2F), 'f' (102, 0x66), 'o' (111, 0x6F), 'o' (111, 0x6F), '.' (46, 0x2E), 'h' (104, 0x68) } ``` Not sure what's wrong. There is an additional front slash and missing ".h" at the end? ================ Comment at: unittests/clangd/ClangdTests.cpp:793 + + Locations = Server.findDefinitions(FooCpp, P3).get().Value; + EXPECT_TRUE(!Locations.empty()); ---------------- Similar unchecked problem here, this works (although a bit yucky): ``` ExpectedLocations = Server.findDefinitions(FooCpp, P3); ASSERT_TRUE(!!ExpectedLocations); Locations = ExpectedLocations->Value; EXPECT_TRUE(!Locations.empty()); // Test invalid include Position P2 = Position{2, 11}; ExpectedLocations = Server.findDefinitions(FooCpp, P2); ASSERT_TRUE(!!ExpectedLocations); Locations = ExpectedLocations->Value; EXPECT_TRUE(Locations.empty()); ``` Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D38639 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits