1 //===- unittest/AST/ExternalASTSourceTest.cpp -----------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains tests for Clang's ExternalASTSource. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/ExternalASTSource.h" 14 #include "clang/AST/ASTConsumer.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/Frontend/CompilerInstance.h" 17 #include "clang/Frontend/CompilerInvocation.h" 18 #include "clang/Frontend/FrontendActions.h" 19 #include "clang/Lex/PreprocessorOptions.h" 20 #include "llvm/Support/VirtualFileSystem.h" 21 #include "gtest/gtest.h" 22 23 using namespace clang; 24 using namespace llvm; 25 26 27 class TestFrontendAction : public ASTFrontendAction { 28 public: 29 TestFrontendAction(ExternalASTSource *Source) : Source(Source) {} 30 31 private: 32 void ExecuteAction() override { 33 getCompilerInstance().getASTContext().setExternalSource(Source); 34 getCompilerInstance().getASTContext().getTranslationUnitDecl() 35 ->setHasExternalVisibleStorage(); 36 return ASTFrontendAction::ExecuteAction(); 37 } 38 39 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 40 StringRef InFile) override { 41 return std::make_unique<ASTConsumer>(); 42 } 43 44 IntrusiveRefCntPtr<ExternalASTSource> Source; 45 }; 46 47 bool testExternalASTSource(ExternalASTSource *Source, 48 StringRef FileContents) { 49 CompilerInstance Compiler; 50 Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem()); 51 52 auto Invocation = std::make_shared<CompilerInvocation>(); 53 Invocation->getPreprocessorOpts().addRemappedFile( 54 "test.cc", MemoryBuffer::getMemBuffer(FileContents).release()); 55 const char *Args[] = { "test.cc" }; 56 CompilerInvocation::CreateFromArgs(*Invocation, Args, 57 Compiler.getDiagnostics()); 58 Compiler.setInvocation(std::move(Invocation)); 59 60 TestFrontendAction Action(Source); 61 return Compiler.ExecuteAction(Action); 62 } 63 64 65 // Ensure that a failed name lookup into an external source only occurs once. 66 TEST(ExternalASTSourceTest, FailedLookupOccursOnce) { 67 struct TestSource : ExternalASTSource { 68 TestSource(unsigned &Calls) : Calls(Calls) {} 69 70 bool 71 FindExternalVisibleDeclsByName(const DeclContext *, DeclarationName Name, 72 const DeclContext *OriginalDC) override { 73 if (Name.getAsString() == "j") 74 ++Calls; 75 return false; 76 } 77 78 unsigned &Calls; 79 }; 80 81 unsigned Calls = 0; 82 ASSERT_TRUE(testExternalASTSource(new TestSource(Calls), "int j, k = j;")); 83 EXPECT_EQ(1u, Calls); 84 } 85