116 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- ModulesTests.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 "Annotations.h"
 | 
						|
#include "TestFS.h"
 | 
						|
#include "TestTU.h"
 | 
						|
#include "gmock/gmock.h"
 | 
						|
#include "gtest/gtest.h"
 | 
						|
 | 
						|
#include <memory>
 | 
						|
#include <string>
 | 
						|
 | 
						|
namespace clang {
 | 
						|
namespace clangd {
 | 
						|
namespace {
 | 
						|
 | 
						|
TEST(Modules, TextualIncludeInPreamble) {
 | 
						|
  TestTU TU = TestTU::withCode(R"cpp(
 | 
						|
    #include "Textual.h"
 | 
						|
 | 
						|
    void foo() {}
 | 
						|
)cpp");
 | 
						|
  TU.ExtraArgs.push_back("-fmodule-name=M");
 | 
						|
  TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
 | 
						|
  TU.AdditionalFiles["Textual.h"] = "void foo();";
 | 
						|
  TU.AdditionalFiles["m.modulemap"] = R"modulemap(
 | 
						|
    module M {
 | 
						|
      module Textual {
 | 
						|
        textual header "Textual.h"
 | 
						|
      }
 | 
						|
    }
 | 
						|
)modulemap";
 | 
						|
  // Test that we do not crash.
 | 
						|
  TU.index();
 | 
						|
}
 | 
						|
 | 
						|
// Verify that visibility of AST nodes belonging to modules, but loaded from
 | 
						|
// preamble PCH, is restored.
 | 
						|
TEST(Modules, PreambleBuildVisibility) {
 | 
						|
  TestTU TU = TestTU::withCode(R"cpp(
 | 
						|
    #include "module.h"
 | 
						|
 | 
						|
    foo x;
 | 
						|
)cpp");
 | 
						|
  TU.OverlayRealFileSystemForModules = true;
 | 
						|
  TU.ExtraArgs.push_back("-fmodules");
 | 
						|
  TU.ExtraArgs.push_back("-fmodules-strict-decluse");
 | 
						|
  TU.ExtraArgs.push_back("-Xclang");
 | 
						|
  TU.ExtraArgs.push_back("-fmodules-local-submodule-visibility");
 | 
						|
  TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
 | 
						|
  TU.AdditionalFiles["module.h"] = R"cpp(
 | 
						|
    typedef int foo;
 | 
						|
)cpp";
 | 
						|
  TU.AdditionalFiles["m.modulemap"] = R"modulemap(
 | 
						|
    module M {
 | 
						|
      header "module.h"
 | 
						|
    }
 | 
						|
)modulemap";
 | 
						|
  EXPECT_TRUE(TU.build().getDiagnostics()->empty());
 | 
						|
}
 | 
						|
 | 
						|
TEST(Modules, Diagnostic) {
 | 
						|
  // Produce a diagnostic while building an implicit module. Use
 | 
						|
  // -fmodules-strict-decluse, but any non-silenced diagnostic will do.
 | 
						|
  TestTU TU = TestTU::withCode(R"cpp(
 | 
						|
    /*error-ok*/
 | 
						|
    #include "modular.h"
 | 
						|
 | 
						|
    void bar() {}
 | 
						|
)cpp");
 | 
						|
  TU.OverlayRealFileSystemForModules = true;
 | 
						|
  TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
 | 
						|
  TU.ExtraArgs.push_back("-fmodules");
 | 
						|
  TU.ExtraArgs.push_back("-fimplicit-modules");
 | 
						|
  TU.ExtraArgs.push_back("-fmodules-strict-decluse");
 | 
						|
  TU.AdditionalFiles["modular.h"] = R"cpp(
 | 
						|
    #include "non-modular.h"
 | 
						|
  )cpp";
 | 
						|
  TU.AdditionalFiles["non-modular.h"] = "";
 | 
						|
  TU.AdditionalFiles["m.modulemap"] = R"modulemap(
 | 
						|
    module M {
 | 
						|
      header "modular.h"
 | 
						|
    }
 | 
						|
)modulemap";
 | 
						|
 | 
						|
  // Test that we do not crash.
 | 
						|
  TU.build();
 | 
						|
}
 | 
						|
 | 
						|
// Unknown module formats are a fatal failure for clang. Ensure we don't crash.
 | 
						|
TEST(Modules, UnknownFormat) {
 | 
						|
  TestTU TU = TestTU::withCode(R"(#include "modular.h")");
 | 
						|
  TU.OverlayRealFileSystemForModules = true;
 | 
						|
  TU.ExtraArgs.push_back("-Xclang");
 | 
						|
  TU.ExtraArgs.push_back("-fmodule-format=obj");
 | 
						|
  TU.ExtraArgs.push_back("-fmodule-map-file=" + testPath("m.modulemap"));
 | 
						|
  TU.ExtraArgs.push_back("-fmodules");
 | 
						|
  TU.ExtraArgs.push_back("-fimplicit-modules");
 | 
						|
  TU.AdditionalFiles["modular.h"] = "";
 | 
						|
  TU.AdditionalFiles["m.modulemap"] = R"modulemap(
 | 
						|
    module M {
 | 
						|
      header "modular.h"
 | 
						|
    })modulemap";
 | 
						|
 | 
						|
  // Test that we do not crash.
 | 
						|
  TU.build();
 | 
						|
}
 | 
						|
} // namespace
 | 
						|
} // namespace clangd
 | 
						|
} // namespace clang
 |