[clang] 9671712 - Revert "[analyzer] On-demand parsing capability for CTU"

Dmitri Gribenko via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 05:45:48 PDT 2020


Author: Dmitri Gribenko
Date: 2020-04-27T14:27:04+02:00
New Revision: 96717125e852d1c6ddf41c22dd2d556f4f5aa34d

URL: https://github.com/llvm/llvm-project/commit/96717125e852d1c6ddf41c22dd2d556f4f5aa34d
DIFF: https://github.com/llvm/llvm-project/commit/96717125e852d1c6ddf41c22dd2d556f4f5aa34d.diff

LOG: Revert "[analyzer] On-demand parsing capability for CTU"

This reverts commit 811c0c9eb462d1fef6ab6908aab7881e5c4f5fbf. It broke
multiple buildbots.

Added: 
    clang/test/Analysis/Inputs/ctu-other.c.externalDefMap.txt
    clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt

Modified: 
    clang/docs/analyzer/user-docs/CrossTranslationUnit.rst
    clang/include/clang/CrossTU/CrossTranslationUnit.h
    clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
    clang/lib/CrossTU/CMakeLists.txt
    clang/lib/CrossTU/CrossTranslationUnit.cpp
    clang/lib/Frontend/CompilerInvocation.cpp
    clang/test/Analysis/Inputs/ctu-other.c
    clang/test/Analysis/analyzer-config.c
    clang/test/Analysis/ctu-different-triples.cpp
    clang/test/Analysis/ctu-main.c
    clang/test/Analysis/ctu-main.cpp
    clang/test/Analysis/ctu-unknown-parts-in-triples.cpp
    clang/unittests/CrossTU/CrossTranslationUnitTest.cpp

Removed: 
    clang/test/Analysis/Inputs/ctu-other.c.externalDefMap.ast-dump.txt
    clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
    clang/test/Analysis/ctu-on-demand-parsing-ambigous-compilation-database.c
    clang/test/Analysis/ctu-on-demand-parsing.c
    clang/test/Analysis/ctu-on-demand-parsing.cpp


################################################################################
diff  --git a/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst b/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst
index 1a7ac1c71f21..86f972b63e31 100644
--- a/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst
+++ b/clang/docs/analyzer/user-docs/CrossTranslationUnit.rst
@@ -3,33 +3,14 @@ Cross Translation Unit (CTU) Analysis
 =====================================
 
 Normally, static analysis works in the boundary of one translation unit (TU).
-However, with additional steps and configuration we can enable the analysis to inline the definition of a function from
-another TU.
+However, with additional steps and configuration we can enable the analysis to inline the definition of a function from another TU.
 
 .. contents::
    :local:
 
-Overview
-________
-CTU analysis can be used in a variety of ways. The importing of external TU definitions can work with pre-dumped PCH
-files or generating the necessary AST structure on-demand, during the analysis of the main TU. Driving the static
-analysis can also be implemented in multiple ways. The most direct way is to specify the necessary commandline options
-of the Clang frontend manually (and generate the prerequisite dependencies of the specific import method by hand). This
-process can be automated by other tools, like `CodeChecker <https://github.com/Ericsson/codechecker>`_ and scan-build-py
-(preference for the former).
-
-PCH-based analysis
-__________________
-The analysis needs the PCH dumps of all the translations units used in the project.
-These can be generated by the Clang Frontend itself, and must be arranged in a specific way in the filesystem.
-The index, which maps symbols' USR names to PCH dumps containing them must also be generated by the
-`clang-extdef-mapping`. This tool uses a :doc:`compilation database <../../JSONCompilationDatabase>` to
-determine the compilation flags used.
-The analysis invocation must be provided with the directory which contains the dumps and the mapping files.
-
-
 Manual CTU Analysis
-###################
+-------------------
+
 Let's consider these source files in our minimal example:
 
 .. code-block:: cpp
@@ -66,8 +47,7 @@ And a compilation database:
   ]
 
 We'd like to analyze `main.cpp` and discover the division by zero bug.
-In order to be able to inline the definition of `foo` from `foo.cpp` first we have to generate the `AST` (or `PCH`) file
-of `foo.cpp`:
+In order to be able to inline the definition of `foo` from `foo.cpp` first we have to generate the `AST` (or `PCH`) file of `foo.cpp`:
 
 .. code-block:: bash
 
@@ -78,8 +58,7 @@ of `foo.cpp`:
   compile_commands.json  foo.cpp.ast  foo.cpp  main.cpp
   $
 
-The next step is to create a CTU index file which holds the `USR` name and location of external definitions in the
-source files:
+The next step is to create a CTU index file which holds the `USR` name and location of external definitions in the source files:
 
 .. code-block:: bash
 
@@ -106,34 +85,47 @@ We have to feed Clang with CTU specific extra arguments:
 
   $ pwd
   /path/to/your/project
-  $ clang++ --analyze \
-      -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true \
-      -Xclang -analyzer-config -Xclang ctu-dir=. \
-      -Xclang -analyzer-config -Xclang ctu-on-demand-parsing=false \
-      -Xclang -analyzer-output=plist-multi-file \
-      main.cpp
+  $ clang++ --analyze -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true -Xclang -analyzer-config -Xclang ctu-dir=. -Xclang -analyzer-output=plist-multi-file main.cpp
   main.cpp:5:12: warning: Division by zero
     return 3 / foo();
            ~~^~~~~~~
   1 warning generated.
   $ # The plist file with the result is generated.
-  $ ls -F
+  $ ls
   compile_commands.json  externalDefMap.txt  foo.ast  foo.cpp  foo.cpp.ast  main.cpp  main.plist
   $
 
-This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use
-`CodeChecker` or `scan-build-py`.
+This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use `CodeChecker` or `scan-build-py`.
 
 Automated CTU Analysis with CodeChecker
-#######################################
+---------------------------------------
 The `CodeChecker <https://github.com/Ericsson/codechecker>`_ project fully supports automated CTU analysis with Clang.
 Once we have set up the `PATH` environment variable and we activated the python `venv` then it is all it takes:
 
 .. code-block:: bash
 
   $ CodeChecker analyze --ctu compile_commands.json -o reports
-  $ ls -F
-  compile_commands.json  foo.cpp  foo.cpp.ast  main.cpp  reports/
+  [INFO 2019-07-16 17:21] - Pre-analysis started.
+  [INFO 2019-07-16 17:21] - Collecting data for ctu analysis.
+  [INFO 2019-07-16 17:21] - [1/2] foo.cpp
+  [INFO 2019-07-16 17:21] - [2/2] main.cpp
+  [INFO 2019-07-16 17:21] - Pre-analysis finished.
+  [INFO 2019-07-16 17:21] - Starting static analysis ...
+  [INFO 2019-07-16 17:21] - [1/2] clangsa analyzed foo.cpp successfully.
+  [INFO 2019-07-16 17:21] - [2/2] clangsa analyzed main.cpp successfully.
+  [INFO 2019-07-16 17:21] - ----==== Summary ====----
+  [INFO 2019-07-16 17:21] - Successfully analyzed
+  [INFO 2019-07-16 17:21] -   clangsa: 2
+  [INFO 2019-07-16 17:21] - Total analyzed compilation commands: 2
+  [INFO 2019-07-16 17:21] - ----=================----
+  [INFO 2019-07-16 17:21] - Analysis finished.
+  [INFO 2019-07-16 17:21] - To view results in the terminal use the "CodeChecker parse" command.
+  [INFO 2019-07-16 17:21] - To store results use the "CodeChecker store" command.
+  [INFO 2019-07-16 17:21] - See --help and the user guide for further options about parsing and storing the reports.
+  [INFO 2019-07-16 17:21] - ----=================----
+  [INFO 2019-07-16 17:21] - Analysis length: 0.659618854523 sec.
+  $ ls
+  compile_commands.json  foo.cpp  foo.cpp.ast  main.cpp  reports
   $ tree reports
   reports
   ├── compile_cmd.json
@@ -182,9 +174,9 @@ Or we can use `CodeChecker parse -e html` to export the results into HTML format
   $ firefox html_out/index.html
 
 Automated CTU Analysis with scan-build-py (don't do it)
-#############################################################
-We actively develop CTU with CodeChecker as the driver for this feature, `scan-build-py` is not actively developed for CTU.
-`scan-build-py` has various errors and issues, expect it to work only with the very basic projects only.
+-------------------------------------------------------
+We actively develop CTU with CodeChecker as a "runner" script, `scan-build-py` is not actively developed for CTU.
+`scan-build-py` has various errors and issues, expect it to work with the very basic projects only.
 
 Example usage of scan-build-py:
 
@@ -199,154 +191,3 @@ Example usage of scan-build-py:
   Opening in existing browser session.
   ^C
   $
-
-On-demand analysis
-__________________
-The analysis produces the necessary AST structure of external TUs during analysis. This requires the
-compilation database in order to determine the exact compiler invocation used for each TU.
-The index, which maps function USR names to source files containing them must also be generated by the
-`clang-extdef-mapping`. The mapping of external definitions implicitly uses a
-:doc:`compilation database <../../JSONCompilationDatabase>` to determine the compilation flags used.
-Preferably the same compilation database should be used when generating the external definitions, and
-during analysis.  The analysis invocation must be provided with the directory which contains the mapping
-files, and the compilation database which is used to determine compiler flags.
-
-
-Manual CTU Analysis
-###################
-
-Let's consider these source files in our minimal example:
-
-.. code-block:: cpp
-
-  // main.cpp
-  int foo();
-
-  int main() {
-    return 3 / foo();
-  }
-
-.. code-block:: cpp
-
-  // foo.cpp
-  int foo() {
-    return 0;
-  }
-
-And a compilation database:
-
-.. code-block:: bash
-
-  [
-    {
-      "directory": "/path/to/your/project",
-      "command": "clang++ -c foo.cpp -o foo.o",
-      "file": "foo.cpp"
-    },
-    {
-      "directory": "/path/to/your/project",
-      "command": "clang++ -c main.cpp -o main.o",
-      "file": "main.cpp"
-    }
-  ]
-
-We'd like to analyze `main.cpp` and discover the division by zero bug.
-As we are using On-demand mode, we only need to create a CTU index file which holds the `USR` name and location of
-external definitions in the source files:
-
-.. code-block:: bash
-
-  $ clang-extdef-mapping -p . foo.cpp
-  c:@F at foo# /path/to/your/project/foo.cpp
-  $ clang-extdef-mapping -p . foo.cpp > externalDefMap.txt
-
-Now everything is available for the CTU analysis.
-We have to feed Clang with CTU specific extra arguments:
-
-.. code-block:: bash
-
-  $ pwd
-  /path/to/your/project
-  $ clang++ --analyze \
-      -Xclang -analyzer-config -Xclang experimental-enable-naive-ctu-analysis=true \
-      -Xclang -analyzer-config -Xclang ctu-dir=. \
-      -Xclang -analyzer-config -Xclang ctu-on-demand-parsing=true \
-      -Xclang -analyzer-config -Xclang ctu-on-demand-parsing-database=compile_commands.json \
-      -Xclang -analyzer-output=plist-multi-file \
-      main.cpp
-  main.cpp:5:12: warning: Division by zero
-    return 3 / foo();
-           ~~^~~~~~~
-  1 warning generated.
-  $ # The plist file with the result is generated.
-  $ ls -F
-  compile_commands.json  externalDefMap.txt  foo.cpp  main.cpp  main.plist
-  $
-
-This manual procedure is error-prone and not scalable, therefore to analyze real projects it is recommended to use
-`CodeChecker` or `scan-build-py`.
-
-Automated CTU Analysis with CodeChecker
-#######################################
-The `CodeChecker <https://github.com/Ericsson/codechecker>`_ project fully supports automated CTU analysis with Clang.
-Once we have set up the `PATH` environment variable and we activated the python `venv` then it is all it takes:
-
-.. code-block:: bash
-
-  $ CodeChecker analyze --ctu --ctu-on-demand compile_commands.json -o reports
-  $ ls -F
-  compile_commands.json  foo.cpp main.cpp  reports/
-  $ tree reports
-  reports
-  ├── compile_cmd.json
-  ├── compiler_info.json
-  ├── foo.cpp_53f6fbf7ab7ec9931301524b551959e2.plist
-  ├── main.cpp_23db3d8df52ff0812e6e5a03071c8337.plist
-  ├── metadata.json
-  └── unique_compile_commands.json
-
-  0 directories, 6 files
-  $
-
-The `plist` files contain the results of the analysis, which may be viewed with the regular analysis tools.
-E.g. one may use `CodeChecker parse` to view the results in command line:
-
-.. code-block:: bash
-
-  $ CodeChecker parse reports
-  [HIGH] /home/egbomrt/ctu_mini_raw_project/main.cpp:5:12: Division by zero [core.DivideZero]
-    return 3 / foo();
-             ^
-
-  Found 1 defect(s) in main.cpp
-
-
-  ----==== Summary ====----
-  -----------------------
-  Filename | Report count
-  -----------------------
-  main.cpp |            1
-  -----------------------
-  -----------------------
-  Severity | Report count
-  -----------------------
-  HIGH     |            1
-  -----------------------
-  ----=================----
-  Total number of reports: 1
-  ----=================----
-
-Or we can use `CodeChecker parse -e html` to export the results into HTML format:
-
-.. code-block:: bash
-
-  $ CodeChecker parse -e html -o html_out reports
-  $ firefox html_out/index.html
-
-Automated CTU Analysis with scan-build-py (don't do it)
-#######################################################
-We actively develop CTU with CodeChecker as the driver for feature, `scan-build-py` is not actively developed for CTU.
-`scan-build-py` has various errors and issues, expect it to work only with the very basic projects only.
-
-Currently On-demand analysis is not supported with `scan-build-py`.
-

diff  --git a/clang/include/clang/CrossTU/CrossTranslationUnit.h b/clang/include/clang/CrossTU/CrossTranslationUnit.h
index af43959355e7..4d2b7109c62a 100644
--- a/clang/include/clang/CrossTU/CrossTranslationUnit.h
+++ b/clang/include/clang/CrossTU/CrossTranslationUnit.h
@@ -33,10 +33,6 @@ class VarDecl;
 class NamedDecl;
 class TranslationUnitDecl;
 
-namespace tooling {
-class JSONCompilationDatabase;
-}
-
 namespace cross_tu {
 
 enum class index_error_code {
@@ -46,14 +42,12 @@ enum class index_error_code {
   multiple_definitions,
   missing_definition,
   failed_import,
-  failed_to_load_compilation_database,
   failed_to_get_external_ast,
   failed_to_generate_usr,
   triple_mismatch,
   lang_mismatch,
   lang_dialect_mismatch,
-  load_threshold_reached,
-  ambiguous_compilation_database
+  load_threshold_reached
 };
 
 class IndexError : public llvm::ErrorInfo<IndexError> {
@@ -84,8 +78,7 @@ class IndexError : public llvm::ErrorInfo<IndexError> {
 };
 
 /// This function parses an index file that determines which
-/// translation unit contains which definition. The IndexPath is not prefixed
-/// with CTUDir, so an absolute path is expected for consistent results.
+///        translation unit contains which definition.
 ///
 /// The index file format is the following:
 /// each line consists of an USR and a filepath separated by a space.
@@ -93,7 +86,7 @@ class IndexError : public llvm::ErrorInfo<IndexError> {
 /// \return Returns a map where the USR is the key and the filepath is the value
 ///         or an error.
 llvm::Expected<llvm::StringMap<std::string>>
-parseCrossTUIndex(StringRef IndexPath);
+parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir);
 
 std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index);
 
@@ -216,47 +209,14 @@ class CrossTranslationUnitContext {
   /// imported the FileID.
   ImportedFileIDMap ImportedFileIDs;
 
-  using LoadResultTy = llvm::Expected<std::unique_ptr<ASTUnit>>;
-
-  class ASTLoader {
-  public:
-    /// Load the ASTUnit by an identifier. Subclasses should determine what this
-    /// would be. The function is used with a string read from the CTU index,
-    /// and the method used for loading determines the semantic meaning of
-    /// Identifier.
-    virtual LoadResultTy load(StringRef Identifier) = 0;
-    virtual ~ASTLoader() = default;
-  };
-
-  /// Implementation for loading ASTUnits from AST-dump files.
-  class ASTFileLoader : public ASTLoader {
-  public:
-    explicit ASTFileLoader(CompilerInstance &CI, StringRef CTUDir);
-
-    /// ASTFileLoader uses a the path of the dump file as Identifier.
-    LoadResultTy load(StringRef Identifier) override;
-
-  private:
-    CompilerInstance &CI;
-    StringRef CTUDir;
-  };
-
-  /// Implementation for loading ASTUnits by parsing them on-demand.
-  class ASTOnDemandLoader : public ASTLoader {
+  /// Functor for loading ASTUnits from AST-dump files.
+  class ASTFileLoader {
   public:
-    ASTOnDemandLoader(StringRef OnDemandParsingDatabase);
-
-    /// ASTOnDemandLoader uses the path of the source file to be parsed as
-    /// Identifier.
-    LoadResultTy load(StringRef Identifier) override;
-
-    llvm::Error lazyInitCompileCommands();
+    ASTFileLoader(const CompilerInstance &CI);
+    std::unique_ptr<ASTUnit> operator()(StringRef ASTFilePath);
 
   private:
-    StringRef OnDemandParsingDatabase;
-    /// In case of on-demand parsing, the compilation database is parsed and
-    /// stored.
-    std::unique_ptr<tooling::JSONCompilationDatabase> CompileCommands;
+    const CompilerInstance &CI;
   };
 
   /// Maintain number of AST loads and check for reaching the load limit.
@@ -282,7 +242,7 @@ class CrossTranslationUnitContext {
   /// are the concerns of ASTUnitStorage class.
   class ASTUnitStorage {
   public:
-    ASTUnitStorage(CompilerInstance &CI);
+    ASTUnitStorage(const CompilerInstance &CI);
     /// Loads an ASTUnit for a function.
     ///
     /// \param FunctionName USR name of the function.
@@ -327,16 +287,18 @@ class CrossTranslationUnitContext {
     using IndexMapTy = BaseMapTy<std::string>;
     IndexMapTy NameFileMap;
 
-    std::unique_ptr<ASTLoader> Loader;
+    ASTFileLoader FileAccessor;
 
-    /// Limit the number of loaded ASTs. It is used to limit the  memory usage
-    /// of the CrossTranslationUnitContext. The ASTUnitStorage has the
-    /// information whether the AST to load is actually loaded or returned from
-    /// cache. This information is needed to maintain the counter.
+    /// Limit the number of loaded ASTs. Used to limit the  memory usage of the
+    /// CrossTranslationUnitContext.
+    /// The ASTUnitStorage has the knowledge about if the AST to load is
+    /// actually loaded or returned from cache. This information is needed to
+    /// maintain the counter.
     ASTLoadGuard LoadGuard;
   };
 
   ASTUnitStorage ASTStorage;
+
 };
 
 } // namespace cross_tu

diff  --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
index 82d9a7d44d1d..597a65c21318 100644
--- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -381,21 +381,6 @@ ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name",
                 "the name of the file containing the CTU index of definitions.",
                 "externalDefMap.txt")
 
-ANALYZER_OPTION(bool, CTUOnDemandParsing, "ctu-on-demand-parsing",
-                "Whether to parse function definitions from external TUs in "
-                "an on-demand manner during analysis. When using on-demand "
-                "parsing there is no need for pre-dumping ASTs. External "
-                "definition mapping is still needed, and a valid compilation "
-                "database with compile commands for the external TUs is also "
-                "necessary. Disabled by default.",
-                false)
-
-ANALYZER_OPTION(StringRef, CTUOnDemandParsingDatabase,
-                "ctu-on-demand-parsing-database",
-                "The path to the compilation database used for on-demand "
-                "parsing of ASTs during CTU analysis.",
-                "compile_commands.json")
-
 ANALYZER_OPTION(
     StringRef, ModelPath, "model-path",
     "The analyzer can inline an alternative implementation written in C at the "

diff  --git a/clang/lib/CrossTU/CMakeLists.txt b/clang/lib/CrossTU/CMakeLists.txt
index 74d4ddc275d5..632b5072ad6a 100644
--- a/clang/lib/CrossTU/CMakeLists.txt
+++ b/clang/lib/CrossTU/CMakeLists.txt
@@ -10,6 +10,4 @@ add_clang_library(clangCrossTU
   clangBasic
   clangFrontend
   clangIndex
-  clangTooling
-  clangSerialization
   )

diff  --git a/clang/lib/CrossTU/CrossTranslationUnit.cpp b/clang/lib/CrossTU/CrossTranslationUnit.cpp
index e265eed0a5f5..689c988d0b36 100644
--- a/clang/lib/CrossTU/CrossTranslationUnit.cpp
+++ b/clang/lib/CrossTU/CrossTranslationUnit.cpp
@@ -18,16 +18,12 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Index/USRGeneration.h"
-#include "clang/Tooling/JSONCompilationDatabase.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
-#include <algorithm>
 #include <fstream>
 #include <sstream>
 
@@ -104,8 +100,6 @@ class IndexErrorCategory : public std::error_category {
       return "Failed to import the definition.";
     case index_error_code::failed_to_get_external_ast:
       return "Failed to load external AST source.";
-    case index_error_code::failed_to_load_compilation_database:
-      return "Failed to load compilation database.";
     case index_error_code::failed_to_generate_usr:
       return "Failed to generate USR.";
     case index_error_code::triple_mismatch:
@@ -116,9 +110,6 @@ class IndexErrorCategory : public std::error_category {
       return "Language dialect mismatch";
     case index_error_code::load_threshold_reached:
       return "Load threshold reached";
-    case index_error_code::ambiguous_compilation_database:
-      return "Compilation database contains multiple references to the same "
-             "source file.";
     }
     llvm_unreachable("Unrecognized index_error_code.");
   }
@@ -138,7 +129,7 @@ std::error_code IndexError::convertToErrorCode() const {
 }
 
 llvm::Expected<llvm::StringMap<std::string>>
-parseCrossTUIndex(StringRef IndexPath) {
+parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir) {
   std::ifstream ExternalMapFile{std::string(IndexPath)};
   if (!ExternalMapFile)
     return llvm::make_error<IndexError>(index_error_code::missing_index_file,
@@ -156,7 +147,9 @@ parseCrossTUIndex(StringRef IndexPath) {
         return llvm::make_error<IndexError>(
             index_error_code::multiple_definitions, IndexPath.str(), LineNo);
       StringRef FileName = LineRef.substr(Pos + 1);
-      Result[LookupName] = FileName.str();
+      SmallString<256> FilePath = CrossTUDir;
+      llvm::sys::path::append(FilePath, FileName);
+      Result[LookupName] = std::string(FilePath);
     } else
       return llvm::make_error<IndexError>(
           index_error_code::invalid_index_format, IndexPath.str(), LineNo);
@@ -348,46 +341,30 @@ void CrossTranslationUnitContext::emitCrossTUDiagnostics(const IndexError &IE) {
   }
 }
 
-CrossTranslationUnitContext::ASTFileLoader::ASTFileLoader(CompilerInstance &CI,
-                                                          StringRef CTUDir)
-    : CI(CI), CTUDir(CTUDir) {}
+CrossTranslationUnitContext::ASTFileLoader::ASTFileLoader(
+    const CompilerInstance &CI)
+    : CI(CI) {}
 
-CrossTranslationUnitContext::LoadResultTy
-CrossTranslationUnitContext::ASTFileLoader::load(StringRef Identifier) {
+std::unique_ptr<ASTUnit>
+CrossTranslationUnitContext::ASTFileLoader::operator()(StringRef ASTFilePath) {
   // Load AST from ast-dump.
-
-  auto LoadFromFile = [this](StringRef Path) {
-    IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
-    TextDiagnosticPrinter *DiagClient =
-        new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
-    IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
-    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
-        new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
-    return ASTUnit::LoadFromASTFile(
-        std::string(Path.str()), CI.getPCHContainerOperations()->getRawReader(),
-        ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts());
-  };
-
-  if (llvm::sys::path::is_absolute(Identifier))
-    return LoadFromFile(Identifier);
-
-  llvm::SmallString<256> PrefixedPath = CTUDir;
-  llvm::sys::path::append(PrefixedPath, Identifier);
-
-  return LoadFromFile(PrefixedPath);
+  IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+  TextDiagnosticPrinter *DiagClient =
+      new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
+  IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+      new DiagnosticsEngine(DiagID, &*DiagOpts, DiagClient));
+
+  return ASTUnit::LoadFromASTFile(
+      std::string(ASTFilePath), CI.getPCHContainerOperations()->getRawReader(),
+      ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts());
 }
 
 CrossTranslationUnitContext::ASTUnitStorage::ASTUnitStorage(
-    CompilerInstance &CI)
-    : LoadGuard(CI.getAnalyzerOpts()->CTUImportThreshold) {
-
-  AnalyzerOptionsRef Opts = CI.getAnalyzerOpts();
-  if (Opts->CTUOnDemandParsing)
-    Loader =
-        std::make_unique<ASTOnDemandLoader>(Opts->CTUOnDemandParsingDatabase);
-  else
-    Loader = std::make_unique<ASTFileLoader>(CI, Opts->CTUDir);
-}
+    const CompilerInstance &CI)
+    : FileAccessor(CI), LoadGuard(const_cast<CompilerInstance &>(CI)
+                                      .getAnalyzerOpts()
+                                      ->CTUImportThreshold) {}
 
 llvm::Expected<ASTUnit *>
 CrossTranslationUnitContext::ASTUnitStorage::getASTUnitForFile(
@@ -403,12 +380,8 @@ CrossTranslationUnitContext::ASTUnitStorage::getASTUnitForFile(
           index_error_code::load_threshold_reached);
     }
 
-    auto LoadAttempt = Loader->load(FileName);
-
-    if (!LoadAttempt)
-      return LoadAttempt.takeError();
-
-    std::unique_ptr<ASTUnit> LoadedUnit = std::move(LoadAttempt.get());
+    // Load the ASTUnit from the pre-dumped AST file specified by ASTFileName.
+    std::unique_ptr<ASTUnit> LoadedUnit = FileAccessor(FileName);
 
     // Need the raw pointer and the unique_ptr as well.
     ASTUnit *Unit = LoadedUnit.get();
@@ -488,7 +461,7 @@ llvm::Error CrossTranslationUnitContext::ASTUnitStorage::ensureCTUIndexLoaded(
   else
     llvm::sys::path::append(IndexFile, IndexName);
 
-  if (auto IndexMapping = parseCrossTUIndex(IndexFile)) {
+  if (auto IndexMapping = parseCrossTUIndex(IndexFile, CrossTUDir)) {
     // Initialize member map.
     NameFileMap = *IndexMapping;
     return llvm::Error::success();
@@ -498,10 +471,6 @@ llvm::Error CrossTranslationUnitContext::ASTUnitStorage::ensureCTUIndexLoaded(
   };
 }
 
-CrossTranslationUnitContext::ASTOnDemandLoader::ASTOnDemandLoader(
-    StringRef OnDemandParsingDatabase)
-    : OnDemandParsingDatabase(OnDemandParsingDatabase) {}
-
 llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
     StringRef LookupName, StringRef CrossTUDir, StringRef IndexName,
     bool DisplayCTUProgress) {
@@ -525,117 +494,6 @@ llvm::Expected<ASTUnit *> CrossTranslationUnitContext::loadExternalAST(
   return Unit;
 }
 
-/// Load the AST from a source-file, which is supposed to be located inside the
-/// compilation database \p CompileCommands. The compilation database
-/// can contain the path of the file under the key "file" as an absolute path,
-/// or as a relative path. When emitting diagnostics, plist files may contain
-/// references to a location in a TU, that is 
diff erent from the main TU. In
-/// such cases, the file path emitted by the DiagnosticEngine is based on how
-/// the exact invocation is assembled inside the ClangTool, which performs the
-/// building of the ASTs. In order to ensure absolute paths inside the
-/// diagnostics, we use the ArgumentsAdjuster API of ClangTool to make sure that
-/// the invocation inside ClangTool is always made with an absolute path. \p
-/// Identifier is assumed to be the lookup-name of the file, which comes from
-/// the Index. The Index is built by the \p clang-extdef-mapping tool, which is
-/// supposed to generate absolute paths.
-///
-/// We must have absolute paths inside the plist, because otherwise we would
-/// not be able to parse the bug, because we could not find the files with
-/// relative paths. The directory of one entry in the compilation db may be
-/// 
diff erent from the directory where the plist is interpreted.
-///
-/// Note that as the ClangTool is instantiated with a lookup-vector, which
-/// contains a single entry; the supposedly absolute path of the source file.
-/// So, the ArgumentAdjuster will only be used on the single corresponding
-/// invocation. This guarantees that even if two files match in name, but
-/// 
diff er in location, only the correct one's invocation will be handled. This
-/// is due to the fact that the lookup is done correctly inside the
-/// OnDemandParsingDatabase, so it works for already absolute paths given under
-/// the "file" entry of the compilation database, but also if a relative path is
-/// given. In such a case, the lookup uses the "directory" entry as well to
-/// identify the correct file.
-CrossTranslationUnitContext::LoadResultTy
-CrossTranslationUnitContext::ASTOnDemandLoader::load(StringRef Identifier) {
-
-  if (auto InitError = lazyInitCompileCommands())
-    return std::move(InitError);
-
-  using namespace tooling;
-
-  SmallVector<std::string, 1> Files;
-  Files.push_back(std::string(Identifier));
-  ClangTool Tool(*CompileCommands, Files);
-
-  /// Lambda filter designed to find the source file argument inside an
-  /// invocation used to build the ASTs, and replace it with its absolute path
-  /// equivalent.
-  auto SourcePathNormalizer = [Identifier](const CommandLineArguments &Args,
-                                           StringRef FileName) {
-    /// Match the argument to the absolute path by checking whether it is a
-    /// postfix.
-    auto IsPostfixOfLookup = [Identifier](const std::string &Arg) {
-      return Identifier.rfind(Arg) != llvm::StringRef::npos;
-    };
-
-    /// Commandline arguments are modified, and the API dictates the return of
-    /// a new instance, so copy the original.
-    CommandLineArguments Result{Args};
-
-    /// Search for the source file argument. Start from the end as a heuristic,
-    /// as most invocations tend to contain the source file argument in their
-    /// latter half. Only the first match is replaced.
-    auto SourceFilePath =
-        std::find_if(Result.rbegin(), Result.rend(), IsPostfixOfLookup);
-
-    /// If source file argument could not been found, return the original
-    /// CommandlineArgumentsInstance.
-    if (SourceFilePath == Result.rend())
-      return Result;
-
-    /// Overwrite the argument with the \p ASTSourcePath, as it is assumed to
-    /// be the absolute path of the file.
-    *SourceFilePath = Identifier.str();
-
-    return Result;
-  };
-
-  Tool.appendArgumentsAdjuster(std::move(SourcePathNormalizer));
-
-  std::vector<std::unique_ptr<ASTUnit>> ASTs;
-  Tool.buildASTs(ASTs);
-
-  /// There is an assumption that the compilation database does not contain
-  /// multiple entries for the same source file.
-  if (ASTs.size() > 1)
-    return llvm::make_error<IndexError>(
-        index_error_code::ambiguous_compilation_database);
-
-  /// Ideally there is exactly one entry in the compilation database that
-  /// matches the source file.
-  if (ASTs.size() != 1)
-    return llvm::make_error<IndexError>(
-        index_error_code::failed_to_get_external_ast);
-
-  ASTs[0]->enableSourceFileDiagnostics();
-  return std::move(ASTs[0]);
-}
-
-llvm::Error
-CrossTranslationUnitContext::ASTOnDemandLoader::lazyInitCompileCommands() {
-  // Lazily initialize the compilation database.
-
-  if (CompileCommands)
-    return llvm::Error::success();
-
-  std::string LoadError;
-  CompileCommands = tooling::JSONCompilationDatabase::loadFromFile(
-      OnDemandParsingDatabase, LoadError,
-      tooling::JSONCommandLineSyntax::AutoDetect);
-  return CompileCommands ? llvm::Error::success()
-                         : llvm::make_error<IndexError>(
-                               index_error_code::failed_to_get_external_ast);
-}
-
 template <typename T>
 llvm::Expected<const T *>
 CrossTranslationUnitContext::importDefinitionImpl(const T *D, ASTUnit *Unit) {

diff  --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index c640574e8670..b327fa902f67 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -511,12 +511,6 @@ static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
     Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir"
                                                            << "a filename";
 
-  if (AnOpts.CTUOnDemandParsing &&
-      !llvm::sys::fs::exists(AnOpts.CTUOnDemandParsingDatabase))
-    Diags->Report(diag::err_analyzer_config_invalid_input)
-        << "ctu-on-demand-parsing-database"
-        << "a filename";
-
   if (!AnOpts.ModelPath.empty() &&
       !llvm::sys::fs::is_directory(AnOpts.ModelPath))
     Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path"

diff  --git a/clang/test/Analysis/Inputs/ctu-other.c b/clang/test/Analysis/Inputs/ctu-other.c
index 7b029ae1f287..82d29c6edb30 100644
--- a/clang/test/Analysis/Inputs/ctu-other.c
+++ b/clang/test/Analysis/Inputs/ctu-other.c
@@ -31,11 +31,9 @@ int g(struct S *ctx) {
 }
 
 // Test that asm import does not fail.
-// TODO: Support the GNU extension asm keyword as well.
-// Example using the GNU extension: asm("mov $42, %0" : "=r"(res));
 int inlineAsm() {
   int res;
-  __asm__("mov $42, %0"
+  asm("mov $42, %0"
       : "=r"(res));
   return res;
 }

diff  --git a/clang/test/Analysis/Inputs/ctu-other.c.externalDefMap.ast-dump.txt b/clang/test/Analysis/Inputs/ctu-other.c.externalDefMap.txt
similarity index 100%
rename from clang/test/Analysis/Inputs/ctu-other.c.externalDefMap.ast-dump.txt
rename to clang/test/Analysis/Inputs/ctu-other.c.externalDefMap.txt

diff  --git a/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt b/clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt
similarity index 100%
rename from clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt
rename to clang/test/Analysis/Inputs/ctu-other.cpp.externalDefMap.txt

diff  --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c
index 653a6b88c25c..226c02012c59 100644
--- a/clang/test/Analysis/analyzer-config.c
+++ b/clang/test/Analysis/analyzer-config.c
@@ -33,8 +33,6 @@
 // CHECK-NEXT: ctu-dir = ""
 // CHECK-NEXT: ctu-import-threshold = 100
 // CHECK-NEXT: ctu-index-name = externalDefMap.txt
-// CHECK-NEXT: ctu-on-demand-parsing = false
-// CHECK-NEXT: ctu-on-demand-parsing-database = compile_commands.json
 // CHECK-NEXT: deadcode.DeadStores:ShowFixIts = false
 // CHECK-NEXT: deadcode.DeadStores:WarnForDeadNestedAssignments = true
 // CHECK-NEXT: debug.AnalysisOrder:* = false
@@ -108,4 +106,4 @@
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 105
+// CHECK-NEXT: num-entries = 103

diff  --git a/clang/test/Analysis/ctu-
diff erent-triples.cpp b/clang/test/Analysis/ctu-
diff erent-triples.cpp
index 68c7b0dd7dc3..20acc318e2e7 100644
--- a/clang/test/Analysis/ctu-
diff erent-triples.cpp
+++ b/clang/test/Analysis/ctu-
diff erent-triples.cpp
@@ -2,7 +2,7 @@
 // RUN: mkdir -p %t/ctudir
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.txt %t/ctudir/externalDefMap.txt
 // RUN: %clang_analyze_cc1 -std=c++14 -triple powerpc64-montavista-linux-gnu \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \

diff  --git a/clang/test/Analysis/ctu-main.c b/clang/test/Analysis/ctu-main.c
index d991eb73a95c..114d694020a1 100644
--- a/clang/test/Analysis/ctu-main.c
+++ b/clang/test/Analysis/ctu-main.c
@@ -2,7 +2,7 @@
 // RUN: mkdir -p %t/ctudir2
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir2/ctu-other.c.ast %S/Inputs/ctu-other.c
-// RUN: cp %S/Inputs/ctu-other.c.externalDefMap.ast-dump.txt %t/ctudir2/externalDefMap.txt
+// RUN: cp %S/Inputs/ctu-other.c.externalDefMap.txt %t/ctudir2/externalDefMap.txt
 // RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -std=c89 -analyze \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
@@ -50,10 +50,6 @@ void testMacro(void) {
 void testImplicit() {
   int res = identImplicit(6);   // external implicit functions are not inlined
   clang_analyzer_eval(res == 6); // expected-warning{{TRUE}}
-  // Call something with uninitialized from the same function in which the implicit was called.
-  // This is necessary to reproduce a special bug in NoStoreFuncVisitor.
-  int uninitialized;
-  h(uninitialized); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 // Tests the import of functions that have a struct parameter

diff  --git a/clang/test/Analysis/ctu-main.cpp b/clang/test/Analysis/ctu-main.cpp
index d76b3984401e..3f095a0aabc3 100644
--- a/clang/test/Analysis/ctu-main.cpp
+++ b/clang/test/Analysis/ctu-main.cpp
@@ -4,7 +4,7 @@
 // RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir/ctu-chain.cpp.ast %S/Inputs/ctu-chain.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.txt %t/ctudir/externalDefMap.txt
 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \

diff  --git a/clang/test/Analysis/ctu-on-demand-parsing-ambigous-compilation-database.c b/clang/test/Analysis/ctu-on-demand-parsing-ambigous-compilation-database.c
deleted file mode 100644
index 8378428b6fcc..000000000000
--- a/clang/test/Analysis/ctu-on-demand-parsing-ambigous-compilation-database.c
+++ /dev/null
@@ -1,23 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir -p %t
-// RUN: cp "%s" "%t/ctu-on-demand-parsing-ambiguous-compilation-database.c"
-// RUN: cp "%S/Inputs/ctu-other.c" "%t/ctu-other.c"
-// Path substitutions on Windows platform could contain backslashes. These are escaped in the json file.
-// Note there is a duplicate entry for 'ctu-other.c'.
-// RUN: echo '[{"directory":"%t","command":"gcc -c -std=c89 -Wno-visibility ctu-other.c","file":"ctu-other.c"},{"directory":"%t","command":"gcc -c -std=c89 -Wno-visibility ctu-other.c","file":"ctu-other.c"}]' | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
-// RUN: cd "%t" && %clang_extdef_map ctu-other.c > externalDefMap.txt
-// The exit code of the analysis is 1 if the import error occurs
-// RUN: cd "%t" && not %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -std=c89 -analyze \
-// RUN:   -analyzer-checker=core,debug.ExprInspection \
-// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
-// RUN:   -analyzer-config ctu-dir=. \
-// RUN:   -analyzer-config ctu-on-demand-parsing=true \
-// RUN:   ctu-on-demand-parsing-ambiguous-compilation-database.c 2>&1 | FileCheck %t/ctu-on-demand-parsing-ambiguous-compilation-database.c
-
-// CHECK: {{.*}}multiple definitions are found for the same key in index
-
-// 'int f(int)' is defined in ctu-other.c
-int f(int);
-void testAmbiguousImport() {
-  f(0);
-}

diff  --git a/clang/test/Analysis/ctu-on-demand-parsing.c b/clang/test/Analysis/ctu-on-demand-parsing.c
deleted file mode 100644
index 80227640c196..000000000000
--- a/clang/test/Analysis/ctu-on-demand-parsing.c
+++ /dev/null
@@ -1,72 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir -p %t
-// RUN: cp "%s" "%t/ctu-on-demand-parsing.c"
-// RUN: cp "%S/Inputs/ctu-other.c" "%t/ctu-other.c"
-// Path substitutions on Windows platform could contain backslashes. These are escaped in the json file.
-// RUN: echo '[{"directory":"%t","command":"gcc -c -std=c89 -Wno-visibility ctu-other.c","file":"ctu-other.c"}]' | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
-// RUN: cd "%t" && %clang_extdef_map ctu-other.c > externalDefMap.txt
-// RUN: cd "%t" && %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only -std=c89 -analyze \
-// RUN:   -analyzer-checker=core,debug.ExprInspection \
-// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
-// RUN:   -analyzer-config ctu-dir=. \
-// RUN:   -analyzer-config ctu-on-demand-parsing=true \
-// RUN:   -verify ctu-on-demand-parsing.c
-
-void clang_analyzer_eval(int);
-
-// Test typedef and global variable in function.
-typedef struct {
-  int a;
-  int b;
-} FooBar;
-extern FooBar fb;
-int f(int);
-void testGlobalVariable() {
-  clang_analyzer_eval(f(5) == 1); // expected-warning{{TRUE}}
-}
-
-// Test enums.
-int enumCheck(void);
-enum A { x, y, z };
-void testEnum() {
-  clang_analyzer_eval(x == 0);            // expected-warning{{TRUE}}
-  clang_analyzer_eval(enumCheck() == 42); // expected-warning{{TRUE}}
-}
-
-// Test that asm import does not fail.
-int inlineAsm();
-int testInlineAsm() { return inlineAsm(); }
-
-// Test reporting error in a macro.
-struct S;
-int g(struct S *);
-void testMacro(void) {
-  g(0);
-  // expected-warning at ctu-other.c:29 {{Access to field 'a' results in a dereference of a null pointer (loaded from variable 'ctx')}}
-}
-
-// The external function prototype is incomplete.
-// warning:implicit functions are prohibited by c99
-void testImplicit() {
-  int res = identImplicit(6);    // external implicit functions are not inlined
-  clang_analyzer_eval(res == 6); // expected-warning{{TRUE}}
-  // Call something with uninitialized from the same function in which the
-  // implicit was called. This is necessary to reproduce a special bug in
-  // NoStoreFuncVisitor.
-  int uninitialized;
-  h(uninitialized); // expected-warning{{1st function call argument is an uninitialized value}}
-}
-
-// Tests the import of functions that have a struct parameter
-// defined in its prototype.
-struct DataType {
-  int a;
-  int b;
-};
-int structInProto(struct DataType *d);
-void testStructDefInArgument() {
-  struct DataType d;
-  d.a = 1;
-  d.b = 0;
-  clang_analyzer_eval(structInProto(&d) == 0); // expected-warning{{TRUE}} expected-warning{{FALSE}}
-}

diff  --git a/clang/test/Analysis/ctu-on-demand-parsing.cpp b/clang/test/Analysis/ctu-on-demand-parsing.cpp
deleted file mode 100644
index c41e5a8f42a0..000000000000
--- a/clang/test/Analysis/ctu-on-demand-parsing.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir -p %t/ctudir
-// RUN: cp %s %t/ctu-on-demand-parsing.cpp
-// RUN: cp %S/ctu-hdr.h %t/ctu-hdr.h
-// RUN: cp %S/Inputs/ctu-chain.cpp %t/ctudir/ctu-chain.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp %t/ctudir/ctu-other.cpp
-// Path substitutions on Windows platform could contain backslashes. These are escaped in the json file.
-// RUN: echo '[{"directory":"%t/ctudir","command":"clang++ -c ctu-chain.cpp","file":"ctu-chain.cpp"},{"directory":"%t/ctudir","command":"clang++ -c ctu-other.cpp","file":"ctu-other.cpp"}]' | sed -e 's/\\/\\\\/g' > %t/compile_commands.json
-// RUN: cd "%t/ctudir" && %clang_extdef_map ctu-chain.cpp ctu-other.cpp > externalDefMap.txt
-// RUN: cd "%t" && %clang_analyze_cc1 -triple x86_64-pc-linux-gnu \
-// RUN:   -analyzer-checker=core,debug.ExprInspection \
-// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
-// RUN:   -analyzer-config ctu-dir=ctudir \
-// RUN:   -analyzer-config ctu-on-demand-parsing=true \
-// RUN:   -verify ctu-on-demand-parsing.cpp
-// RUN: cd "%t" && %clang_analyze_cc1 -triple x86_64-pc-linux-gnu \
-// RUN:   -analyzer-checker=core,debug.ExprInspection \
-// RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \
-// RUN:   -analyzer-config ctu-dir="%t/ctudir" \
-// RUN:   -analyzer-config ctu-on-demand-parsing=true \
-// RUN:   -analyzer-config display-ctu-progress=true 2>&1 ctu-on-demand-parsing.cpp | FileCheck %t/ctu-on-demand-parsing.cpp
-
-// CHECK: CTU loaded AST file: {{.*}}ctu-other.cpp
-// CHECK: CTU loaded AST file: {{.*}}ctu-chain.cpp
-
-#include "ctu-hdr.h"
-
-void clang_analyzer_eval(int);
-
-int f(int);
-int g(int);
-int h(int);
-
-int callback_to_main(int x) { return x + 1; }
-
-namespace myns {
-int fns(int x);
-
-namespace embed_ns {
-int fens(int x);
-}
-
-class embed_cls {
-public:
-  int fecl(int x);
-};
-} // namespace myns
-
-class mycls {
-public:
-  int fcl(int x);
-  virtual int fvcl(int x);
-  static int fscl(int x);
-
-  class embed_cls2 {
-  public:
-    int fecl2(int x);
-  };
-};
-
-class derived : public mycls {
-public:
-  virtual int fvcl(int x) override;
-};
-
-namespace chns {
-int chf1(int x);
-}
-
-int fun_using_anon_struct(int);
-int other_macro_diag(int);
-
-void test_virtual_functions(mycls *obj) {
-  // The dynamic type is known.
-  clang_analyzer_eval(mycls().fvcl(1) == 8);   // expected-warning{{TRUE}}
-  clang_analyzer_eval(derived().fvcl(1) == 9); // expected-warning{{TRUE}}
-  // We cannot decide about the dynamic type.
-  clang_analyzer_eval(obj->fvcl(1) == 8); // expected-warning{{FALSE}} expected-warning{{TRUE}}
-  clang_analyzer_eval(obj->fvcl(1) == 9); // expected-warning{{FALSE}} expected-warning{{TRUE}}
-}
-
-int main() {
-  clang_analyzer_eval(f(3) == 2); // expected-warning{{TRUE}}
-  clang_analyzer_eval(f(4) == 3); // expected-warning{{TRUE}}
-  clang_analyzer_eval(f(5) == 3); // expected-warning{{FALSE}}
-  clang_analyzer_eval(g(4) == 6); // expected-warning{{TRUE}}
-  clang_analyzer_eval(h(2) == 8); // expected-warning{{TRUE}}
-
-  clang_analyzer_eval(myns::fns(2) == 9);                   // expected-warning{{TRUE}}
-  clang_analyzer_eval(myns::embed_ns::fens(2) == -1);       // expected-warning{{TRUE}}
-  clang_analyzer_eval(mycls().fcl(1) == 6);                 // expected-warning{{TRUE}}
-  clang_analyzer_eval(mycls::fscl(1) == 7);                 // expected-warning{{TRUE}}
-  clang_analyzer_eval(myns::embed_cls().fecl(1) == -6);     // expected-warning{{TRUE}}
-  clang_analyzer_eval(mycls::embed_cls2().fecl2(0) == -11); // expected-warning{{TRUE}}
-
-  clang_analyzer_eval(chns::chf1(4) == 12);           // expected-warning{{TRUE}}
-  clang_analyzer_eval(fun_using_anon_struct(8) == 8); // expected-warning{{TRUE}}
-
-  clang_analyzer_eval(other_macro_diag(1) == 1); // expected-warning{{TRUE}}
-  // expected-warning at ctudir/ctu-other.cpp:93{{REACHABLE}}
-  MACRODIAG(); // expected-warning{{REACHABLE}}
-}

diff  --git a/clang/test/Analysis/ctu-unknown-parts-in-triples.cpp b/clang/test/Analysis/ctu-unknown-parts-in-triples.cpp
index f41f07d1edc9..6bcbd709b5ef 100644
--- a/clang/test/Analysis/ctu-unknown-parts-in-triples.cpp
+++ b/clang/test/Analysis/ctu-unknown-parts-in-triples.cpp
@@ -5,7 +5,7 @@
 // RUN: mkdir -p %t/ctudir
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-pc-linux-gnu \
 // RUN:   -emit-pch -o %t/ctudir/ctu-other.cpp.ast %S/Inputs/ctu-other.cpp
-// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.ast-dump.txt %t/ctudir/externalDefMap.txt
+// RUN: cp %S/Inputs/ctu-other.cpp.externalDefMap.txt %t/ctudir/externalDefMap.txt
 // RUN: %clang_analyze_cc1 -std=c++14 -triple x86_64-unknown-linux-gnu \
 // RUN:   -analyzer-checker=core,debug.ExprInspection \
 // RUN:   -analyzer-config experimental-enable-naive-ctu-analysis=true \

diff  --git a/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp b/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp
index 80e2e7d3c75d..86ede5e319cb 100644
--- a/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp
+++ b/clang/unittests/CrossTU/CrossTranslationUnitTest.cpp
@@ -7,11 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/CrossTU/CrossTranslationUnit.h"
-#include "clang/AST/ASTConsumer.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/AST/ASTConsumer.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Tooling/Tooling.h"
-#include "llvm/ADT/Optional.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/ToolOutputFile.h"
@@ -163,7 +162,7 @@ TEST(CrossTranslationUnit, IndexFormatCanBeParsed) {
   IndexFile.os().flush();
   EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));
   llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
-      parseCrossTUIndex(IndexFileName);
+      parseCrossTUIndex(IndexFileName, "");
   EXPECT_TRUE((bool)IndexOrErr);
   llvm::StringMap<std::string> ParsedIndex = IndexOrErr.get();
   for (const auto &E : Index) {
@@ -174,5 +173,25 @@ TEST(CrossTranslationUnit, IndexFormatCanBeParsed) {
     EXPECT_TRUE(Index.count(E.getKey()));
 }
 
+TEST(CrossTranslationUnit, CTUDirIsHandledCorrectly) {
+  llvm::StringMap<std::string> Index;
+  Index["a"] = "/b/c/d";
+  std::string IndexText = createCrossTUIndexString(Index);
+
+  int IndexFD;
+  llvm::SmallString<256> IndexFileName;
+  ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("index", "txt", IndexFD,
+                                                  IndexFileName));
+  llvm::ToolOutputFile IndexFile(IndexFileName, IndexFD);
+  IndexFile.os() << IndexText;
+  IndexFile.os().flush();
+  EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));
+  llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
+      parseCrossTUIndex(IndexFileName, "/ctudir");
+  EXPECT_TRUE((bool)IndexOrErr);
+  llvm::StringMap<std::string> ParsedIndex = IndexOrErr.get();
+  EXPECT_EQ(ParsedIndex["a"], "/ctudir/b/c/d");
+}
+
 } // end namespace cross_tu
 } // end namespace clang


        


More information about the cfe-commits mailing list