1 //===- unittest/AST/ExternalASTSourceTest.cpp -----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains tests for Clang's ExternalASTSource. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/ASTConsumer.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ExternalASTSource.h" 17 #include "clang/Frontend/CompilerInstance.h" 18 #include "clang/Frontend/CompilerInvocation.h" 19 #include "clang/Frontend/FrontendActions.h" 20 #include "clang/Lex/PreprocessorOptions.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 llvm::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(); 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 Args + array_lengthof(Args), 58 Compiler.getDiagnostics()); 59 Compiler.setInvocation(std::move(Invocation)); 60 61 TestFrontendAction Action(Source); 62 return Compiler.ExecuteAction(Action); 63 } 64 65 66 // Ensure that a failed name lookup into an external source only occurs once. 67 TEST(ExternalASTSourceTest, FailedLookupOccursOnce) { 68 struct TestSource : ExternalASTSource { 69 TestSource(unsigned &Calls) : Calls(Calls) {} 70 71 bool FindExternalVisibleDeclsByName(const DeclContext *, 72 DeclarationName Name) 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