blob: cfe302124ffdd425d0cf4603b35007c2d399e989 [file] [log] [blame]
Gabor Marton3c72fe12019-05-13 10:06:25 +00001//===- unittest/AST/ASTImporterFixtures.h - AST unit test support ---------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Fixture classes for testing the ASTImporter.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_UNITTESTS_AST_IMPORTER_FIXTURES_H
15#define LLVM_CLANG_UNITTESTS_AST_IMPORTER_FIXTURES_H
16
17#include "gmock/gmock.h"
18
19#include "clang/AST/ASTImporter.h"
20#include "clang/AST/ASTImporterLookupTable.h"
21#include "clang/Frontend/ASTUnit.h"
22
23#include "DeclMatcher.h"
24#include "Language.h"
25
26namespace clang {
27
28class ASTImporter;
29class ASTImporterLookupTable;
30class ASTUnit;
31
32namespace ast_matchers {
33
34const StringRef DeclToImportID = "declToImport";
35const StringRef DeclToVerifyID = "declToVerify";
36
37// Creates a virtual file and assigns that to the context of given AST. If the
38// file already exists then the file will not be created again as a duplicate.
39void createVirtualFileIfNeeded(ASTUnit *ToAST, StringRef FileName,
40 std::unique_ptr<llvm::MemoryBuffer> &&Buffer);
41
42void createVirtualFileIfNeeded(ASTUnit *ToAST, StringRef FileName,
43 StringRef Code);
44
45// Common base for the different families of ASTImporter tests that are
46// parameterized on the compiler options which may result a different AST. E.g.
47// -fms-compatibility or -fdelayed-template-parsing.
48class CompilerOptionSpecificTest : public ::testing::Test {
49protected:
50 // Return the extra arguments appended to runtime options at compilation.
51 virtual ArgVector getExtraArgs() const { return ArgVector(); }
52
53 // Returns the argument vector used for a specific language option, this set
54 // can be tweaked by the test parameters.
55 ArgVector getArgVectorForLanguage(Language Lang) const {
56 ArgVector Args = getBasicRunOptionsForLanguage(Lang);
57 ArgVector ExtraArgs = getExtraArgs();
58 for (const auto &Arg : ExtraArgs) {
59 Args.push_back(Arg);
60 }
61 return Args;
62 }
63};
64
65const auto DefaultTestValuesForRunOptions = ::testing::Values(
66 ArgVector(), ArgVector{"-fdelayed-template-parsing"},
67 ArgVector{"-fms-compatibility"},
68 ArgVector{"-fdelayed-template-parsing", "-fms-compatibility"});
69
70// This class provides generic methods to write tests which can check internal
71// attributes of AST nodes like getPreviousDecl(), isVirtual(), etc. Also,
72// this fixture makes it possible to import from several "From" contexts.
73class ASTImporterTestBase : public CompilerOptionSpecificTest {
74
75 const char *const InputFileName = "input.cc";
76 const char *const OutputFileName = "output.cc";
77
78public:
79 /// Allocates an ASTImporter (or one of its subclasses).
80 typedef std::function<ASTImporter *(ASTContext &, FileManager &, ASTContext &,
81 FileManager &, bool,
82 ASTImporterLookupTable *)>
83 ImporterConstructor;
84
85 // The lambda that constructs the ASTImporter we use in this test.
86 ImporterConstructor Creator;
87
88private:
89 // Buffer for the To context, must live in the test scope.
90 std::string ToCode;
91
92 // Represents a "From" translation unit and holds an importer object which we
93 // use to import from this translation unit.
94 struct TU {
95 // Buffer for the context, must live in the test scope.
96 std::string Code;
97 std::string FileName;
98 std::unique_ptr<ASTUnit> Unit;
99 TranslationUnitDecl *TUDecl = nullptr;
100 std::unique_ptr<ASTImporter> Importer;
101 ImporterConstructor Creator;
102
103 TU(StringRef Code, StringRef FileName, ArgVector Args,
104 ImporterConstructor C = ImporterConstructor());
105 ~TU();
106
107 void lazyInitImporter(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST);
108 Decl *import(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST,
109 Decl *FromDecl);
110 QualType import(ASTImporterLookupTable &LookupTable, ASTUnit *ToAST,
111 QualType FromType);
112 };
113
114 // We may have several From contexts and related translation units. In each
115 // AST, the buffers for the source are handled via references and are set
116 // during the creation of the AST. These references must point to a valid
117 // buffer until the AST is alive. Thus, we must use a list in order to avoid
118 // moving of the stored objects because that would mean breaking the
119 // references in the AST. By using a vector a move could happen when the
120 // vector is expanding, with the list we won't have these issues.
121 std::list<TU> FromTUs;
122
123 // Initialize the lookup table if not initialized already.
124 void lazyInitLookupTable(TranslationUnitDecl *ToTU);
125
126 void lazyInitToAST(Language ToLang, StringRef ToSrcCode, StringRef FileName);
127 TU *findFromTU(Decl *From);
128
129protected:
130 std::unique_ptr<ASTImporterLookupTable> LookupTablePtr;
131
132public:
133 // We may have several From context but only one To context.
134 std::unique_ptr<ASTUnit> ToAST;
135
136 // Creates an AST both for the From and To source code and imports the Decl
137 // of the identifier into the To context.
138 // Must not be called more than once within the same test.
139 std::tuple<Decl *, Decl *>
140 getImportedDecl(StringRef FromSrcCode, Language FromLang, StringRef ToSrcCode,
141 Language ToLang, StringRef Identifier = DeclToImportID);
142
143 // Creates a TU decl for the given source code which can be used as a From
144 // context. May be called several times in a given test (with different file
145 // name).
146 TranslationUnitDecl *getTuDecl(StringRef SrcCode, Language Lang,
147 StringRef FileName = "input.cc");
148
149 // Creates the To context with the given source code and returns the TU decl.
150 TranslationUnitDecl *getToTuDecl(StringRef ToSrcCode, Language ToLang);
151
152 // Import the given Decl into the ToCtx.
153 // May be called several times in a given test.
154 // The different instances of the param From may have different ASTContext.
155 Decl *Import(Decl *From, Language ToLang);
156
157 template <class DeclT> DeclT *Import(DeclT *From, Language Lang) {
158 return cast_or_null<DeclT>(Import(cast<Decl>(From), Lang));
159 }
160
161 QualType ImportType(QualType FromType, Decl *TUDecl, Language ToLang);
162
163 ~ASTImporterTestBase();
164};
165
166class ASTImporterOptionSpecificTestBase
167 : public ASTImporterTestBase,
168 public ::testing::WithParamInterface<ArgVector> {
169protected:
170 ArgVector getExtraArgs() const override { return GetParam(); }
171};
172
173} // end namespace ast_matchers
174} // end namespace clang
175
176#endif