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 "gtest/gtest.h" 21 22 using namespace clang; 23 using namespace llvm; 24 25 26 class TestFrontendAction : public ASTFrontendAction { 27 public: 28 TestFrontendAction(ExternalASTSource *Source) : Source(Source) {} 29 30 private: 31 void ExecuteAction() override { 32 getCompilerInstance().getASTContext().setExternalSource(Source); 33 getCompilerInstance().getASTContext().getTranslationUnitDecl() 34 ->setHasExternalVisibleStorage(); 35 return ASTFrontendAction::ExecuteAction(); 36 } 37 38 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 39 StringRef InFile) override { 40 return llvm::make_unique<ASTConsumer>(); 41 } 42 43 IntrusiveRefCntPtr<ExternalASTSource> Source; 44 }; 45 46 bool testExternalASTSource(ExternalASTSource *Source, 47 StringRef FileContents) { 48 CompilerInstance Compiler; 49 Compiler.createDiagnostics(); 50 51 CompilerInvocation *Invocation = new CompilerInvocation; 52 Invocation->getPreprocessorOpts().addRemappedFile( 53 "test.cc", MemoryBuffer::getMemBuffer(FileContents).release()); 54 const char *Args[] = { "test.cc" }; 55 CompilerInvocation::CreateFromArgs(*Invocation, Args, 56 Args + array_lengthof(Args), 57 Compiler.getDiagnostics()); 58 Compiler.setInvocation(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 FindExternalVisibleDeclsByName(const DeclContext *, 71 DeclarationName Name) override { 72 if (Name.getAsString() == "j") 73 ++Calls; 74 return false; 75 } 76 77 unsigned &Calls; 78 }; 79 80 unsigned Calls = 0; 81 ASSERT_TRUE(testExternalASTSource(new TestSource(Calls), "int j, k = j;")); 82 EXPECT_EQ(1u, Calls); 83 } 84