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 22using namespace clang; 23using namespace llvm; 24 25 26class TestFrontendAction : public ASTFrontendAction { 27public: 28 TestFrontendAction(ExternalASTSource *Source) : Source(Source) {} 29 30private: 31 virtual void ExecuteAction() { 32 getCompilerInstance().getASTContext().setExternalSource(Source); 33 getCompilerInstance().getASTContext().getTranslationUnitDecl() 34 ->setHasExternalVisibleStorage(); 35 return ASTFrontendAction::ExecuteAction(); 36 } 37 38 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 39 StringRef InFile) { 40 return new ASTConsumer; 41 } 42 43 IntrusiveRefCntPtr<ExternalASTSource> Source; 44}; 45 46bool 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)); 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. 66TEST(ExternalASTSourceTest, FailedLookupOccursOnce) { 67 struct TestSource : ExternalASTSource { 68 TestSource(unsigned &Calls) : Calls(Calls) {} 69 70 bool FindExternalVisibleDeclsByName(const DeclContext*, 71 DeclarationName Name) { 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