blob: 4e666e37aa3aba438fb1278d4a81e8b852518efe [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);
Gabor Marton3c72fe12019-05-13 10:06:25 +0000127
128protected:
129 std::unique_ptr<ASTImporterLookupTable> LookupTablePtr;
130
131public:
132 // We may have several From context but only one To context.
133 std::unique_ptr<ASTUnit> ToAST;
134
Gabor Marton303c98612019-06-25 08:00:51 +0000135 // Returns with the TU associated with the given Decl.
136 TU *findFromTU(Decl *From);
137
Gabor Marton3c72fe12019-05-13 10:06:25 +0000138 // Creates an AST both for the From and To source code and imports the Decl
139 // of the identifier into the To context.
140 // Must not be called more than once within the same test.
141 std::tuple<Decl *, Decl *>
142 getImportedDecl(StringRef FromSrcCode, Language FromLang, StringRef ToSrcCode,
143 Language ToLang, StringRef Identifier = DeclToImportID);
144
145 // Creates a TU decl for the given source code which can be used as a From
146 // context. May be called several times in a given test (with different file
147 // name).
148 TranslationUnitDecl *getTuDecl(StringRef SrcCode, Language Lang,
149 StringRef FileName = "input.cc");
150
151 // Creates the To context with the given source code and returns the TU decl.
152 TranslationUnitDecl *getToTuDecl(StringRef ToSrcCode, Language ToLang);
153
154 // Import the given Decl into the ToCtx.
155 // May be called several times in a given test.
156 // The different instances of the param From may have different ASTContext.
157 Decl *Import(Decl *From, Language ToLang);
158
159 template <class DeclT> DeclT *Import(DeclT *From, Language Lang) {
160 return cast_or_null<DeclT>(Import(cast<Decl>(From), Lang));
161 }
162
163 QualType ImportType(QualType FromType, Decl *TUDecl, Language ToLang);
164
165 ~ASTImporterTestBase();
166};
167
168class ASTImporterOptionSpecificTestBase
169 : public ASTImporterTestBase,
170 public ::testing::WithParamInterface<ArgVector> {
171protected:
172 ArgVector getExtraArgs() const override { return GetParam(); }
173};
174
175} // end namespace ast_matchers
176} // end namespace clang
177
178#endif