1//===- unittest/AST/SourceLocationTest.cpp - AST source loc unit tests ----===//
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 SourceLocation and SourceRange fields
11// in AST nodes.
12//
13// FIXME: In the long-term, when we test more than source locations, we may
14// want to have a unit test file for an AST node (or group of related nodes),
15// rather than a unit test file for source locations for all AST nodes.
16//
17//===----------------------------------------------------------------------===//
18
19#include "clang/AST/ASTContext.h"
20#include "MatchVerifier.h"
21#include "clang/ASTMatchers/ASTMatchFinder.h"
22#include "clang/ASTMatchers/ASTMatchers.h"
23#include "clang/Tooling/Tooling.h"
24#include "gtest/gtest.h"
25
26namespace clang {
27namespace ast_matchers {
28
29// FIXME: Pull the *Verifier tests into their own test file.
30
31TEST(MatchVerifier, ParseError) {
32  LocationVerifier<VarDecl> Verifier;
33  Verifier.expectLocation(1, 1);
34  EXPECT_FALSE(Verifier.match("int i", varDecl()));
35}
36
37TEST(MatchVerifier, NoMatch) {
38  LocationVerifier<VarDecl> Verifier;
39  Verifier.expectLocation(1, 1);
40  EXPECT_FALSE(Verifier.match("int i;", recordDecl()));
41}
42
43TEST(MatchVerifier, WrongType) {
44  LocationVerifier<RecordDecl> Verifier;
45  Verifier.expectLocation(1, 1);
46  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
47}
48
49TEST(LocationVerifier, WrongLocation) {
50  LocationVerifier<VarDecl> Verifier;
51  Verifier.expectLocation(1, 1);
52  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
53}
54
55TEST(RangeVerifier, WrongRange) {
56  RangeVerifier<VarDecl> Verifier;
57  Verifier.expectRange(1, 1, 1, 1);
58  EXPECT_FALSE(Verifier.match("int i;", varDecl()));
59}
60
61class LabelDeclRangeVerifier : public RangeVerifier<LabelStmt> {
62protected:
63  virtual SourceRange getRange(const LabelStmt &Node) {
64    return Node.getDecl()->getSourceRange();
65  }
66};
67
68TEST(LabelDecl, Range) {
69  LabelDeclRangeVerifier Verifier;
70  Verifier.expectRange(1, 12, 1, 12);
71  EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
72}
73
74TEST(LabelStmt, Range) {
75  RangeVerifier<LabelStmt> Verifier;
76  Verifier.expectRange(1, 12, 1, 15);
77  EXPECT_TRUE(Verifier.match("void f() { l: return; }", labelStmt()));
78}
79
80TEST(ParmVarDecl, KNRLocation) {
81  LocationVerifier<ParmVarDecl> Verifier;
82  Verifier.expectLocation(1, 8);
83  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
84}
85
86TEST(ParmVarDecl, KNRRange) {
87  RangeVerifier<ParmVarDecl> Verifier;
88  Verifier.expectRange(1, 8, 1, 8);
89  EXPECT_TRUE(Verifier.match("void f(i) {}", varDecl(), Lang_C));
90}
91
92TEST(CXXNewExpr, ArrayRange) {
93  RangeVerifier<CXXNewExpr> Verifier;
94  Verifier.expectRange(1, 12, 1, 22);
95  EXPECT_TRUE(Verifier.match("void f() { new int[10]; }", newExpr()));
96}
97
98TEST(CXXNewExpr, ParenRange) {
99  RangeVerifier<CXXNewExpr> Verifier;
100  Verifier.expectRange(1, 12, 1, 20);
101  EXPECT_TRUE(Verifier.match("void f() { new int(); }", newExpr()));
102}
103
104TEST(MemberExpr, ImplicitMemberRange) {
105  RangeVerifier<MemberExpr> Verifier;
106  Verifier.expectRange(2, 30, 2, 30);
107  EXPECT_TRUE(Verifier.match("struct S { operator int() const; };\n"
108                             "int foo(const S& s) { return s; }",
109                             memberExpr()));
110}
111
112TEST(VarDecl, VMTypeFixedVarDeclRange) {
113  RangeVerifier<VarDecl> Verifier;
114  Verifier.expectRange(1, 1, 1, 23);
115  EXPECT_TRUE(Verifier.match("int a[(int)(void*)1234];",
116                             varDecl(), Lang_C89));
117}
118
119TEST(CXXConstructorDecl, NoRetFunTypeLocRange) {
120  RangeVerifier<CXXConstructorDecl> Verifier;
121  Verifier.expectRange(1, 11, 1, 13);
122  EXPECT_TRUE(Verifier.match("class C { C(); };", functionDecl()));
123}
124
125TEST(CompoundLiteralExpr, CompoundVectorLiteralRange) {
126  RangeVerifier<CompoundLiteralExpr> Verifier;
127  Verifier.expectRange(2, 11, 2, 22);
128  EXPECT_TRUE(Verifier.match(
129                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
130                  "int2 i2 = (int2){1, 2};", compoundLiteralExpr()));
131}
132
133TEST(CompoundLiteralExpr, ParensCompoundVectorLiteralRange) {
134  RangeVerifier<CompoundLiteralExpr> Verifier;
135  Verifier.expectRange(2, 20, 2, 31);
136  EXPECT_TRUE(Verifier.match(
137                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
138                  "constant int2 i2 = (int2)(1, 2);",
139                  compoundLiteralExpr(), Lang_OpenCL));
140}
141
142TEST(InitListExpr, VectorLiteralListBraceRange) {
143  RangeVerifier<InitListExpr> Verifier;
144  Verifier.expectRange(2, 17, 2, 22);
145  EXPECT_TRUE(Verifier.match(
146                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
147                  "int2 i2 = (int2){1, 2};", initListExpr()));
148}
149
150TEST(InitListExpr, VectorLiteralInitListParens) {
151  RangeVerifier<InitListExpr> Verifier;
152  Verifier.expectRange(2, 26, 2, 31);
153  EXPECT_TRUE(Verifier.match(
154                  "typedef int int2 __attribute__((ext_vector_type(2)));\n"
155                  "constant int2 i2 = (int2)(1, 2);", initListExpr(), Lang_OpenCL));
156}
157
158class TemplateAngleBracketLocRangeVerifier : public RangeVerifier<TypeLoc> {
159protected:
160  virtual SourceRange getRange(const TypeLoc &Node) {
161    TemplateSpecializationTypeLoc T =
162        Node.getUnqualifiedLoc().castAs<TemplateSpecializationTypeLoc>();
163    assert(!T.isNull());
164    return SourceRange(T.getLAngleLoc(), T.getRAngleLoc());
165  }
166};
167
168TEST(TemplateSpecializationTypeLoc, AngleBracketLocations) {
169  TemplateAngleBracketLocRangeVerifier Verifier;
170  Verifier.expectRange(2, 8, 2, 10);
171  EXPECT_TRUE(Verifier.match(
172      "template<typename T> struct A {}; struct B{}; void f(\n"
173      "const A<B>&);",
174      loc(templateSpecializationType())));
175}
176
177TEST(CXXNewExpr, TypeParenRange) {
178  RangeVerifier<CXXNewExpr> Verifier;
179  Verifier.expectRange(1, 10, 1, 18);
180  EXPECT_TRUE(Verifier.match("int* a = new (int);", newExpr()));
181}
182
183class UnaryTransformTypeLocParensRangeVerifier : public RangeVerifier<TypeLoc> {
184protected:
185  virtual SourceRange getRange(const TypeLoc &Node) {
186    UnaryTransformTypeLoc T =
187        Node.getUnqualifiedLoc().castAs<UnaryTransformTypeLoc>();
188    assert(!T.isNull());
189    return SourceRange(T.getLParenLoc(), T.getRParenLoc());
190  }
191};
192
193TEST(UnaryTransformTypeLoc, ParensRange) {
194  UnaryTransformTypeLocParensRangeVerifier Verifier;
195  Verifier.expectRange(3, 26, 3, 28);
196  EXPECT_TRUE(Verifier.match(
197      "template <typename T>\n"
198      "struct S {\n"
199      "typedef __underlying_type(T) type;\n"
200      "};",
201      loc(unaryTransformType())));
202}
203
204TEST(CXXFunctionalCastExpr, SourceRange) {
205  RangeVerifier<CXXFunctionalCastExpr> Verifier;
206  Verifier.expectRange(2, 10, 2, 14);
207  EXPECT_TRUE(Verifier.match(
208      "int foo() {\n"
209      "  return int{};\n"
210      "}",
211      functionalCastExpr(), Lang_CXX11));
212}
213
214TEST(CXXConstructExpr, SourceRange) {
215  RangeVerifier<CXXConstructExpr> Verifier;
216  Verifier.expectRange(3, 14, 3, 19);
217  EXPECT_TRUE(Verifier.match(
218      "struct A { A(int, int); };\n"
219      "void f(A a);\n"
220      "void g() { f({0, 0}); }",
221      constructExpr(), Lang_CXX11));
222}
223
224TEST(CXXTemporaryObjectExpr, SourceRange) {
225  RangeVerifier<CXXTemporaryObjectExpr> Verifier;
226  Verifier.expectRange(2, 6, 2, 12);
227  EXPECT_TRUE(Verifier.match(
228      "struct A { A(int, int); };\n"
229      "A a( A{0, 0} );",
230      temporaryObjectExpr(), Lang_CXX11));
231}
232
233TEST(CXXUnresolvedConstructExpr, SourceRange) {
234  RangeVerifier<CXXUnresolvedConstructExpr> Verifier;
235  Verifier.expectRange(3, 10, 3, 12);
236  std::vector<std::string> Args;
237  Args.push_back("-fno-delayed-template-parsing");
238  EXPECT_TRUE(Verifier.match(
239      "template <typename U>\n"
240      "U foo() {\n"
241      "  return U{};\n"
242      "}",
243      unresolvedConstructExpr(), Args, Lang_CXX11));
244}
245
246TEST(UsingDecl, SourceRange) {
247  RangeVerifier<UsingDecl> Verifier;
248  Verifier.expectRange(2, 22, 2, 25);
249  EXPECT_TRUE(Verifier.match(
250      "class B { protected: int i; };\n"
251      "class D : public B { B::i; };",
252      usingDecl()));
253}
254
255TEST(UnresolvedUsingValueDecl, SourceRange) {
256  RangeVerifier<UnresolvedUsingValueDecl> Verifier;
257  Verifier.expectRange(3, 3, 3, 6);
258  EXPECT_TRUE(Verifier.match(
259      "template <typename B>\n"
260      "class D : public B {\n"
261      "  B::i;\n"
262      "};",
263      unresolvedUsingValueDecl()));
264}
265
266TEST(FriendDecl, FriendFunctionLocation) {
267  LocationVerifier<FriendDecl> Verifier;
268  Verifier.expectLocation(2, 13);
269  EXPECT_TRUE(Verifier.match("struct A {\n"
270                             "friend void f();\n"
271                             "};\n",
272                             friendDecl()));
273}
274
275TEST(FriendDecl, FriendFunctionRange) {
276  RangeVerifier<FriendDecl> Verifier;
277  Verifier.expectRange(2, 1, 2, 15);
278  EXPECT_TRUE(Verifier.match("struct A {\n"
279                             "friend void f();\n"
280                             "};\n",
281                             friendDecl()));
282}
283
284TEST(FriendDecl, FriendClassLocation) {
285  LocationVerifier<FriendDecl> Verifier;
286  Verifier.expectLocation(2, 8);
287  EXPECT_TRUE(Verifier.match("struct A {\n"
288                             "friend class B;\n"
289                             "};\n",
290                             friendDecl()));
291}
292
293TEST(FriendDecl, FriendClassRange) {
294  RangeVerifier<FriendDecl> Verifier;
295  Verifier.expectRange(2, 1, 2, 14);
296  EXPECT_TRUE(Verifier.match("struct A {\n"
297                             "friend class B;\n"
298                             "};\n",
299                             friendDecl()));
300}
301
302TEST(FriendDecl, FriendTemplateParameterLocation) {
303  LocationVerifier<FriendDecl> Verifier;
304  Verifier.expectLocation(3, 8);
305  EXPECT_TRUE(Verifier.match("template <typename T>\n"
306                             "struct A {\n"
307                             "friend T;\n"
308                             "};\n",
309                             friendDecl(), Lang_CXX11));
310}
311
312TEST(FriendDecl, FriendTemplateParameterRange) {
313  RangeVerifier<FriendDecl> Verifier;
314  Verifier.expectRange(3, 1, 3, 8);
315  EXPECT_TRUE(Verifier.match("template <typename T>\n"
316                             "struct A {\n"
317                             "friend T;\n"
318                             "};\n",
319                             friendDecl(), Lang_CXX11));
320}
321
322TEST(FriendDecl, FriendDecltypeLocation) {
323  LocationVerifier<FriendDecl> Verifier;
324  Verifier.expectLocation(4, 8);
325  EXPECT_TRUE(Verifier.match("struct A;\n"
326                             "A foo();\n"
327                             "struct A {\n"
328                             "friend decltype(foo());\n"
329                             "};\n",
330                             friendDecl(), Lang_CXX11));
331}
332
333TEST(FriendDecl, FriendDecltypeRange) {
334  RangeVerifier<FriendDecl> Verifier;
335  Verifier.expectRange(4, 1, 4, 8);
336  EXPECT_TRUE(Verifier.match("struct A;\n"
337                             "A foo();\n"
338                             "struct A {\n"
339                             "friend decltype(foo());\n"
340                             "};\n",
341                             friendDecl(), Lang_CXX11));
342}
343
344TEST(FriendDecl, InstantiationSourceRange) {
345  RangeVerifier<FriendDecl> Verifier;
346  Verifier.expectRange(4, 3, 4, 35);
347  EXPECT_TRUE(Verifier.match(
348      "template <typename T> class S;\n"
349      "template<class T> void operator+(S<T> x);\n"
350      "template<class T> struct S {\n"
351      "  friend void operator+<>(S<T> src);\n"
352      "};\n"
353      "void test(S<double> s) { +s; }",
354      friendDecl(hasParent(recordDecl(isTemplateInstantiation())))));
355}
356
357} // end namespace ast_matchers
358} // end namespace clang
359