[clang-tools-extra] r370862 - [clangd] Rename ClangdUnit.h -> ParsedAST.h. NFC

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 4 02:46:07 PDT 2019


Author: sammccall
Date: Wed Sep  4 02:46:06 2019
New Revision: 370862

URL: http://llvm.org/viewvc/llvm-project?rev=370862&view=rev
Log:
[clangd] Rename ClangdUnit.h -> ParsedAST.h. NFC

This much better reflects what is (now) in this header.
Maybe a rename to ParsedTU would be an improvement, but that's a much
more invasive change and life is too short.

ClangdUnit is dead, long live ClangdUnitTests!

Added:
    clang-tools-extra/trunk/clangd/ParsedAST.cpp
    clang-tools-extra/trunk/clangd/ParsedAST.h
    clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp
Removed:
    clang-tools-extra/trunk/clangd/ClangdUnit.cpp
    clang-tools-extra/trunk/clangd/ClangdUnit.h
    clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp
Modified:
    clang-tools-extra/trunk/clangd/CMakeLists.txt
    clang-tools-extra/trunk/clangd/ClangdServer.cpp
    clang-tools-extra/trunk/clangd/FindSymbols.cpp
    clang-tools-extra/trunk/clangd/Preamble.cpp
    clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp
    clang-tools-extra/trunk/clangd/SemanticHighlighting.h
    clang-tools-extra/trunk/clangd/TUScheduler.cpp
    clang-tools-extra/trunk/clangd/XRefs.cpp
    clang-tools-extra/trunk/clangd/XRefs.h
    clang-tools-extra/trunk/clangd/index/Background.cpp
    clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp
    clang-tools-extra/trunk/clangd/index/FileIndex.cpp
    clang-tools-extra/trunk/clangd/refactor/Rename.cpp
    clang-tools-extra/trunk/clangd/refactor/Tweak.h
    clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractFunction.cpp
    clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp
    clang-tools-extra/trunk/clangd/refactor/tweaks/RawStringLiteral.cpp
    clang-tools-extra/trunk/clangd/refactor/tweaks/SwapIfBranches.cpp
    clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt
    clang-tools-extra/trunk/clangd/unittests/DiagnosticsTests.cpp
    clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp
    clang-tools-extra/trunk/clangd/unittests/FileIndexTests.cpp
    clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp
    clang-tools-extra/trunk/clangd/unittests/SymbolInfoTests.cpp
    clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp
    clang-tools-extra/trunk/clangd/unittests/TestTU.h
    clang-tools-extra/trunk/clangd/unittests/TypeHierarchyTests.cpp
    clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp

Modified: clang-tools-extra/trunk/clangd/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/CMakeLists.txt?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/CMakeLists.txt Wed Sep  4 02:46:06 2019
@@ -39,7 +39,6 @@ add_clang_library(clangDaemon
   Cancellation.cpp
   ClangdLSPServer.cpp
   ClangdServer.cpp
-  ClangdUnit.cpp
   CodeComplete.cpp
   CodeCompletionStrings.cpp
   Compiler.cpp
@@ -62,6 +61,7 @@ add_clang_library(clangDaemon
   Logger.cpp
   Protocol.cpp
   Quality.cpp
+  ParsedAST.cpp
   Preamble.cpp
   RIFF.cpp
   Selection.cpp

Modified: clang-tools-extra/trunk/clangd/ClangdServer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdServer.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdServer.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdServer.cpp Wed Sep  4 02:46:06 2019
@@ -7,12 +7,12 @@
 //===-------------------------------------------------------------------===//
 
 #include "ClangdServer.h"
-#include "ClangdUnit.h"
 #include "CodeComplete.h"
 #include "FindSymbols.h"
 #include "Format.h"
 #include "FormattedString.h"
 #include "Headers.h"
+#include "ParsedAST.h"
 #include "Preamble.h"
 #include "Protocol.h"
 #include "SemanticHighlighting.h"

Removed: clang-tools-extra/trunk/clangd/ClangdUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.cpp?rev=370861&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.cpp (removed)
@@ -1,574 +0,0 @@
-//===--- ClangdUnit.cpp ------------------------------------------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "ClangdUnit.h"
-#include "../clang-tidy/ClangTidyDiagnosticConsumer.h"
-#include "../clang-tidy/ClangTidyModuleRegistry.h"
-#include "AST.h"
-#include "Compiler.h"
-#include "Diagnostics.h"
-#include "Headers.h"
-#include "IncludeFixer.h"
-#include "Logger.h"
-#include "SourceCode.h"
-#include "Trace.h"
-#include "index/CanonicalIncludes.h"
-#include "index/Index.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/Basic/LangOptions.h"
-#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Frontend/Utils.h"
-#include "clang/Index/IndexDataConsumer.h"
-#include "clang/Index/IndexingAction.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Lex/PPCallbacks.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Sema/Sema.h"
-#include "clang/Serialization/ASTWriter.h"
-#include "clang/Serialization/PCHContainerOperations.h"
-#include "clang/Tooling/CompilationDatabase.h"
-#include "clang/Tooling/Syntax/Tokens.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <memory>
-
-namespace clang {
-namespace clangd {
-namespace {
-
-template <class T> std::size_t getUsedBytes(const std::vector<T> &Vec) {
-  return Vec.capacity() * sizeof(T);
-}
-
-class DeclTrackingASTConsumer : public ASTConsumer {
-public:
-  DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
-      : TopLevelDecls(TopLevelDecls) {}
-
-  bool HandleTopLevelDecl(DeclGroupRef DG) override {
-    for (Decl *D : DG) {
-      auto &SM = D->getASTContext().getSourceManager();
-      if (!isInsideMainFile(D->getLocation(), SM))
-        continue;
-      if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
-        if (isImplicitTemplateInstantiation(ND))
-          continue;
-
-      // ObjCMethodDecl are not actually top-level decls.
-      if (isa<ObjCMethodDecl>(D))
-        continue;
-
-      TopLevelDecls.push_back(D);
-    }
-    return true;
-  }
-
-private:
-  std::vector<Decl *> &TopLevelDecls;
-};
-
-class ClangdFrontendAction : public SyntaxOnlyAction {
-public:
-  std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
-
-protected:
-  std::unique_ptr<ASTConsumer>
-  CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
-    return std::make_unique<DeclTrackingASTConsumer>(/*ref*/ TopLevelDecls);
-  }
-
-private:
-  std::vector<Decl *> TopLevelDecls;
-};
-
-// This collects macro expansions in the main file.
-// (Contrast with CollectMainFileMacros in Preamble.cpp, which collects macro
-// *definitions* in the preamble region of the main file).
-class CollectMainFileMacroExpansions : public PPCallbacks {
-  const SourceManager &SM;
-  std::vector<SourceLocation> &MainFileMacroLocs;
-
-public:
-  CollectMainFileMacroExpansions(const SourceManager &SM,
-                                 std::vector<SourceLocation> &MainFileMacroLocs)
-      : SM(SM), MainFileMacroLocs(MainFileMacroLocs) {}
-
-  virtual void MacroExpands(const Token &MacroNameTok,
-                            const MacroDefinition &MD, SourceRange Range,
-                            const MacroArgs *Args) {
-    SourceLocation L = MacroNameTok.getLocation();
-    if (!L.isMacroID() && isInsideMainFile(L, SM))
-      MainFileMacroLocs.push_back(L);
-  }
-};
-
-// When using a preamble, only preprocessor events outside its bounds are seen.
-// This is almost what we want: replaying transitive preprocessing wastes time.
-// However this confuses clang-tidy checks: they don't see any #includes!
-// So we replay the *non-transitive* #includes that appear in the main-file.
-// It would be nice to replay other events (macro definitions, ifdefs etc) but
-// this addresses the most common cases fairly cheaply.
-class ReplayPreamble : private PPCallbacks {
-public:
-  // Attach preprocessor hooks such that preamble events will be injected at
-  // the appropriate time.
-  // Events will be delivered to the *currently registered* PP callbacks.
-  static void attach(const IncludeStructure &Includes,
-                     CompilerInstance &Clang) {
-    auto &PP = Clang.getPreprocessor();
-    auto *ExistingCallbacks = PP.getPPCallbacks();
-    // No need to replay events if nobody is listening.
-    if (!ExistingCallbacks)
-      return;
-    PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
-        new ReplayPreamble(Includes, ExistingCallbacks,
-                           Clang.getSourceManager(), PP, Clang.getLangOpts())));
-    // We're relying on the fact that addPPCallbacks keeps the old PPCallbacks
-    // around, creating a chaining wrapper. Guard against other implementations.
-    assert(PP.getPPCallbacks() != ExistingCallbacks &&
-           "Expected chaining implementation");
-  }
-
-private:
-  ReplayPreamble(const IncludeStructure &Includes, PPCallbacks *Delegate,
-                 const SourceManager &SM, Preprocessor &PP,
-                 const LangOptions &LangOpts)
-      : Includes(Includes), Delegate(Delegate), SM(SM), PP(PP),
-        LangOpts(LangOpts) {}
-
-  // In a normal compile, the preamble traverses the following structure:
-  //
-  // mainfile.cpp
-  //   <built-in>
-  //     ... macro definitions like __cplusplus ...
-  //     <command-line>
-  //       ... macro definitions for args like -Dfoo=bar ...
-  //   "header1.h"
-  //     ... header file contents ...
-  //   "header2.h"
-  //     ... header file contents ...
-  //   ... main file contents ...
-  //
-  // When using a preamble, the "header1" and "header2" subtrees get skipped.
-  // We insert them right after the built-in header, which still appears.
-  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
-                   SrcMgr::CharacteristicKind Kind, FileID PrevFID) override {
-    // It'd be nice if there was a better way to identify built-in headers...
-    if (Reason == FileChangeReason::ExitFile &&
-        SM.getBuffer(PrevFID)->getBufferIdentifier() == "<built-in>")
-      replay();
-  }
-
-  void replay() {
-    for (const auto &Inc : Includes.MainFileIncludes) {
-      const FileEntry *File = nullptr;
-      if (Inc.Resolved != "")
-        if (auto FE = SM.getFileManager().getFile(Inc.Resolved))
-          File = *FE;
-
-      llvm::StringRef WrittenFilename =
-          llvm::StringRef(Inc.Written).drop_front().drop_back();
-      bool Angled = llvm::StringRef(Inc.Written).startswith("<");
-
-      // Re-lex the #include directive to find its interesting parts.
-      llvm::StringRef Src = SM.getBufferData(SM.getMainFileID());
-      Lexer RawLexer(SM.getLocForStartOfFile(SM.getMainFileID()), LangOpts,
-                     Src.begin(), Src.begin() + Inc.HashOffset, Src.end());
-      Token HashTok, IncludeTok, FilenameTok;
-      RawLexer.LexFromRawLexer(HashTok);
-      assert(HashTok.getKind() == tok::hash);
-      RawLexer.setParsingPreprocessorDirective(true);
-      RawLexer.LexFromRawLexer(IncludeTok);
-      IdentifierInfo *II = PP.getIdentifierInfo(IncludeTok.getRawIdentifier());
-      IncludeTok.setIdentifierInfo(II);
-      IncludeTok.setKind(II->getTokenID());
-      RawLexer.LexIncludeFilename(FilenameTok);
-
-      Delegate->InclusionDirective(
-          HashTok.getLocation(), IncludeTok, WrittenFilename, Angled,
-          CharSourceRange::getCharRange(FilenameTok.getLocation(),
-                                        FilenameTok.getEndLoc()),
-          File, "SearchPath", "RelPath", /*Imported=*/nullptr, Inc.FileKind);
-      if (File)
-        // FIXME: Use correctly named FileEntryRef.
-        Delegate->FileSkipped(FileEntryRef(File->getName(), *File), FilenameTok,
-                              Inc.FileKind);
-      else {
-        llvm::SmallString<1> UnusedRecovery;
-        Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
-      }
-    }
-  }
-
-  const IncludeStructure &Includes;
-  PPCallbacks *Delegate;
-  const SourceManager &SM;
-  Preprocessor &PP;
-  const LangOptions &LangOpts;
-};
-
-} // namespace
-
-void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
-  AST.getASTContext().getTranslationUnitDecl()->dump(OS, true);
-}
-
-llvm::Optional<ParsedAST>
-ParsedAST::build(std::unique_ptr<clang::CompilerInvocation> CI,
-                 llvm::ArrayRef<Diag> CompilerInvocationDiags,
-                 std::shared_ptr<const PreambleData> Preamble,
-                 std::unique_ptr<llvm::MemoryBuffer> Buffer,
-                 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-                 const SymbolIndex *Index, const ParseOptions &Opts) {
-  assert(CI);
-  // Command-line parsing sets DisableFree to true by default, but we don't want
-  // to leak memory in clangd.
-  CI->getFrontendOpts().DisableFree = false;
-  const PrecompiledPreamble *PreamblePCH =
-      Preamble ? &Preamble->Preamble : nullptr;
-
-  StoreDiags ASTDiags;
-  std::string Content = Buffer->getBuffer();
-  std::string Filename = Buffer->getBufferIdentifier(); // Absolute.
-
-  auto Clang = prepareCompilerInstance(std::move(CI), PreamblePCH,
-                                       std::move(Buffer), VFS, ASTDiags);
-  if (!Clang)
-    return None;
-
-  auto Action = std::make_unique<ClangdFrontendAction>();
-  const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
-  if (!Action->BeginSourceFile(*Clang, MainInput)) {
-    log("BeginSourceFile() failed when building AST for {0}",
-        MainInput.getFile());
-    return None;
-  }
-
-  // Set up ClangTidy. Must happen after BeginSourceFile() so ASTContext exists.
-  // Clang-tidy has some limitiations to ensure reasonable performance:
-  //  - checks don't see all preprocessor events in the preamble
-  //  - matchers run only over the main-file top-level decls (and can't see
-  //    ancestors outside this scope).
-  // In practice almost all checks work well without modifications.
-  std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
-  ast_matchers::MatchFinder CTFinder;
-  llvm::Optional<tidy::ClangTidyContext> CTContext;
-  {
-    trace::Span Tracer("ClangTidyInit");
-    dlog("ClangTidy configuration for file {0}: {1}", Filename,
-         tidy::configurationAsText(Opts.ClangTidyOpts));
-    tidy::ClangTidyCheckFactories CTFactories;
-    for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
-      E.instantiate()->addCheckFactories(CTFactories);
-    CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
-        tidy::ClangTidyGlobalOptions(), Opts.ClangTidyOpts));
-    CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
-    CTContext->setASTContext(&Clang->getASTContext());
-    CTContext->setCurrentFile(Filename);
-    CTFactories.createChecks(CTContext.getPointer(), CTChecks);
-    ASTDiags.setLevelAdjuster([&CTContext](DiagnosticsEngine::Level DiagLevel,
-                                           const clang::Diagnostic &Info) {
-      if (CTContext) {
-        std::string CheckName = CTContext->getCheckName(Info.getID());
-        bool IsClangTidyDiag = !CheckName.empty();
-        if (IsClangTidyDiag) {
-          // Check for warning-as-error.
-          // We deliberately let this take precedence over suppression comments
-          // to match clang-tidy's behaviour.
-          if (DiagLevel == DiagnosticsEngine::Warning &&
-              CTContext->treatAsError(CheckName)) {
-            return DiagnosticsEngine::Error;
-          }
-
-          // Check for suppression comment. Skip the check for diagnostics not
-          // in the main file, because we don't want that function to query the
-          // source buffer for preamble files. For the same reason, we ask
-          // ShouldSuppressDiagnostic not to follow macro expansions, since
-          // those might take us into a preamble file as well.
-          bool IsInsideMainFile =
-              Info.hasSourceManager() &&
-              isInsideMainFile(Info.getLocation(), Info.getSourceManager());
-          if (IsInsideMainFile && tidy::ShouldSuppressDiagnostic(
-                                      DiagLevel, Info, *CTContext,
-                                      /* CheckMacroExpansion = */ false)) {
-            return DiagnosticsEngine::Ignored;
-          }
-        }
-      }
-      return DiagLevel;
-    });
-    Preprocessor *PP = &Clang->getPreprocessor();
-    for (const auto &Check : CTChecks) {
-      // FIXME: the PP callbacks skip the entire preamble.
-      // Checks that want to see #includes in the main file do not see them.
-      Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
-      Check->registerMatchers(&CTFinder);
-    }
-  }
-
-  // Add IncludeFixer which can recover diagnostics caused by missing includes
-  // (e.g. incomplete type) and attach include insertion fixes to diagnostics.
-  llvm::Optional<IncludeFixer> FixIncludes;
-  auto BuildDir = VFS->getCurrentWorkingDirectory();
-  if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) {
-    auto Style = getFormatStyleForFile(Filename, Content, VFS.get());
-    auto Inserter = std::make_shared<IncludeInserter>(
-        Filename, Content, Style, BuildDir.get(),
-        &Clang->getPreprocessor().getHeaderSearchInfo());
-    if (Preamble) {
-      for (const auto &Inc : Preamble->Includes.MainFileIncludes)
-        Inserter->addExisting(Inc);
-    }
-    FixIncludes.emplace(Filename, Inserter, *Index,
-                        /*IndexRequestLimit=*/5);
-    ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
-                                            const clang::Diagnostic &Info) {
-      return FixIncludes->fix(DiagLevl, Info);
-    });
-    Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
-  }
-
-  // Copy over the includes from the preamble, then combine with the
-  // non-preamble includes below.
-  auto Includes = Preamble ? Preamble->Includes : IncludeStructure{};
-  // Replay the preamble includes so that clang-tidy checks can see them.
-  if (Preamble)
-    ReplayPreamble::attach(Includes, *Clang);
-  // Important: collectIncludeStructure is registered *after* ReplayPreamble!
-  // Otherwise we would collect the replayed includes again...
-  // (We can't *just* use the replayed includes, they don't have Resolved path).
-  Clang->getPreprocessor().addPPCallbacks(
-      collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
-  // Collect the macro expansions in the main file.
-  std::vector<SourceLocation> MainFileMacroExpLocs;
-  Clang->getPreprocessor().addPPCallbacks(
-      std::make_unique<CollectMainFileMacroExpansions>(
-          Clang->getSourceManager(), MainFileMacroExpLocs));
-
-  // Copy over the includes from the preamble, then combine with the
-  // non-preamble includes below.
-  CanonicalIncludes CanonIncludes;
-  if (Preamble)
-    CanonIncludes = Preamble->CanonIncludes;
-  else
-    addSystemHeadersMapping(&CanonIncludes, Clang->getLangOpts());
-  std::unique_ptr<CommentHandler> IWYUHandler =
-      collectIWYUHeaderMaps(&CanonIncludes);
-  Clang->getPreprocessor().addCommentHandler(IWYUHandler.get());
-
-  // Collect tokens of the main file.
-  syntax::TokenCollector CollectTokens(Clang->getPreprocessor());
-
-  if (llvm::Error Err = Action->Execute())
-    log("Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
-        toString(std::move(Err)));
-
-  // We have to consume the tokens before running clang-tidy to avoid collecting
-  // tokens from running the preprocessor inside the checks (only
-  // modernize-use-trailing-return-type does that today).
-  syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
-  std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls();
-  // AST traversals should exclude the preamble, to avoid performance cliffs.
-  Clang->getASTContext().setTraversalScope(ParsedDecls);
-  {
-    // Run the AST-dependent part of the clang-tidy checks.
-    // (The preprocessor part ran already, via PPCallbacks).
-    trace::Span Tracer("ClangTidyMatch");
-    CTFinder.matchAST(Clang->getASTContext());
-  }
-
-  // UnitDiagsConsumer is local, we can not store it in CompilerInstance that
-  // has a longer lifetime.
-  Clang->getDiagnostics().setClient(new IgnoreDiagnostics);
-  // CompilerInstance won't run this callback, do it directly.
-  ASTDiags.EndSourceFile();
-  // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF.
-  // However Action->EndSourceFile() would destroy the ASTContext!
-  // So just inform the preprocessor of EOF, while keeping everything alive.
-  Clang->getPreprocessor().EndSourceFile();
-
-  std::vector<Diag> Diags = CompilerInvocationDiags;
-  // Add diagnostics from the preamble, if any.
-  if (Preamble)
-    Diags.insert(Diags.end(), Preamble->Diags.begin(), Preamble->Diags.end());
-  // Finally, add diagnostics coming from the AST.
-  {
-    std::vector<Diag> D = ASTDiags.take(CTContext.getPointer());
-    Diags.insert(Diags.end(), D.begin(), D.end());
-  }
-  return ParsedAST(std::move(Preamble), std::move(Clang), std::move(Action),
-                   std::move(Tokens), std::move(MainFileMacroExpLocs),
-                   std::move(ParsedDecls), std::move(Diags),
-                   std::move(Includes), std::move(CanonIncludes));
-}
-
-ParsedAST::ParsedAST(ParsedAST &&Other) = default;
-
-ParsedAST &ParsedAST::operator=(ParsedAST &&Other) = default;
-
-ParsedAST::~ParsedAST() {
-  if (Action) {
-    // We already notified the PP of end-of-file earlier, so detach it first.
-    // We must keep it alive until after EndSourceFile(), Sema relies on this.
-    auto PP = Clang->getPreprocessorPtr(); // Keep PP alive for now.
-    Clang->setPreprocessor(nullptr);       // Detach so we don't send EOF again.
-    Action->EndSourceFile();               // Destroy ASTContext and Sema.
-    // Now Sema is gone, it's safe for PP to go out of scope.
-  }
-}
-
-ASTContext &ParsedAST::getASTContext() { return Clang->getASTContext(); }
-
-const ASTContext &ParsedAST::getASTContext() const {
-  return Clang->getASTContext();
-}
-
-Preprocessor &ParsedAST::getPreprocessor() { return Clang->getPreprocessor(); }
-
-std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
-  return Clang->getPreprocessorPtr();
-}
-
-const Preprocessor &ParsedAST::getPreprocessor() const {
-  return Clang->getPreprocessor();
-}
-
-llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
-  return LocalTopLevelDecls;
-}
-
-llvm::ArrayRef<SourceLocation> ParsedAST::getMainFileExpansions() const {
-  return MainFileMacroExpLocs;
-}
-
-const std::vector<Diag> &ParsedAST::getDiagnostics() const { return Diags; }
-
-std::size_t ParsedAST::getUsedBytes() const {
-  auto &AST = getASTContext();
-  // FIXME(ibiryukov): we do not account for the dynamically allocated part of
-  // Message and Fixes inside each diagnostic.
-  std::size_t Total =
-      clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
-
-  // FIXME: the rest of the function is almost a direct copy-paste from
-  // libclang's clang_getCXTUResourceUsage. We could share the implementation.
-
-  // Sum up variaous allocators inside the ast context and the preprocessor.
-  Total += AST.getASTAllocatedMemory();
-  Total += AST.getSideTableAllocatedMemory();
-  Total += AST.Idents.getAllocator().getTotalMemory();
-  Total += AST.Selectors.getTotalMemory();
-
-  Total += AST.getSourceManager().getContentCacheSize();
-  Total += AST.getSourceManager().getDataStructureSizes();
-  Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
-
-  if (ExternalASTSource *Ext = AST.getExternalSource())
-    Total += Ext->getMemoryBufferSizes().malloc_bytes;
-
-  const Preprocessor &PP = getPreprocessor();
-  Total += PP.getTotalMemory();
-  if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
-    Total += PRec->getTotalMemory();
-  Total += PP.getHeaderSearchInfo().getTotalMemory();
-
-  return Total;
-}
-
-const IncludeStructure &ParsedAST::getIncludeStructure() const {
-  return Includes;
-}
-
-const CanonicalIncludes &ParsedAST::getCanonicalIncludes() const {
-  return CanonIncludes;
-}
-
-ParsedAST::ParsedAST(std::shared_ptr<const PreambleData> Preamble,
-                     std::unique_ptr<CompilerInstance> Clang,
-                     std::unique_ptr<FrontendAction> Action,
-                     syntax::TokenBuffer Tokens,
-                     std::vector<SourceLocation> MainFileMacroExpLocs,
-                     std::vector<Decl *> LocalTopLevelDecls,
-                     std::vector<Diag> Diags, IncludeStructure Includes,
-                     CanonicalIncludes CanonIncludes)
-    : Preamble(std::move(Preamble)), Clang(std::move(Clang)),
-      Action(std::move(Action)), Tokens(std::move(Tokens)),
-      MainFileMacroExpLocs(std::move(MainFileMacroExpLocs)),
-      Diags(std::move(Diags)),
-      LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
-      Includes(std::move(Includes)), CanonIncludes(std::move(CanonIncludes)) {
-  assert(this->Clang);
-  assert(this->Action);
-}
-
-llvm::Optional<ParsedAST>
-buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
-         llvm::ArrayRef<Diag> CompilerInvocationDiags,
-         const ParseInputs &Inputs,
-         std::shared_ptr<const PreambleData> Preamble) {
-  trace::Span Tracer("BuildAST");
-  SPAN_ATTACH(Tracer, "File", FileName);
-
-  auto VFS = Inputs.FS;
-  if (Preamble && Preamble->StatCache)
-    VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
-  if (VFS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
-    log("Couldn't set working directory when building the preamble.");
-    // We proceed anyway, our lit-tests rely on results for non-existing working
-    // dirs.
-  }
-
-  return ParsedAST::build(
-      std::make_unique<CompilerInvocation>(*Invocation),
-      CompilerInvocationDiags, Preamble,
-      llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, FileName),
-      std::move(VFS), Inputs.Index, Inputs.Opts);
-}
-
-} // namespace clangd
-namespace tidy {
-// Force the linker to link in Clang-tidy modules.
-#define LINK_TIDY_MODULE(X)                                                    \
-  extern volatile int X##ModuleAnchorSource;                                   \
-  static int LLVM_ATTRIBUTE_UNUSED X##ModuleAnchorDestination =                \
-      X##ModuleAnchorSource
-LINK_TIDY_MODULE(Abseil);
-LINK_TIDY_MODULE(Android);
-LINK_TIDY_MODULE(Boost);
-LINK_TIDY_MODULE(Bugprone);
-LINK_TIDY_MODULE(CERT);
-LINK_TIDY_MODULE(CppCoreGuidelines);
-LINK_TIDY_MODULE(Fuchsia);
-LINK_TIDY_MODULE(Google);
-LINK_TIDY_MODULE(HICPP);
-LINK_TIDY_MODULE(LinuxKernel);
-LINK_TIDY_MODULE(LLVM);
-LINK_TIDY_MODULE(Misc);
-LINK_TIDY_MODULE(Modernize);
-// LINK_TIDY_MODULE(MPI); // clangd doesn't support static analyzer.
-LINK_TIDY_MODULE(ObjC);
-LINK_TIDY_MODULE(OpenMP);
-LINK_TIDY_MODULE(Performance);
-LINK_TIDY_MODULE(Portability);
-LINK_TIDY_MODULE(Readability);
-LINK_TIDY_MODULE(Zircon);
-#undef LINK_TIDY_MODULE
-} // namespace tidy
-} // namespace clang

Removed: clang-tools-extra/trunk/clangd/ClangdUnit.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangdUnit.h?rev=370861&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangdUnit.h (original)
+++ clang-tools-extra/trunk/clangd/ClangdUnit.h (removed)
@@ -1,139 +0,0 @@
-//===--- ClangdUnit.h --------------------------------------------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H
-
-#include "Compiler.h"
-#include "Diagnostics.h"
-#include "Headers.h"
-#include "Path.h"
-#include "Preamble.h"
-#include "index/CanonicalIncludes.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Frontend/PrecompiledPreamble.h"
-#include "clang/Lex/Preprocessor.h"
-#include "clang/Tooling/CompilationDatabase.h"
-#include "clang/Tooling/Syntax/Tokens.h"
-#include "llvm/ADT/ArrayRef.h"
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace clang {
-namespace clangd {
-class SymbolIndex;
-
-/// Stores and provides access to parsed AST.
-class ParsedAST {
-public:
-  /// Attempts to run Clang and store parsed AST. If \p Preamble is non-null
-  /// it is reused during parsing.
-  static llvm::Optional<ParsedAST>
-  build(std::unique_ptr<clang::CompilerInvocation> CI,
-        llvm::ArrayRef<Diag> CompilerInvocationDiags,
-        std::shared_ptr<const PreambleData> Preamble,
-        std::unique_ptr<llvm::MemoryBuffer> Buffer,
-        llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
-        const SymbolIndex *Index, const ParseOptions &Opts);
-
-  ParsedAST(ParsedAST &&Other);
-  ParsedAST &operator=(ParsedAST &&Other);
-
-  ~ParsedAST();
-
-  /// Note that the returned ast will not contain decls from the preamble that
-  /// were not deserialized during parsing. Clients should expect only decls
-  /// from the main file to be in the AST.
-  ASTContext &getASTContext();
-  const ASTContext &getASTContext() const;
-
-  Preprocessor &getPreprocessor();
-  std::shared_ptr<Preprocessor> getPreprocessorPtr();
-  const Preprocessor &getPreprocessor() const;
-
-  SourceManager &getSourceManager() {
-    return getASTContext().getSourceManager();
-  }
-  const SourceManager &getSourceManager() const {
-    return getASTContext().getSourceManager();
-  }
-
-  /// This function returns top-level decls present in the main file of the AST.
-  /// The result does not include the decls that come from the preamble.
-  /// (These should be const, but RecursiveASTVisitor requires Decl*).
-  ArrayRef<Decl *> getLocalTopLevelDecls();
-
-  const std::vector<Diag> &getDiagnostics() const;
-
-  /// Returns the esitmated size of the AST and the accessory structures, in
-  /// bytes. Does not include the size of the preamble.
-  std::size_t getUsedBytes() const;
-  const IncludeStructure &getIncludeStructure() const;
-  const CanonicalIncludes &getCanonicalIncludes() const;
-
-  /// The start locations of all macro expansions spelled inside the main file.
-  /// Does not include expansions from inside other macro expansions.
-  llvm::ArrayRef<SourceLocation> getMainFileExpansions() const;
-  /// Tokens recorded while parsing the main file.
-  /// (!) does not have tokens from the preamble.
-  const syntax::TokenBuffer &getTokens() const { return Tokens; }
-
-private:
-  ParsedAST(std::shared_ptr<const PreambleData> Preamble,
-            std::unique_ptr<CompilerInstance> Clang,
-            std::unique_ptr<FrontendAction> Action, syntax::TokenBuffer Tokens,
-            std::vector<SourceLocation> MainFileMacroExpLocs,
-            std::vector<Decl *> LocalTopLevelDecls, std::vector<Diag> Diags,
-            IncludeStructure Includes, CanonicalIncludes CanonIncludes);
-
-  // In-memory preambles must outlive the AST, it is important that this member
-  // goes before Clang and Action.
-  std::shared_ptr<const PreambleData> Preamble;
-  // We store an "incomplete" FrontendAction (i.e. no EndSourceFile was called
-  // on it) and CompilerInstance used to run it. That way we don't have to do
-  // complex memory management of all Clang structures on our own. (They are
-  // stored in CompilerInstance and cleaned up by
-  // FrontendAction.EndSourceFile).
-  std::unique_ptr<CompilerInstance> Clang;
-  std::unique_ptr<FrontendAction> Action;
-  /// Tokens recorded after the preamble finished.
-  ///   - Includes all spelled tokens for the main file.
-  ///   - Includes expanded tokens produced **after** preabmle.
-  ///   - Does not have spelled or expanded tokens for files from preamble.
-  syntax::TokenBuffer Tokens;
-
-  /// The start locations of all macro expansions spelled inside the main file.
-  /// Does not include expansions from inside other macro expansions.
-  std::vector<SourceLocation> MainFileMacroExpLocs;
-  // Data, stored after parsing.
-  std::vector<Diag> Diags;
-  // Top-level decls inside the current file. Not that this does not include
-  // top-level decls from the preamble.
-  std::vector<Decl *> LocalTopLevelDecls;
-  IncludeStructure Includes;
-  CanonicalIncludes CanonIncludes;
-};
-
-/// Build an AST from provided user inputs. This function does not check if
-/// preamble can be reused, as this function expects that \p Preamble is the
-/// result of calling buildPreamble.
-llvm::Optional<ParsedAST>
-buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
-         llvm::ArrayRef<Diag> CompilerInvocationDiags,
-         const ParseInputs &Inputs,
-         std::shared_ptr<const PreambleData> Preamble);
-
-/// For testing/debugging purposes. Note that this method deserializes all
-/// unserialized Decls, so use with care.
-void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS);
-
-} // namespace clangd
-} // namespace clang
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H

Modified: clang-tools-extra/trunk/clangd/FindSymbols.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/FindSymbols.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/FindSymbols.cpp (original)
+++ clang-tools-extra/trunk/clangd/FindSymbols.cpp Wed Sep  4 02:46:06 2019
@@ -8,9 +8,9 @@
 #include "FindSymbols.h"
 
 #include "AST.h"
-#include "ClangdUnit.h"
 #include "FuzzyMatch.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Quality.h"
 #include "SourceCode.h"
 #include "index/Index.h"

Added: clang-tools-extra/trunk/clangd/ParsedAST.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ParsedAST.cpp?rev=370862&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/ParsedAST.cpp (added)
+++ clang-tools-extra/trunk/clangd/ParsedAST.cpp Wed Sep  4 02:46:06 2019
@@ -0,0 +1,574 @@
+//===--- ParsedAST.cpp -------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "ParsedAST.h"
+#include "../clang-tidy/ClangTidyDiagnosticConsumer.h"
+#include "../clang-tidy/ClangTidyModuleRegistry.h"
+#include "AST.h"
+#include "Compiler.h"
+#include "Diagnostics.h"
+#include "Headers.h"
+#include "IncludeFixer.h"
+#include "Logger.h"
+#include "SourceCode.h"
+#include "Trace.h"
+#include "index/CanonicalIncludes.h"
+#include "index/Index.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Index/IndexDataConsumer.h"
+#include "clang/Index/IndexingAction.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Serialization/ASTWriter.h"
+#include "clang/Serialization/PCHContainerOperations.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Syntax/Tokens.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <memory>
+
+namespace clang {
+namespace clangd {
+namespace {
+
+template <class T> std::size_t getUsedBytes(const std::vector<T> &Vec) {
+  return Vec.capacity() * sizeof(T);
+}
+
+class DeclTrackingASTConsumer : public ASTConsumer {
+public:
+  DeclTrackingASTConsumer(std::vector<Decl *> &TopLevelDecls)
+      : TopLevelDecls(TopLevelDecls) {}
+
+  bool HandleTopLevelDecl(DeclGroupRef DG) override {
+    for (Decl *D : DG) {
+      auto &SM = D->getASTContext().getSourceManager();
+      if (!isInsideMainFile(D->getLocation(), SM))
+        continue;
+      if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
+        if (isImplicitTemplateInstantiation(ND))
+          continue;
+
+      // ObjCMethodDecl are not actually top-level decls.
+      if (isa<ObjCMethodDecl>(D))
+        continue;
+
+      TopLevelDecls.push_back(D);
+    }
+    return true;
+  }
+
+private:
+  std::vector<Decl *> &TopLevelDecls;
+};
+
+class ClangdFrontendAction : public SyntaxOnlyAction {
+public:
+  std::vector<Decl *> takeTopLevelDecls() { return std::move(TopLevelDecls); }
+
+protected:
+  std::unique_ptr<ASTConsumer>
+  CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) override {
+    return std::make_unique<DeclTrackingASTConsumer>(/*ref*/ TopLevelDecls);
+  }
+
+private:
+  std::vector<Decl *> TopLevelDecls;
+};
+
+// This collects macro expansions in the main file.
+// (Contrast with CollectMainFileMacros in Preamble.cpp, which collects macro
+// *definitions* in the preamble region of the main file).
+class CollectMainFileMacroExpansions : public PPCallbacks {
+  const SourceManager &SM;
+  std::vector<SourceLocation> &MainFileMacroLocs;
+
+public:
+  CollectMainFileMacroExpansions(const SourceManager &SM,
+                                 std::vector<SourceLocation> &MainFileMacroLocs)
+      : SM(SM), MainFileMacroLocs(MainFileMacroLocs) {}
+
+  virtual void MacroExpands(const Token &MacroNameTok,
+                            const MacroDefinition &MD, SourceRange Range,
+                            const MacroArgs *Args) {
+    SourceLocation L = MacroNameTok.getLocation();
+    if (!L.isMacroID() && isInsideMainFile(L, SM))
+      MainFileMacroLocs.push_back(L);
+  }
+};
+
+// When using a preamble, only preprocessor events outside its bounds are seen.
+// This is almost what we want: replaying transitive preprocessing wastes time.
+// However this confuses clang-tidy checks: they don't see any #includes!
+// So we replay the *non-transitive* #includes that appear in the main-file.
+// It would be nice to replay other events (macro definitions, ifdefs etc) but
+// this addresses the most common cases fairly cheaply.
+class ReplayPreamble : private PPCallbacks {
+public:
+  // Attach preprocessor hooks such that preamble events will be injected at
+  // the appropriate time.
+  // Events will be delivered to the *currently registered* PP callbacks.
+  static void attach(const IncludeStructure &Includes,
+                     CompilerInstance &Clang) {
+    auto &PP = Clang.getPreprocessor();
+    auto *ExistingCallbacks = PP.getPPCallbacks();
+    // No need to replay events if nobody is listening.
+    if (!ExistingCallbacks)
+      return;
+    PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(
+        new ReplayPreamble(Includes, ExistingCallbacks,
+                           Clang.getSourceManager(), PP, Clang.getLangOpts())));
+    // We're relying on the fact that addPPCallbacks keeps the old PPCallbacks
+    // around, creating a chaining wrapper. Guard against other implementations.
+    assert(PP.getPPCallbacks() != ExistingCallbacks &&
+           "Expected chaining implementation");
+  }
+
+private:
+  ReplayPreamble(const IncludeStructure &Includes, PPCallbacks *Delegate,
+                 const SourceManager &SM, Preprocessor &PP,
+                 const LangOptions &LangOpts)
+      : Includes(Includes), Delegate(Delegate), SM(SM), PP(PP),
+        LangOpts(LangOpts) {}
+
+  // In a normal compile, the preamble traverses the following structure:
+  //
+  // mainfile.cpp
+  //   <built-in>
+  //     ... macro definitions like __cplusplus ...
+  //     <command-line>
+  //       ... macro definitions for args like -Dfoo=bar ...
+  //   "header1.h"
+  //     ... header file contents ...
+  //   "header2.h"
+  //     ... header file contents ...
+  //   ... main file contents ...
+  //
+  // When using a preamble, the "header1" and "header2" subtrees get skipped.
+  // We insert them right after the built-in header, which still appears.
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind Kind, FileID PrevFID) override {
+    // It'd be nice if there was a better way to identify built-in headers...
+    if (Reason == FileChangeReason::ExitFile &&
+        SM.getBuffer(PrevFID)->getBufferIdentifier() == "<built-in>")
+      replay();
+  }
+
+  void replay() {
+    for (const auto &Inc : Includes.MainFileIncludes) {
+      const FileEntry *File = nullptr;
+      if (Inc.Resolved != "")
+        if (auto FE = SM.getFileManager().getFile(Inc.Resolved))
+          File = *FE;
+
+      llvm::StringRef WrittenFilename =
+          llvm::StringRef(Inc.Written).drop_front().drop_back();
+      bool Angled = llvm::StringRef(Inc.Written).startswith("<");
+
+      // Re-lex the #include directive to find its interesting parts.
+      llvm::StringRef Src = SM.getBufferData(SM.getMainFileID());
+      Lexer RawLexer(SM.getLocForStartOfFile(SM.getMainFileID()), LangOpts,
+                     Src.begin(), Src.begin() + Inc.HashOffset, Src.end());
+      Token HashTok, IncludeTok, FilenameTok;
+      RawLexer.LexFromRawLexer(HashTok);
+      assert(HashTok.getKind() == tok::hash);
+      RawLexer.setParsingPreprocessorDirective(true);
+      RawLexer.LexFromRawLexer(IncludeTok);
+      IdentifierInfo *II = PP.getIdentifierInfo(IncludeTok.getRawIdentifier());
+      IncludeTok.setIdentifierInfo(II);
+      IncludeTok.setKind(II->getTokenID());
+      RawLexer.LexIncludeFilename(FilenameTok);
+
+      Delegate->InclusionDirective(
+          HashTok.getLocation(), IncludeTok, WrittenFilename, Angled,
+          CharSourceRange::getCharRange(FilenameTok.getLocation(),
+                                        FilenameTok.getEndLoc()),
+          File, "SearchPath", "RelPath", /*Imported=*/nullptr, Inc.FileKind);
+      if (File)
+        // FIXME: Use correctly named FileEntryRef.
+        Delegate->FileSkipped(FileEntryRef(File->getName(), *File), FilenameTok,
+                              Inc.FileKind);
+      else {
+        llvm::SmallString<1> UnusedRecovery;
+        Delegate->FileNotFound(WrittenFilename, UnusedRecovery);
+      }
+    }
+  }
+
+  const IncludeStructure &Includes;
+  PPCallbacks *Delegate;
+  const SourceManager &SM;
+  Preprocessor &PP;
+  const LangOptions &LangOpts;
+};
+
+} // namespace
+
+void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS) {
+  AST.getASTContext().getTranslationUnitDecl()->dump(OS, true);
+}
+
+llvm::Optional<ParsedAST>
+ParsedAST::build(std::unique_ptr<clang::CompilerInvocation> CI,
+                 llvm::ArrayRef<Diag> CompilerInvocationDiags,
+                 std::shared_ptr<const PreambleData> Preamble,
+                 std::unique_ptr<llvm::MemoryBuffer> Buffer,
+                 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
+                 const SymbolIndex *Index, const ParseOptions &Opts) {
+  assert(CI);
+  // Command-line parsing sets DisableFree to true by default, but we don't want
+  // to leak memory in clangd.
+  CI->getFrontendOpts().DisableFree = false;
+  const PrecompiledPreamble *PreamblePCH =
+      Preamble ? &Preamble->Preamble : nullptr;
+
+  StoreDiags ASTDiags;
+  std::string Content = Buffer->getBuffer();
+  std::string Filename = Buffer->getBufferIdentifier(); // Absolute.
+
+  auto Clang = prepareCompilerInstance(std::move(CI), PreamblePCH,
+                                       std::move(Buffer), VFS, ASTDiags);
+  if (!Clang)
+    return None;
+
+  auto Action = std::make_unique<ClangdFrontendAction>();
+  const FrontendInputFile &MainInput = Clang->getFrontendOpts().Inputs[0];
+  if (!Action->BeginSourceFile(*Clang, MainInput)) {
+    log("BeginSourceFile() failed when building AST for {0}",
+        MainInput.getFile());
+    return None;
+  }
+
+  // Set up ClangTidy. Must happen after BeginSourceFile() so ASTContext exists.
+  // Clang-tidy has some limitiations to ensure reasonable performance:
+  //  - checks don't see all preprocessor events in the preamble
+  //  - matchers run only over the main-file top-level decls (and can't see
+  //    ancestors outside this scope).
+  // In practice almost all checks work well without modifications.
+  std::vector<std::unique_ptr<tidy::ClangTidyCheck>> CTChecks;
+  ast_matchers::MatchFinder CTFinder;
+  llvm::Optional<tidy::ClangTidyContext> CTContext;
+  {
+    trace::Span Tracer("ClangTidyInit");
+    dlog("ClangTidy configuration for file {0}: {1}", Filename,
+         tidy::configurationAsText(Opts.ClangTidyOpts));
+    tidy::ClangTidyCheckFactories CTFactories;
+    for (const auto &E : tidy::ClangTidyModuleRegistry::entries())
+      E.instantiate()->addCheckFactories(CTFactories);
+    CTContext.emplace(std::make_unique<tidy::DefaultOptionsProvider>(
+        tidy::ClangTidyGlobalOptions(), Opts.ClangTidyOpts));
+    CTContext->setDiagnosticsEngine(&Clang->getDiagnostics());
+    CTContext->setASTContext(&Clang->getASTContext());
+    CTContext->setCurrentFile(Filename);
+    CTFactories.createChecks(CTContext.getPointer(), CTChecks);
+    ASTDiags.setLevelAdjuster([&CTContext](DiagnosticsEngine::Level DiagLevel,
+                                           const clang::Diagnostic &Info) {
+      if (CTContext) {
+        std::string CheckName = CTContext->getCheckName(Info.getID());
+        bool IsClangTidyDiag = !CheckName.empty();
+        if (IsClangTidyDiag) {
+          // Check for warning-as-error.
+          // We deliberately let this take precedence over suppression comments
+          // to match clang-tidy's behaviour.
+          if (DiagLevel == DiagnosticsEngine::Warning &&
+              CTContext->treatAsError(CheckName)) {
+            return DiagnosticsEngine::Error;
+          }
+
+          // Check for suppression comment. Skip the check for diagnostics not
+          // in the main file, because we don't want that function to query the
+          // source buffer for preamble files. For the same reason, we ask
+          // ShouldSuppressDiagnostic not to follow macro expansions, since
+          // those might take us into a preamble file as well.
+          bool IsInsideMainFile =
+              Info.hasSourceManager() &&
+              isInsideMainFile(Info.getLocation(), Info.getSourceManager());
+          if (IsInsideMainFile && tidy::ShouldSuppressDiagnostic(
+                                      DiagLevel, Info, *CTContext,
+                                      /* CheckMacroExpansion = */ false)) {
+            return DiagnosticsEngine::Ignored;
+          }
+        }
+      }
+      return DiagLevel;
+    });
+    Preprocessor *PP = &Clang->getPreprocessor();
+    for (const auto &Check : CTChecks) {
+      // FIXME: the PP callbacks skip the entire preamble.
+      // Checks that want to see #includes in the main file do not see them.
+      Check->registerPPCallbacks(Clang->getSourceManager(), PP, PP);
+      Check->registerMatchers(&CTFinder);
+    }
+  }
+
+  // Add IncludeFixer which can recover diagnostics caused by missing includes
+  // (e.g. incomplete type) and attach include insertion fixes to diagnostics.
+  llvm::Optional<IncludeFixer> FixIncludes;
+  auto BuildDir = VFS->getCurrentWorkingDirectory();
+  if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) {
+    auto Style = getFormatStyleForFile(Filename, Content, VFS.get());
+    auto Inserter = std::make_shared<IncludeInserter>(
+        Filename, Content, Style, BuildDir.get(),
+        &Clang->getPreprocessor().getHeaderSearchInfo());
+    if (Preamble) {
+      for (const auto &Inc : Preamble->Includes.MainFileIncludes)
+        Inserter->addExisting(Inc);
+    }
+    FixIncludes.emplace(Filename, Inserter, *Index,
+                        /*IndexRequestLimit=*/5);
+    ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl,
+                                            const clang::Diagnostic &Info) {
+      return FixIncludes->fix(DiagLevl, Info);
+    });
+    Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder());
+  }
+
+  // Copy over the includes from the preamble, then combine with the
+  // non-preamble includes below.
+  auto Includes = Preamble ? Preamble->Includes : IncludeStructure{};
+  // Replay the preamble includes so that clang-tidy checks can see them.
+  if (Preamble)
+    ReplayPreamble::attach(Includes, *Clang);
+  // Important: collectIncludeStructure is registered *after* ReplayPreamble!
+  // Otherwise we would collect the replayed includes again...
+  // (We can't *just* use the replayed includes, they don't have Resolved path).
+  Clang->getPreprocessor().addPPCallbacks(
+      collectIncludeStructureCallback(Clang->getSourceManager(), &Includes));
+  // Collect the macro expansions in the main file.
+  std::vector<SourceLocation> MainFileMacroExpLocs;
+  Clang->getPreprocessor().addPPCallbacks(
+      std::make_unique<CollectMainFileMacroExpansions>(
+          Clang->getSourceManager(), MainFileMacroExpLocs));
+
+  // Copy over the includes from the preamble, then combine with the
+  // non-preamble includes below.
+  CanonicalIncludes CanonIncludes;
+  if (Preamble)
+    CanonIncludes = Preamble->CanonIncludes;
+  else
+    addSystemHeadersMapping(&CanonIncludes, Clang->getLangOpts());
+  std::unique_ptr<CommentHandler> IWYUHandler =
+      collectIWYUHeaderMaps(&CanonIncludes);
+  Clang->getPreprocessor().addCommentHandler(IWYUHandler.get());
+
+  // Collect tokens of the main file.
+  syntax::TokenCollector CollectTokens(Clang->getPreprocessor());
+
+  if (llvm::Error Err = Action->Execute())
+    log("Execute() failed when building AST for {0}: {1}", MainInput.getFile(),
+        toString(std::move(Err)));
+
+  // We have to consume the tokens before running clang-tidy to avoid collecting
+  // tokens from running the preprocessor inside the checks (only
+  // modernize-use-trailing-return-type does that today).
+  syntax::TokenBuffer Tokens = std::move(CollectTokens).consume();
+  std::vector<Decl *> ParsedDecls = Action->takeTopLevelDecls();
+  // AST traversals should exclude the preamble, to avoid performance cliffs.
+  Clang->getASTContext().setTraversalScope(ParsedDecls);
+  {
+    // Run the AST-dependent part of the clang-tidy checks.
+    // (The preprocessor part ran already, via PPCallbacks).
+    trace::Span Tracer("ClangTidyMatch");
+    CTFinder.matchAST(Clang->getASTContext());
+  }
+
+  // UnitDiagsConsumer is local, we can not store it in CompilerInstance that
+  // has a longer lifetime.
+  Clang->getDiagnostics().setClient(new IgnoreDiagnostics);
+  // CompilerInstance won't run this callback, do it directly.
+  ASTDiags.EndSourceFile();
+  // XXX: This is messy: clang-tidy checks flush some diagnostics at EOF.
+  // However Action->EndSourceFile() would destroy the ASTContext!
+  // So just inform the preprocessor of EOF, while keeping everything alive.
+  Clang->getPreprocessor().EndSourceFile();
+
+  std::vector<Diag> Diags = CompilerInvocationDiags;
+  // Add diagnostics from the preamble, if any.
+  if (Preamble)
+    Diags.insert(Diags.end(), Preamble->Diags.begin(), Preamble->Diags.end());
+  // Finally, add diagnostics coming from the AST.
+  {
+    std::vector<Diag> D = ASTDiags.take(CTContext.getPointer());
+    Diags.insert(Diags.end(), D.begin(), D.end());
+  }
+  return ParsedAST(std::move(Preamble), std::move(Clang), std::move(Action),
+                   std::move(Tokens), std::move(MainFileMacroExpLocs),
+                   std::move(ParsedDecls), std::move(Diags),
+                   std::move(Includes), std::move(CanonIncludes));
+}
+
+ParsedAST::ParsedAST(ParsedAST &&Other) = default;
+
+ParsedAST &ParsedAST::operator=(ParsedAST &&Other) = default;
+
+ParsedAST::~ParsedAST() {
+  if (Action) {
+    // We already notified the PP of end-of-file earlier, so detach it first.
+    // We must keep it alive until after EndSourceFile(), Sema relies on this.
+    auto PP = Clang->getPreprocessorPtr(); // Keep PP alive for now.
+    Clang->setPreprocessor(nullptr);       // Detach so we don't send EOF again.
+    Action->EndSourceFile();               // Destroy ASTContext and Sema.
+    // Now Sema is gone, it's safe for PP to go out of scope.
+  }
+}
+
+ASTContext &ParsedAST::getASTContext() { return Clang->getASTContext(); }
+
+const ASTContext &ParsedAST::getASTContext() const {
+  return Clang->getASTContext();
+}
+
+Preprocessor &ParsedAST::getPreprocessor() { return Clang->getPreprocessor(); }
+
+std::shared_ptr<Preprocessor> ParsedAST::getPreprocessorPtr() {
+  return Clang->getPreprocessorPtr();
+}
+
+const Preprocessor &ParsedAST::getPreprocessor() const {
+  return Clang->getPreprocessor();
+}
+
+llvm::ArrayRef<Decl *> ParsedAST::getLocalTopLevelDecls() {
+  return LocalTopLevelDecls;
+}
+
+llvm::ArrayRef<SourceLocation> ParsedAST::getMainFileExpansions() const {
+  return MainFileMacroExpLocs;
+}
+
+const std::vector<Diag> &ParsedAST::getDiagnostics() const { return Diags; }
+
+std::size_t ParsedAST::getUsedBytes() const {
+  auto &AST = getASTContext();
+  // FIXME(ibiryukov): we do not account for the dynamically allocated part of
+  // Message and Fixes inside each diagnostic.
+  std::size_t Total =
+      clangd::getUsedBytes(LocalTopLevelDecls) + clangd::getUsedBytes(Diags);
+
+  // FIXME: the rest of the function is almost a direct copy-paste from
+  // libclang's clang_getCXTUResourceUsage. We could share the implementation.
+
+  // Sum up variaous allocators inside the ast context and the preprocessor.
+  Total += AST.getASTAllocatedMemory();
+  Total += AST.getSideTableAllocatedMemory();
+  Total += AST.Idents.getAllocator().getTotalMemory();
+  Total += AST.Selectors.getTotalMemory();
+
+  Total += AST.getSourceManager().getContentCacheSize();
+  Total += AST.getSourceManager().getDataStructureSizes();
+  Total += AST.getSourceManager().getMemoryBufferSizes().malloc_bytes;
+
+  if (ExternalASTSource *Ext = AST.getExternalSource())
+    Total += Ext->getMemoryBufferSizes().malloc_bytes;
+
+  const Preprocessor &PP = getPreprocessor();
+  Total += PP.getTotalMemory();
+  if (PreprocessingRecord *PRec = PP.getPreprocessingRecord())
+    Total += PRec->getTotalMemory();
+  Total += PP.getHeaderSearchInfo().getTotalMemory();
+
+  return Total;
+}
+
+const IncludeStructure &ParsedAST::getIncludeStructure() const {
+  return Includes;
+}
+
+const CanonicalIncludes &ParsedAST::getCanonicalIncludes() const {
+  return CanonIncludes;
+}
+
+ParsedAST::ParsedAST(std::shared_ptr<const PreambleData> Preamble,
+                     std::unique_ptr<CompilerInstance> Clang,
+                     std::unique_ptr<FrontendAction> Action,
+                     syntax::TokenBuffer Tokens,
+                     std::vector<SourceLocation> MainFileMacroExpLocs,
+                     std::vector<Decl *> LocalTopLevelDecls,
+                     std::vector<Diag> Diags, IncludeStructure Includes,
+                     CanonicalIncludes CanonIncludes)
+    : Preamble(std::move(Preamble)), Clang(std::move(Clang)),
+      Action(std::move(Action)), Tokens(std::move(Tokens)),
+      MainFileMacroExpLocs(std::move(MainFileMacroExpLocs)),
+      Diags(std::move(Diags)),
+      LocalTopLevelDecls(std::move(LocalTopLevelDecls)),
+      Includes(std::move(Includes)), CanonIncludes(std::move(CanonIncludes)) {
+  assert(this->Clang);
+  assert(this->Action);
+}
+
+llvm::Optional<ParsedAST>
+buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
+         llvm::ArrayRef<Diag> CompilerInvocationDiags,
+         const ParseInputs &Inputs,
+         std::shared_ptr<const PreambleData> Preamble) {
+  trace::Span Tracer("BuildAST");
+  SPAN_ATTACH(Tracer, "File", FileName);
+
+  auto VFS = Inputs.FS;
+  if (Preamble && Preamble->StatCache)
+    VFS = Preamble->StatCache->getConsumingFS(std::move(VFS));
+  if (VFS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) {
+    log("Couldn't set working directory when building the preamble.");
+    // We proceed anyway, our lit-tests rely on results for non-existing working
+    // dirs.
+  }
+
+  return ParsedAST::build(
+      std::make_unique<CompilerInvocation>(*Invocation),
+      CompilerInvocationDiags, Preamble,
+      llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents, FileName),
+      std::move(VFS), Inputs.Index, Inputs.Opts);
+}
+
+} // namespace clangd
+namespace tidy {
+// Force the linker to link in Clang-tidy modules.
+#define LINK_TIDY_MODULE(X)                                                    \
+  extern volatile int X##ModuleAnchorSource;                                   \
+  static int LLVM_ATTRIBUTE_UNUSED X##ModuleAnchorDestination =                \
+      X##ModuleAnchorSource
+LINK_TIDY_MODULE(Abseil);
+LINK_TIDY_MODULE(Android);
+LINK_TIDY_MODULE(Boost);
+LINK_TIDY_MODULE(Bugprone);
+LINK_TIDY_MODULE(CERT);
+LINK_TIDY_MODULE(CppCoreGuidelines);
+LINK_TIDY_MODULE(Fuchsia);
+LINK_TIDY_MODULE(Google);
+LINK_TIDY_MODULE(HICPP);
+LINK_TIDY_MODULE(LinuxKernel);
+LINK_TIDY_MODULE(LLVM);
+LINK_TIDY_MODULE(Misc);
+LINK_TIDY_MODULE(Modernize);
+// LINK_TIDY_MODULE(MPI); // clangd doesn't support static analyzer.
+LINK_TIDY_MODULE(ObjC);
+LINK_TIDY_MODULE(OpenMP);
+LINK_TIDY_MODULE(Performance);
+LINK_TIDY_MODULE(Portability);
+LINK_TIDY_MODULE(Readability);
+LINK_TIDY_MODULE(Zircon);
+#undef LINK_TIDY_MODULE
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clangd/ParsedAST.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ParsedAST.h?rev=370862&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/ParsedAST.h (added)
+++ clang-tools-extra/trunk/clangd/ParsedAST.h Wed Sep  4 02:46:06 2019
@@ -0,0 +1,151 @@
+//===--- ParsedAST.h - Building translation units ----------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes building a file as if it were open in clangd, and defines
+// the ParsedAST structure that holds the results.
+//
+// This is similar to a clang -fsyntax-only run that produces a clang AST, but
+// we have several customizations:
+//  - preamble handling
+//  - capturing diagnostics for later access
+//  - running clang-tidy checks checks
+//
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H
+
+#include "Compiler.h"
+#include "Diagnostics.h"
+#include "Headers.h"
+#include "Path.h"
+#include "Preamble.h"
+#include "index/CanonicalIncludes.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/PrecompiledPreamble.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Syntax/Tokens.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace clangd {
+class SymbolIndex;
+
+/// Stores and provides access to parsed AST.
+class ParsedAST {
+public:
+  /// Attempts to run Clang and store parsed AST. If \p Preamble is non-null
+  /// it is reused during parsing.
+  static llvm::Optional<ParsedAST>
+  build(std::unique_ptr<clang::CompilerInvocation> CI,
+        llvm::ArrayRef<Diag> CompilerInvocationDiags,
+        std::shared_ptr<const PreambleData> Preamble,
+        std::unique_ptr<llvm::MemoryBuffer> Buffer,
+        llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
+        const SymbolIndex *Index, const ParseOptions &Opts);
+
+  ParsedAST(ParsedAST &&Other);
+  ParsedAST &operator=(ParsedAST &&Other);
+
+  ~ParsedAST();
+
+  /// Note that the returned ast will not contain decls from the preamble that
+  /// were not deserialized during parsing. Clients should expect only decls
+  /// from the main file to be in the AST.
+  ASTContext &getASTContext();
+  const ASTContext &getASTContext() const;
+
+  Preprocessor &getPreprocessor();
+  std::shared_ptr<Preprocessor> getPreprocessorPtr();
+  const Preprocessor &getPreprocessor() const;
+
+  SourceManager &getSourceManager() {
+    return getASTContext().getSourceManager();
+  }
+  const SourceManager &getSourceManager() const {
+    return getASTContext().getSourceManager();
+  }
+
+  /// This function returns top-level decls present in the main file of the AST.
+  /// The result does not include the decls that come from the preamble.
+  /// (These should be const, but RecursiveASTVisitor requires Decl*).
+  ArrayRef<Decl *> getLocalTopLevelDecls();
+
+  const std::vector<Diag> &getDiagnostics() const;
+
+  /// Returns the esitmated size of the AST and the accessory structures, in
+  /// bytes. Does not include the size of the preamble.
+  std::size_t getUsedBytes() const;
+  const IncludeStructure &getIncludeStructure() const;
+  const CanonicalIncludes &getCanonicalIncludes() const;
+
+  /// The start locations of all macro expansions spelled inside the main file.
+  /// Does not include expansions from inside other macro expansions.
+  llvm::ArrayRef<SourceLocation> getMainFileExpansions() const;
+  /// Tokens recorded while parsing the main file.
+  /// (!) does not have tokens from the preamble.
+  const syntax::TokenBuffer &getTokens() const { return Tokens; }
+
+private:
+  ParsedAST(std::shared_ptr<const PreambleData> Preamble,
+            std::unique_ptr<CompilerInstance> Clang,
+            std::unique_ptr<FrontendAction> Action, syntax::TokenBuffer Tokens,
+            std::vector<SourceLocation> MainFileMacroExpLocs,
+            std::vector<Decl *> LocalTopLevelDecls, std::vector<Diag> Diags,
+            IncludeStructure Includes, CanonicalIncludes CanonIncludes);
+
+  // In-memory preambles must outlive the AST, it is important that this member
+  // goes before Clang and Action.
+  std::shared_ptr<const PreambleData> Preamble;
+  // We store an "incomplete" FrontendAction (i.e. no EndSourceFile was called
+  // on it) and CompilerInstance used to run it. That way we don't have to do
+  // complex memory management of all Clang structures on our own. (They are
+  // stored in CompilerInstance and cleaned up by
+  // FrontendAction.EndSourceFile).
+  std::unique_ptr<CompilerInstance> Clang;
+  std::unique_ptr<FrontendAction> Action;
+  /// Tokens recorded after the preamble finished.
+  ///   - Includes all spelled tokens for the main file.
+  ///   - Includes expanded tokens produced **after** preabmle.
+  ///   - Does not have spelled or expanded tokens for files from preamble.
+  syntax::TokenBuffer Tokens;
+
+  /// The start locations of all macro expansions spelled inside the main file.
+  /// Does not include expansions from inside other macro expansions.
+  std::vector<SourceLocation> MainFileMacroExpLocs;
+  // Data, stored after parsing.
+  std::vector<Diag> Diags;
+  // Top-level decls inside the current file. Not that this does not include
+  // top-level decls from the preamble.
+  std::vector<Decl *> LocalTopLevelDecls;
+  IncludeStructure Includes;
+  CanonicalIncludes CanonIncludes;
+};
+
+/// Build an AST from provided user inputs. This function does not check if
+/// preamble can be reused, as this function expects that \p Preamble is the
+/// result of calling buildPreamble.
+llvm::Optional<ParsedAST>
+buildAST(PathRef FileName, std::unique_ptr<CompilerInvocation> Invocation,
+         llvm::ArrayRef<Diag> CompilerInvocationDiags,
+         const ParseInputs &Inputs,
+         std::shared_ptr<const PreambleData> Preamble);
+
+/// For testing/debugging purposes. Note that this method deserializes all
+/// unserialized Decls, so use with care.
+void dumpAST(ParsedAST &AST, llvm::raw_ostream &OS);
+
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_PARSEDAST_H

Modified: clang-tools-extra/trunk/clangd/Preamble.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/Preamble.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/Preamble.cpp (original)
+++ clang-tools-extra/trunk/clangd/Preamble.cpp Wed Sep  4 02:46:06 2019
@@ -25,7 +25,7 @@ bool compileCommandsAreEqual(const tooli
 }
 
 // This collects macro definitions in the *preamble region* of the main file.
-// (Contrast with CollectMainFileMacroExpansions in ClangdUnit.cpp, which
+// (Contrast with CollectMainFileMacroExpansions in ParsedAST.cpp, which
 // collects macro *expansions* in the rest of the main file.
 class CollectMainFileMacros : public PPCallbacks {
 public:

Modified: clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp (original)
+++ clang-tools-extra/trunk/clangd/SemanticHighlighting.cpp Wed Sep  4 02:46:06 2019
@@ -8,6 +8,7 @@
 
 #include "SemanticHighlighting.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Protocol.h"
 #include "SourceCode.h"
 #include "clang/AST/ASTContext.h"

Modified: clang-tools-extra/trunk/clangd/SemanticHighlighting.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/SemanticHighlighting.h?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/SemanticHighlighting.h (original)
+++ clang-tools-extra/trunk/clangd/SemanticHighlighting.h Wed Sep  4 02:46:06 2019
@@ -17,11 +17,11 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SEMANTICHIGHLIGHTING_H
 
-#include "ClangdUnit.h"
 #include "Protocol.h"
 
 namespace clang {
 namespace clangd {
+class ParsedAST;
 
 enum class HighlightingKind {
   Variable = 0,

Modified: clang-tools-extra/trunk/clangd/TUScheduler.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/TUScheduler.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/TUScheduler.cpp (original)
+++ clang-tools-extra/trunk/clangd/TUScheduler.cpp Wed Sep  4 02:46:06 2019
@@ -43,11 +43,11 @@
 
 #include "TUScheduler.h"
 #include "Cancellation.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
 #include "Diagnostics.h"
 #include "GlobalCompilationDatabase.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Preamble.h"
 #include "Trace.h"
 #include "index/CanonicalIncludes.h"

Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Wed Sep  4 02:46:06 2019
@@ -11,6 +11,7 @@
 #include "FindSymbols.h"
 #include "FormattedString.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Protocol.h"
 #include "SourceCode.h"
 #include "URI.h"

Modified: clang-tools-extra/trunk/clangd/XRefs.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.h?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.h (original)
+++ clang-tools-extra/trunk/clangd/XRefs.h Wed Sep  4 02:46:06 2019
@@ -13,11 +13,13 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_XREFS_H
 
-#include "ClangdUnit.h"
 #include "FormattedString.h"
+#include "Path.h"
 #include "Protocol.h"
 #include "index/Index.h"
+#include "clang/AST/Type.h"
 #include "index/SymbolLocation.h"
+#include "clang/Format/Format.h"
 #include "clang/Index/IndexSymbol.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/raw_ostream.h"
@@ -25,6 +27,7 @@
 
 namespace clang {
 namespace clangd {
+class ParsedAST;
 
 // Describes where a symbol is declared and defined (as far as clangd knows).
 // There are three cases:

Modified: clang-tools-extra/trunk/clangd/index/Background.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/Background.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/Background.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/Background.cpp Wed Sep  4 02:46:06 2019
@@ -7,12 +7,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "index/Background.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
 #include "Context.h"
 #include "FSProvider.h"
 #include "Headers.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Path.h"
 #include "SourceCode.h"
 #include "Symbol.h"

Modified: clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/BackgroundRebuild.cpp Wed Sep  4 02:46:06 2019
@@ -7,10 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "index/BackgroundRebuild.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
 #include "Headers.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Path.h"
 #include "SourceCode.h"
 #include "Symbol.h"

Modified: clang-tools-extra/trunk/clangd/index/FileIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/index/FileIndex.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/index/FileIndex.cpp (original)
+++ clang-tools-extra/trunk/clangd/index/FileIndex.cpp Wed Sep  4 02:46:06 2019
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "FileIndex.h"
-#include "ClangdUnit.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "SymbolCollector.h"
 #include "index/CanonicalIncludes.h"
 #include "index/Index.h"

Modified: clang-tools-extra/trunk/clangd/refactor/Rename.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/Rename.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/Rename.cpp (original)
+++ clang-tools-extra/trunk/clangd/refactor/Rename.cpp Wed Sep  4 02:46:06 2019
@@ -8,8 +8,8 @@
 
 #include "refactor/Rename.h"
 #include "AST.h"
-#include "ClangdUnit.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "SourceCode.h"
 #include "index/SymbolCollector.h"
 #include "clang/Tooling/Refactoring/Rename/RenamingAction.h"

Modified: clang-tools-extra/trunk/clangd/refactor/Tweak.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/Tweak.h?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/Tweak.h (original)
+++ clang-tools-extra/trunk/clangd/refactor/Tweak.h Wed Sep  4 02:46:06 2019
@@ -19,7 +19,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_ACTIONS_TWEAK_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_ACTIONS_TWEAK_H
 
-#include "ClangdUnit.h"
+#include "ParsedAST.h"
 #include "Protocol.h"
 #include "Selection.h"
 #include "clang/Tooling/Core/Replacement.h"

Modified: clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractFunction.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractFunction.cpp (original)
+++ clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractFunction.cpp Wed Sep  4 02:46:06 2019
@@ -47,8 +47,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "AST.h"
-#include "ClangdUnit.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Selection.h"
 #include "SourceCode.h"
 #include "refactor/Tweak.h"

Modified: clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp (original)
+++ clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp Wed Sep  4 02:46:06 2019
@@ -5,8 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#include "ClangdUnit.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "Protocol.h"
 #include "Selection.h"
 #include "SourceCode.h"

Modified: clang-tools-extra/trunk/clangd/refactor/tweaks/RawStringLiteral.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/tweaks/RawStringLiteral.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/tweaks/RawStringLiteral.cpp (original)
+++ clang-tools-extra/trunk/clangd/refactor/tweaks/RawStringLiteral.cpp Wed Sep  4 02:46:06 2019
@@ -5,8 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#include "ClangdUnit.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTContext.h"

Modified: clang-tools-extra/trunk/clangd/refactor/tweaks/SwapIfBranches.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/refactor/tweaks/SwapIfBranches.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/refactor/tweaks/SwapIfBranches.cpp (original)
+++ clang-tools-extra/trunk/clangd/refactor/tweaks/SwapIfBranches.cpp Wed Sep  4 02:46:06 2019
@@ -5,8 +5,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-#include "ClangdUnit.h"
 #include "Logger.h"
+#include "ParsedAST.h"
 #include "SourceCode.h"
 #include "refactor/Tweak.h"
 #include "clang/AST/ASTContext.h"

Modified: clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clangd/unittests/CMakeLists.txt Wed Sep  4 02:46:06 2019
@@ -28,7 +28,6 @@ add_unittest(ClangdUnitTests ClangdTests
   CancellationTests.cpp
   CanonicalIncludesTests.cpp
   ClangdTests.cpp
-  ClangdUnitTests.cpp
   CodeCompleteTests.cpp
   CodeCompletionStringsTests.cpp
   ContextTests.cpp
@@ -50,6 +49,7 @@ add_unittest(ClangdUnitTests ClangdTests
   IndexActionTests.cpp
   IndexTests.cpp
   JSONTransportTests.cpp
+  ParsedASTTests.cpp
   PrintASTTests.cpp
   QualityTests.cpp
   RenameTests.cpp

Removed: clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp?rev=370861&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/ClangdUnitTests.cpp (removed)
@@ -1,278 +0,0 @@
-//===-- ClangdUnitTests.cpp - ClangdUnit tests ------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "AST.h"
-#include "Annotations.h"
-#include "ClangdUnit.h"
-#include "Compiler.h"
-#include "Diagnostics.h"
-#include "SourceCode.h"
-#include "TestFS.h"
-#include "TestTU.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/Basic/TokenKinds.h"
-#include "clang/Tooling/Syntax/Tokens.h"
-#include "llvm/Support/ScopedPrinter.h"
-#include "gmock/gmock-matchers.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace clang {
-namespace clangd {
-namespace {
-
-using ::testing::ElementsAre;
-using ::testing::ElementsAreArray;
-using ::testing::AllOf;
-
-MATCHER_P(DeclNamed, Name, "") {
-  if (NamedDecl *ND = dyn_cast<NamedDecl>(arg))
-    if (ND->getName() == Name)
-      return true;
-  if (auto *Stream = result_listener->stream()) {
-    llvm::raw_os_ostream OS(*Stream);
-    arg->dump(OS);
-  }
-  return false;
-}
-
-// Matches if the Decl has template args equal to ArgName. If the decl is a
-// NamedDecl and ArgName is an empty string it also matches.
-MATCHER_P(WithTemplateArgs, ArgName, "") {
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(arg)) {
-    if (const auto *Args = FD->getTemplateSpecializationArgs()) {
-      std::string SpecializationArgs;
-      // Without the PrintingPolicy "bool" will be printed as "_Bool".
-      LangOptions LO;
-      PrintingPolicy Policy(LO);
-      Policy.adjustForCPlusPlus();
-      for (const auto Arg : Args->asArray()) {
-        if (SpecializationArgs.size() > 0)
-          SpecializationArgs += ",";
-        SpecializationArgs += Arg.getAsType().getAsString(Policy);
-      }
-      if (Args->size() == 0)
-        return ArgName == SpecializationArgs;
-      return ArgName == "<" + SpecializationArgs + ">";
-    }
-  }
-  if (const NamedDecl *ND = dyn_cast<NamedDecl>(arg))
-    return printTemplateSpecializationArgs(*ND) == ArgName;
-  return false;
-}
-
-TEST(ClangdUnitTest, TopLevelDecls) {
-  TestTU TU;
-  TU.HeaderCode = R"(
-    int header1();
-    int header2;
-  )";
-  TU.Code = "int main();";
-  auto AST = TU.build();
-  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
-}
-
-TEST(ClangdUnitTest, DoesNotGetIncludedTopDecls) {
-  TestTU TU;
-  TU.HeaderCode = R"cpp(
-    #define LL void foo(){}
-    template<class T>
-    struct H {
-      H() {}
-      LL
-    };
-  )cpp";
-  TU.Code = R"cpp(
-    int main() {
-      H<int> h;
-      h.foo();
-    }
-  )cpp";
-  auto AST = TU.build();
-  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
-}
-
-TEST(ClangdUnitTest, DoesNotGetImplicitTemplateTopDecls) {
-  TestTU TU;
-  TU.Code = R"cpp(
-    template<typename T>
-    void f(T) {}
-    void s() {
-      f(10UL);
-    }
-  )cpp";
-
-  auto AST = TU.build();
-  EXPECT_THAT(AST.getLocalTopLevelDecls(),
-              ElementsAre(DeclNamed("f"), DeclNamed("s")));
-}
-
-TEST(ClangdUnitTest,
-     GetsExplicitInstantiationAndSpecializationTemplateTopDecls) {
-  TestTU TU;
-  TU.Code = R"cpp(
-    template <typename T>
-    void f(T) {}
-    template<>
-    void f(bool);
-    template void f(double);
-
-    template <class T>
-    struct V {};
-    template<class T>
-    struct V<T*> {};
-    template <>
-    struct V<bool> {};
-
-    template<class T>
-    T foo = T(10);
-    int i = foo<int>;
-    double d = foo<double>;
-
-    template <class T>
-    int foo<T*> = 0;
-    template <>
-    int foo<bool> = 0;
-  )cpp";
-
-  auto AST = TU.build();
-  EXPECT_THAT(
-      AST.getLocalTopLevelDecls(),
-      ElementsAreArray({AllOf(DeclNamed("f"), WithTemplateArgs("")),
-                        AllOf(DeclNamed("f"), WithTemplateArgs("<bool>")),
-                        AllOf(DeclNamed("f"), WithTemplateArgs("<double>")),
-                        AllOf(DeclNamed("V"), WithTemplateArgs("")),
-                        AllOf(DeclNamed("V"), WithTemplateArgs("<T *>")),
-                        AllOf(DeclNamed("V"), WithTemplateArgs("<bool>")),
-                        AllOf(DeclNamed("foo"), WithTemplateArgs("")),
-                        AllOf(DeclNamed("i"), WithTemplateArgs("")),
-                        AllOf(DeclNamed("d"), WithTemplateArgs("")),
-                        AllOf(DeclNamed("foo"), WithTemplateArgs("<T *>")),
-                        AllOf(DeclNamed("foo"), WithTemplateArgs("<bool>"))}));
-}
-
-TEST(ClangdUnitTest, TokensAfterPreamble) {
-  TestTU TU;
-  TU.AdditionalFiles["foo.h"] = R"(
-    int foo();
-  )";
-  TU.Code = R"cpp(
-      #include "foo.h"
-      first_token;
-      void test() {
-      }
-      last_token
-)cpp";
-  auto AST = TU.build();
-  const syntax::TokenBuffer &T = AST.getTokens();
-  const auto &SM = AST.getSourceManager();
-
-  ASSERT_GT(T.expandedTokens().size(), 2u);
-  // Check first token after the preamble.
-  EXPECT_EQ(T.expandedTokens().front().text(SM), "first_token");
-  // Last token is always 'eof'.
-  EXPECT_EQ(T.expandedTokens().back().kind(), tok::eof);
-  // Check the token before 'eof'.
-  EXPECT_EQ(T.expandedTokens().drop_back().back().text(SM), "last_token");
-
-  // The spelled tokens for the main file should have everything.
-  auto Spelled = T.spelledTokens(SM.getMainFileID());
-  ASSERT_FALSE(Spelled.empty());
-  EXPECT_EQ(Spelled.front().kind(), tok::hash);
-  EXPECT_EQ(Spelled.back().text(SM), "last_token");
-}
-
-
-TEST(ClangdUnitTest, NoCrashOnTokensWithTidyCheck) {
-  TestTU TU;
-  // this check runs the preprocessor, we need to make sure it does not break
-  // our recording logic.
-  TU.ClangTidyChecks = "modernize-use-trailing-return-type";
-  TU.Code = "inline int foo() {}";
-
-  auto AST = TU.build();
-  const syntax::TokenBuffer &T = AST.getTokens();
-  const auto &SM = AST.getSourceManager();
-
-  ASSERT_GT(T.expandedTokens().size(), 7u);
-  // Check first token after the preamble.
-  EXPECT_EQ(T.expandedTokens().front().text(SM), "inline");
-  // Last token is always 'eof'.
-  EXPECT_EQ(T.expandedTokens().back().kind(), tok::eof);
-  // Check the token before 'eof'.
-  EXPECT_EQ(T.expandedTokens().drop_back().back().text(SM), "}");
-}
-
-TEST(ClangdUnitTest, CanBuildInvocationWithUnknownArgs) {
-  // Unknown flags should not prevent a build of compiler invocation.
-  ParseInputs Inputs;
-  Inputs.FS = buildTestFS({{testPath("foo.cpp"), "void test() {}"}});
-  Inputs.CompileCommand.CommandLine = {"clang", "-fsome-unknown-flag",
-                                       testPath("foo.cpp")};
-  IgnoreDiagnostics IgnoreDiags;
-  EXPECT_NE(buildCompilerInvocation(Inputs, IgnoreDiags), nullptr);
-
-  // Unknown forwarded to -cc1 should not a failure either.
-  Inputs.CompileCommand.CommandLine = {
-      "clang", "-Xclang", "-fsome-unknown-flag", testPath("foo.cpp")};
-  EXPECT_NE(buildCompilerInvocation(Inputs, IgnoreDiags), nullptr);
-}
-
-TEST(ClangdUnitTest, CollectsMainFileMacroExpansions) {
-  Annotations TestCase(R"cpp(
-    #define MACRO_ARGS(X, Y) X Y
-    ^ID(int A);
-    // Macro arguments included.
-    ^MACRO_ARGS(^MACRO_ARGS(^MACRO_EXP(int), A), ^ID(= 2));
-
-    // Macro names inside other macros not included.
-    #define FOO BAR
-    #define BAR 1
-    int A = ^FOO;
-
-    // Macros from token concatenations not included.
-    #define CONCAT(X) X##A()
-    #define PREPEND(X) MACRO##X()
-    #define MACROA() 123
-    int B = ^CONCAT(MACRO);
-    int D = ^PREPEND(A)
-
-    // Macros included not from preamble not included.
-    #include "foo.inc"
-
-    #define assert(COND) if (!(COND)) { printf("%s", #COND); exit(0); }
-
-    void test() {
-      // Includes macro expansions in arguments that are expressions
-      ^assert(0 <= ^BAR);
-    }
-  )cpp");
-  auto TU = TestTU::withCode(TestCase.code());
-  TU.HeaderCode = R"cpp(
-    #define ID(X) X
-    #define MACRO_EXP(X) ID(X)
-    MACRO_EXP(int B);
-  )cpp";
-  TU.AdditionalFiles["foo.inc"] = R"cpp(
-    int C = ID(1);
-    #define DEF 1
-    int D = DEF;
-  )cpp";
-  ParsedAST AST = TU.build();
-  const std::vector<SourceLocation> &MacroExpansionLocations =
-      AST.getMainFileExpansions();
-  std::vector<Position> MacroExpansionPositions;
-  for (const auto &L : MacroExpansionLocations)
-    MacroExpansionPositions.push_back(
-        sourceLocToPosition(AST.getSourceManager(), L));
-  EXPECT_EQ(MacroExpansionPositions, TestCase.points());
-}
-
-} // namespace
-} // namespace clangd
-} // namespace clang

Modified: clang-tools-extra/trunk/clangd/unittests/DiagnosticsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/DiagnosticsTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/DiagnosticsTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/DiagnosticsTests.cpp Wed Sep  4 02:46:06 2019
@@ -7,8 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "Annotations.h"
-#include "ClangdUnit.h"
 #include "Diagnostics.h"
+#include "ParsedAST.h"
 #include "Path.h"
 #include "Protocol.h"
 #include "SourceCode.h"

Modified: clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/ExpectedTypeTest.cpp Wed Sep  4 02:46:06 2019
@@ -6,8 +6,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ClangdUnit.h"
 #include "ExpectedTypes.h"
+#include "ParsedAST.h"
 #include "TestTU.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"

Modified: clang-tools-extra/trunk/clangd/unittests/FileIndexTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/FileIndexTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/FileIndexTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/FileIndexTests.cpp Wed Sep  4 02:46:06 2019
@@ -8,8 +8,8 @@
 
 #include "AST.h"
 #include "Annotations.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
+#include "ParsedAST.h"
 #include "SyncAPI.h"
 #include "TestFS.h"
 #include "TestTU.h"

Added: clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp?rev=370862&view=auto
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp (added)
+++ clang-tools-extra/trunk/clangd/unittests/ParsedASTTests.cpp Wed Sep  4 02:46:06 2019
@@ -0,0 +1,282 @@
+//===-- ParsedASTTests.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// These tests cover clangd's logic to build a TU, which generally uses the APIs
+// in ParsedAST and Preamble, via the TestTU helper.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AST.h"
+#include "Annotations.h"
+#include "Compiler.h"
+#include "Diagnostics.h"
+#include "ParsedAST.h"
+#include "SourceCode.h"
+#include "TestFS.h"
+#include "TestTU.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/TokenKinds.h"
+#include "clang/Tooling/Syntax/Tokens.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "gmock/gmock-matchers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace clangd {
+namespace {
+
+using ::testing::AllOf;
+using ::testing::ElementsAre;
+using ::testing::ElementsAreArray;
+
+MATCHER_P(DeclNamed, Name, "") {
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(arg))
+    if (ND->getName() == Name)
+      return true;
+  if (auto *Stream = result_listener->stream()) {
+    llvm::raw_os_ostream OS(*Stream);
+    arg->dump(OS);
+  }
+  return false;
+}
+
+// Matches if the Decl has template args equal to ArgName. If the decl is a
+// NamedDecl and ArgName is an empty string it also matches.
+MATCHER_P(WithTemplateArgs, ArgName, "") {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(arg)) {
+    if (const auto *Args = FD->getTemplateSpecializationArgs()) {
+      std::string SpecializationArgs;
+      // Without the PrintingPolicy "bool" will be printed as "_Bool".
+      LangOptions LO;
+      PrintingPolicy Policy(LO);
+      Policy.adjustForCPlusPlus();
+      for (const auto Arg : Args->asArray()) {
+        if (SpecializationArgs.size() > 0)
+          SpecializationArgs += ",";
+        SpecializationArgs += Arg.getAsType().getAsString(Policy);
+      }
+      if (Args->size() == 0)
+        return ArgName == SpecializationArgs;
+      return ArgName == "<" + SpecializationArgs + ">";
+    }
+  }
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(arg))
+    return printTemplateSpecializationArgs(*ND) == ArgName;
+  return false;
+}
+
+TEST(ParsedASTTest, TopLevelDecls) {
+  TestTU TU;
+  TU.HeaderCode = R"(
+    int header1();
+    int header2;
+  )";
+  TU.Code = "int main();";
+  auto AST = TU.build();
+  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
+}
+
+TEST(ParsedASTTest, DoesNotGetIncludedTopDecls) {
+  TestTU TU;
+  TU.HeaderCode = R"cpp(
+    #define LL void foo(){}
+    template<class T>
+    struct H {
+      H() {}
+      LL
+    };
+  )cpp";
+  TU.Code = R"cpp(
+    int main() {
+      H<int> h;
+      h.foo();
+    }
+  )cpp";
+  auto AST = TU.build();
+  EXPECT_THAT(AST.getLocalTopLevelDecls(), ElementsAre(DeclNamed("main")));
+}
+
+TEST(ParsedASTTest, DoesNotGetImplicitTemplateTopDecls) {
+  TestTU TU;
+  TU.Code = R"cpp(
+    template<typename T>
+    void f(T) {}
+    void s() {
+      f(10UL);
+    }
+  )cpp";
+
+  auto AST = TU.build();
+  EXPECT_THAT(AST.getLocalTopLevelDecls(),
+              ElementsAre(DeclNamed("f"), DeclNamed("s")));
+}
+
+TEST(ParsedASTTest,
+     GetsExplicitInstantiationAndSpecializationTemplateTopDecls) {
+  TestTU TU;
+  TU.Code = R"cpp(
+    template <typename T>
+    void f(T) {}
+    template<>
+    void f(bool);
+    template void f(double);
+
+    template <class T>
+    struct V {};
+    template<class T>
+    struct V<T*> {};
+    template <>
+    struct V<bool> {};
+
+    template<class T>
+    T foo = T(10);
+    int i = foo<int>;
+    double d = foo<double>;
+
+    template <class T>
+    int foo<T*> = 0;
+    template <>
+    int foo<bool> = 0;
+  )cpp";
+
+  auto AST = TU.build();
+  EXPECT_THAT(
+      AST.getLocalTopLevelDecls(),
+      ElementsAreArray({AllOf(DeclNamed("f"), WithTemplateArgs("")),
+                        AllOf(DeclNamed("f"), WithTemplateArgs("<bool>")),
+                        AllOf(DeclNamed("f"), WithTemplateArgs("<double>")),
+                        AllOf(DeclNamed("V"), WithTemplateArgs("")),
+                        AllOf(DeclNamed("V"), WithTemplateArgs("<T *>")),
+                        AllOf(DeclNamed("V"), WithTemplateArgs("<bool>")),
+                        AllOf(DeclNamed("foo"), WithTemplateArgs("")),
+                        AllOf(DeclNamed("i"), WithTemplateArgs("")),
+                        AllOf(DeclNamed("d"), WithTemplateArgs("")),
+                        AllOf(DeclNamed("foo"), WithTemplateArgs("<T *>")),
+                        AllOf(DeclNamed("foo"), WithTemplateArgs("<bool>"))}));
+}
+
+TEST(ParsedASTTest, TokensAfterPreamble) {
+  TestTU TU;
+  TU.AdditionalFiles["foo.h"] = R"(
+    int foo();
+  )";
+  TU.Code = R"cpp(
+      #include "foo.h"
+      first_token;
+      void test() {
+      }
+      last_token
+)cpp";
+  auto AST = TU.build();
+  const syntax::TokenBuffer &T = AST.getTokens();
+  const auto &SM = AST.getSourceManager();
+
+  ASSERT_GT(T.expandedTokens().size(), 2u);
+  // Check first token after the preamble.
+  EXPECT_EQ(T.expandedTokens().front().text(SM), "first_token");
+  // Last token is always 'eof'.
+  EXPECT_EQ(T.expandedTokens().back().kind(), tok::eof);
+  // Check the token before 'eof'.
+  EXPECT_EQ(T.expandedTokens().drop_back().back().text(SM), "last_token");
+
+  // The spelled tokens for the main file should have everything.
+  auto Spelled = T.spelledTokens(SM.getMainFileID());
+  ASSERT_FALSE(Spelled.empty());
+  EXPECT_EQ(Spelled.front().kind(), tok::hash);
+  EXPECT_EQ(Spelled.back().text(SM), "last_token");
+}
+
+TEST(ParsedASTTest, NoCrashOnTokensWithTidyCheck) {
+  TestTU TU;
+  // this check runs the preprocessor, we need to make sure it does not break
+  // our recording logic.
+  TU.ClangTidyChecks = "modernize-use-trailing-return-type";
+  TU.Code = "inline int foo() {}";
+
+  auto AST = TU.build();
+  const syntax::TokenBuffer &T = AST.getTokens();
+  const auto &SM = AST.getSourceManager();
+
+  ASSERT_GT(T.expandedTokens().size(), 7u);
+  // Check first token after the preamble.
+  EXPECT_EQ(T.expandedTokens().front().text(SM), "inline");
+  // Last token is always 'eof'.
+  EXPECT_EQ(T.expandedTokens().back().kind(), tok::eof);
+  // Check the token before 'eof'.
+  EXPECT_EQ(T.expandedTokens().drop_back().back().text(SM), "}");
+}
+
+TEST(ParsedASTTest, CanBuildInvocationWithUnknownArgs) {
+  // Unknown flags should not prevent a build of compiler invocation.
+  ParseInputs Inputs;
+  Inputs.FS = buildTestFS({{testPath("foo.cpp"), "void test() {}"}});
+  Inputs.CompileCommand.CommandLine = {"clang", "-fsome-unknown-flag",
+                                       testPath("foo.cpp")};
+  IgnoreDiagnostics IgnoreDiags;
+  EXPECT_NE(buildCompilerInvocation(Inputs, IgnoreDiags), nullptr);
+
+  // Unknown forwarded to -cc1 should not a failure either.
+  Inputs.CompileCommand.CommandLine = {
+      "clang", "-Xclang", "-fsome-unknown-flag", testPath("foo.cpp")};
+  EXPECT_NE(buildCompilerInvocation(Inputs, IgnoreDiags), nullptr);
+}
+
+TEST(ParsedASTTest, CollectsMainFileMacroExpansions) {
+  Annotations TestCase(R"cpp(
+    #define MACRO_ARGS(X, Y) X Y
+    ^ID(int A);
+    // Macro arguments included.
+    ^MACRO_ARGS(^MACRO_ARGS(^MACRO_EXP(int), A), ^ID(= 2));
+
+    // Macro names inside other macros not included.
+    #define FOO BAR
+    #define BAR 1
+    int A = ^FOO;
+
+    // Macros from token concatenations not included.
+    #define CONCAT(X) X##A()
+    #define PREPEND(X) MACRO##X()
+    #define MACROA() 123
+    int B = ^CONCAT(MACRO);
+    int D = ^PREPEND(A)
+
+    // Macros included not from preamble not included.
+    #include "foo.inc"
+
+    #define assert(COND) if (!(COND)) { printf("%s", #COND); exit(0); }
+
+    void test() {
+      // Includes macro expansions in arguments that are expressions
+      ^assert(0 <= ^BAR);
+    }
+  )cpp");
+  auto TU = TestTU::withCode(TestCase.code());
+  TU.HeaderCode = R"cpp(
+    #define ID(X) X
+    #define MACRO_EXP(X) ID(X)
+    MACRO_EXP(int B);
+  )cpp";
+  TU.AdditionalFiles["foo.inc"] = R"cpp(
+    int C = ID(1);
+    #define DEF 1
+    int D = DEF;
+  )cpp";
+  ParsedAST AST = TU.build();
+  const std::vector<SourceLocation> &MacroExpansionLocations =
+      AST.getMainFileExpansions();
+  std::vector<Position> MacroExpansionPositions;
+  for (const auto &L : MacroExpansionLocations)
+    MacroExpansionPositions.push_back(
+        sourceLocToPosition(AST.getSourceManager(), L));
+  EXPECT_EQ(MacroExpansionPositions, TestCase.points());
+}
+
+} // namespace
+} // namespace clangd
+} // namespace clang

Modified: clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/SourceCodeTests.cpp Wed Sep  4 02:46:06 2019
@@ -312,7 +312,7 @@ TEST(SourceCodeTests, SourceLocationInMa
   }
 }
 
-TEST(ClangdUnitTest, GetBeginningOfIdentifier) {
+TEST(SourceCodeTests, GetBeginningOfIdentifier) {
   std::string Preamble = R"cpp(
 struct Bar { int func(); };
 #define MACRO(X) void f() { X; }

Modified: clang-tools-extra/trunk/clangd/unittests/SymbolInfoTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/SymbolInfoTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/SymbolInfoTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/SymbolInfoTests.cpp Wed Sep  4 02:46:06 2019
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 #include "Annotations.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
 #include "Matchers.h"
+#include "ParsedAST.h"
 #include "SyncAPI.h"
 #include "TestFS.h"
 #include "TestTU.h"

Modified: clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/TUSchedulerTests.cpp Wed Sep  4 02:46:06 2019
@@ -7,10 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "Annotations.h"
-#include "ClangdUnit.h"
 #include "Context.h"
 #include "Diagnostics.h"
 #include "Matchers.h"
+#include "ParsedAST.h"
 #include "Path.h"
 #include "Preamble.h"
 #include "TUScheduler.h"

Modified: clang-tools-extra/trunk/clangd/unittests/TestTU.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/TestTU.h?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/TestTU.h (original)
+++ clang-tools-extra/trunk/clangd/unittests/TestTU.h Wed Sep  4 02:46:06 2019
@@ -17,7 +17,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H
 #define LLVM_CLANG_TOOLS_EXTRA_UNITTESTS_CLANGD_TESTTU_H
 
-#include "ClangdUnit.h"
+#include "ParsedAST.h"
 #include "Path.h"
 #include "index/Index.h"
 #include "llvm/ADT/StringMap.h"

Modified: clang-tools-extra/trunk/clangd/unittests/TypeHierarchyTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/TypeHierarchyTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/TypeHierarchyTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/TypeHierarchyTests.cpp Wed Sep  4 02:46:06 2019
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 #include "Annotations.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
 #include "Matchers.h"
+#include "ParsedAST.h"
 #include "SyncAPI.h"
 #include "TestFS.h"
 #include "TestTU.h"

Modified: clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp?rev=370862&r1=370861&r2=370862&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp Wed Sep  4 02:46:06 2019
@@ -6,9 +6,9 @@
 //
 //===----------------------------------------------------------------------===//
 #include "Annotations.h"
-#include "ClangdUnit.h"
 #include "Compiler.h"
 #include "Matchers.h"
+#include "ParsedAST.h"
 #include "Protocol.h"
 #include "SyncAPI.h"
 #include "TestFS.h"




More information about the cfe-commits mailing list