90 lines · cpp
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-exception6//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 23using namespace clang;24using namespace llvm;25 26 27class TestFrontendAction : public ASTFrontendAction {28public:29 TestFrontendAction(IntrusiveRefCntPtr<ExternalASTSource> Source)30 : Source(std::move(Source)) {}31 32private:33 void ExecuteAction() override {34 getCompilerInstance().getASTContext().setExternalSource(Source);35 getCompilerInstance().getASTContext().getTranslationUnitDecl()36 ->setHasExternalVisibleStorage();37 return ASTFrontendAction::ExecuteAction();38 }39 40 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,41 StringRef InFile) override {42 return std::make_unique<ASTConsumer>();43 }44 45 IntrusiveRefCntPtr<ExternalASTSource> Source;46};47 48bool testExternalASTSource(llvm::IntrusiveRefCntPtr<ExternalASTSource> Source,49 StringRef FileContents) {50 51 auto Invocation = std::make_shared<CompilerInvocation>();52 Invocation->getPreprocessorOpts().addRemappedFile(53 "test.cc", MemoryBuffer::getMemBuffer(FileContents).release());54 const char *Args[] = { "test.cc" };55 56 DiagnosticOptions InvocationDiagOpts;57 auto InvocationDiags = CompilerInstance::createDiagnostics(58 *llvm::vfs::getRealFileSystem(), InvocationDiagOpts);59 CompilerInvocation::CreateFromArgs(*Invocation, Args, *InvocationDiags);60 61 CompilerInstance Compiler(std::move(Invocation));62 Compiler.setVirtualFileSystem(llvm::vfs::getRealFileSystem());63 Compiler.createDiagnostics();64 65 TestFrontendAction Action(Source);66 return Compiler.ExecuteAction(Action);67}68 69// Ensure that a failed name lookup into an external source only occurs once.70TEST(ExternalASTSourceTest, FailedLookupOccursOnce) {71 struct TestSource : ExternalASTSource {72 TestSource(unsigned &Calls) : Calls(Calls) {}73 74 bool75 FindExternalVisibleDeclsByName(const DeclContext *, DeclarationName Name,76 const DeclContext *OriginalDC) override {77 if (Name.getAsString() == "j")78 ++Calls;79 return false;80 }81 82 unsigned &Calls;83 };84 85 unsigned Calls = 0;86 ASSERT_TRUE(testExternalASTSource(87 llvm::makeIntrusiveRefCnt<TestSource>(Calls), "int j, k = j;"));88 EXPECT_EQ(1u, Calls);89}90