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