1//
2// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#include "PreprocessorTest.h"
8#include "Token.h"
9
10class PragmaTest : public PreprocessorTest
11{
12};
13
14TEST_F(PragmaTest, EmptyName)
15{
16    const char* str = "#pragma\n";
17    const char* expected = "\n";
18
19    using testing::_;
20    // No handlePragma calls.
21    EXPECT_CALL(mDirectiveHandler, handlePragma(_, _, _)).Times(0);
22    // No error or warning.
23    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
24
25    preprocess(str, expected);
26}
27
28TEST_F(PragmaTest, EmptyValue)
29{
30    const char* str = "#pragma foo\n";
31    const char* expected = "\n";
32
33    using testing::_;
34    EXPECT_CALL(mDirectiveHandler,
35                handlePragma(pp::SourceLocation(0, 1), "foo", ""));
36    // No error or warning.
37    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
38
39    preprocess(str, expected);
40}
41
42TEST_F(PragmaTest, NameValue)
43{
44    const char* str = "#pragma foo(bar)\n";
45    const char* expected = "\n";
46
47    using testing::_;
48    EXPECT_CALL(mDirectiveHandler,
49                handlePragma(pp::SourceLocation(0, 1), "foo", "bar"));
50    // No error or warning.
51    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
52
53    preprocess(str, expected);
54}
55
56TEST_F(PragmaTest, Comments)
57{
58    const char* str = "/*foo*/"
59                      "#"
60                      "/*foo*/"
61                      "pragma"
62                      "/*foo*/"
63                      "foo"
64                      "/*foo*/"
65                      "("
66                      "/*foo*/"
67                      "bar"
68                      "/*foo*/"
69                      ")"
70                      "/*foo*/"
71                      "//foo"
72                      "\n";
73    const char* expected = "\n";
74
75    using testing::_;
76    EXPECT_CALL(mDirectiveHandler,
77                handlePragma(pp::SourceLocation(0, 1), "foo", "bar"));
78    // No error or warning.
79    EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
80
81    preprocess(str, expected);
82}
83
84TEST_F(PragmaTest, MissingNewline)
85{
86    const char* str = "#pragma foo(bar)";
87    const char* expected = "";
88
89    using testing::_;
90    // Pragma successfully parsed.
91    EXPECT_CALL(mDirectiveHandler,
92                handlePragma(pp::SourceLocation(0, 1), "foo", "bar"));
93    // Error reported about EOF.
94    EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_EOF_IN_DIRECTIVE, _, _));
95
96    preprocess(str, expected);
97}
98
99class InvalidPragmaTest : public PragmaTest,
100                          public testing::WithParamInterface<const char*>
101{
102};
103
104TEST_P(InvalidPragmaTest, Identified)
105{
106    const char* str = GetParam();
107    const char* expected = "\n";
108
109    using testing::_;
110    // No handlePragma calls.
111    EXPECT_CALL(mDirectiveHandler, handlePragma(_, _, _)).Times(0);
112    // Unrecognized pragma warning.
113    EXPECT_CALL(mDiagnostics,
114                print(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA,
115                      pp::SourceLocation(0, 1), _));
116
117    preprocess(str, expected);
118}
119
120INSTANTIATE_TEST_CASE_P(All, InvalidPragmaTest, testing::Values(
121    "#pragma 1\n",               // Invalid name.
122    "#pragma foo()\n",           // Missing value.
123    "#pragma foo bar)\n",        // Missing left paren,
124    "#pragma foo(bar\n",         // Missing right paren.
125    "#pragma foo bar\n",         // Missing parens.
126    "#pragma foo(bar) baz\n"));  // Extra tokens.
127