Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / driver / tests / pch_test.py
1 #!/usr/bin/python
2 # Copyright 2014 The Native Client 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 import os
7 import shutil
8 import sys
9 import tempfile
10 import unittest
11
12 from driver_env import env
13 import driver_test_utils
14 import driver_tools
15 import filetype
16
17 class TestPrecompiledHeaders(driver_test_utils.DriverTesterCommon):
18   def setUp(self):
19     super(TestPrecompiledHeaders, self).setUp()
20     driver_test_utils.ApplyTestEnvOverrides(env)
21     self.exit_backup = sys.exit
22     sys.exit = driver_test_utils.FakeExit
23     self.temp_dir = tempfile.mkdtemp()
24
25   def tearDown(self):
26     # Reset some internal state.
27     sys.exit = self.exit_backup
28     filetype.ClearFileTypeCaches()
29     filetype.SetForcedFileType(None)
30     shutil.rmtree(self.temp_dir)
31     super(TestPrecompiledHeaders, self).tearDown()
32
33   def runDriver(self, driver, flags):
34     driver_tools.RunDriver(driver, flags)
35     # Reset some internal state.
36     filetype.ClearFileTypeCaches()
37     filetype.SetForcedFileType(None)
38
39   def getFirstTestHeader(self, suffix='.h'):
40     filename = os.path.join(self.temp_dir, 'test_foo' + suffix)
41     with open(filename, 'w') as t:
42       t.write('''
43 #ifndef _PNACL_DRIVER_TESTS_TEST_HEADER_H_
44 #define _PNACL_DRIVER_TESTS_TEST_HEADER_H_
45 #ifdef __cplusplus
46 void foo_cxx(int x, int y);
47 #else
48 void bar_c(int x);
49 #endif
50 #endif''')
51       return t
52
53   def getSecondTestHeader(self, first_header, suffix='.h'):
54     filename = os.path.join(self.temp_dir, 'test_bar' + suffix)
55     with open(filename, 'w') as t:
56       t.write('''
57     #ifdef __cplusplus
58     #include "{header}"
59     #else
60     #include "{header}"
61     #endif
62 '''.format(header=first_header))
63       return t
64
65   def getTestSource(self, header_name, suffix='.c'):
66     filename = os.path.join(self.temp_dir, 'test_source' + suffix)
67     with open(filename, 'w') as t:
68       t.write('''#include <%s>
69 #ifdef __cplusplus
70 void cxx_func() {
71   foo_cxx(1, 2);
72 }
73 #else
74 void c_func() {
75   bar_c(1);
76 }
77 #endif''' % header_name)
78       return t
79
80   def compileAndCheck(self, driver, header, source, is_cxx):
81     source_base, _ = os.path.splitext(source)
82     out = source_base + '.ll'
83     self.runDriver(driver,
84             ['-include', header, '-S', source, '-o', out])
85     self.checkCompiledAs(out, is_cxx=is_cxx)
86
87   def checkCompiledAs(self, out, is_cxx):
88     with open(out, 'r') as t:
89       if is_cxx:
90         self.assertTrue('foo_cxx' in t.read())
91       else:
92         self.assertTrue('bar_c' in t.read())
93
94   #---- Actual tests -----#
95
96   def test_one_with_xlang(self):
97     """Test compiling one PCH file with an explicit -x, but no -o"""
98     h = self.getFirstTestHeader(suffix='.h')
99     h2 = self.getSecondTestHeader(h.name, suffix='.h')
100     self.runDriver('pnacl-clang',
101             ['-x', 'c-header', '-I', self.temp_dir, h2.name])
102     s = self.getTestSource(h2.name)
103     self.compileAndCheck('pnacl-clang', h2.name, s.name, is_cxx=False)
104
105   def test_one_override_output(self):
106     """Test compiling one PCH file with an explicit -o <output>"""
107     h = self.getFirstTestHeader(suffix='.h')
108     h2 = self.getSecondTestHeader(h.name, suffix='.h')
109     h2_out = h2.name + 'fancy.pch'
110     self.assertFalse(os.path.exists(h2_out))
111     self.runDriver('pnacl-clang',
112             ['-x', 'c-header', '-I', self.temp_dir, h2.name,
113              '-o', h2_out])
114     self.assertTrue(os.path.exists(h2_out))
115     s = self.getTestSource(h2.name)
116     self.compileAndCheck('pnacl-clang', h2.name, s.name, is_cxx=False)
117
118   def test_two_with_xlang(self):
119     """Test compiling two PCH files with an explicit -x"""
120     # Specifying multiple header files without something like -c, or -S
121     # should be fine. It should not attempt to compile and link like what
122     # would happen if there were .c or .cpp files without -c, or -S.
123     h = self.getFirstTestHeader(suffix='.h')
124     h2 = self.getSecondTestHeader(h.name, suffix='.h')
125     self.runDriver('pnacl-clang',
126             ['-x', 'c-header', '-I', self.temp_dir, h.name, h2.name])
127     self.assertTrue(os.path.exists(driver_tools.DefaultPCHOutputName(h.name)))
128     self.assertTrue(os.path.exists(driver_tools.DefaultPCHOutputName(h2.name)))
129     s = self.getTestSource(h2.name)
130     self.compileAndCheck('pnacl-clang', h2.name, s.name, is_cxx=False)
131
132   def test_ignored_dash_mode(self):
133     """Test that compiling PCH (essentially) ignores -c, -S, but not -E"""
134     h = self.getFirstTestHeader(suffix='.h')
135     self.runDriver('pnacl-clang',
136             ['-c', '-x', 'c-header', '-I', self.temp_dir, h.name])
137     h2 = self.getSecondTestHeader(h.name, suffix='.h')
138     self.runDriver('pnacl-clang',
139             ['-S', '-x', 'c-header', '-I', self.temp_dir, h2.name])
140     s = self.getTestSource(h2.name)
141     self.compileAndCheck('pnacl-clang', h2.name, s.name, is_cxx=False)
142
143   def test_not_ignore_dash_E(self):
144     """Test that compiling PCH does not ignore -E"""
145     h = self.getFirstTestHeader(suffix='.h')
146     self.runDriver('pnacl-clang',
147             ['-E', '-x', 'c-header', '-I', self.temp_dir, h.name])
148     self.assertFalse(os.path.exists(driver_tools.DefaultPCHOutputName(h.name)))
149
150   def test_two_no_xlang(self):
151     """Test compiling two PCH files without a -x (guess from suffix/driver)"""
152     h = self.getFirstTestHeader(suffix='.h')
153     h2 = self.getSecondTestHeader(h.name, suffix='.h')
154     self.runDriver('pnacl-clang',
155             ['-I', self.temp_dir, h.name, h2.name])
156     s = self.getTestSource(h2.name)
157     self.compileAndCheck('pnacl-clang', h2.name, s.name, is_cxx=False)
158
159   def test_hpp_no_xlang_clangxx(self):
160     """Test what happens when using clang++ without a -x <...> / .hpp file"""
161     h = self.getFirstTestHeader(suffix='.hpp')
162     h2 = self.getSecondTestHeader(h.name, suffix='.hpp')
163     self.runDriver('pnacl-clang++',
164             ['-I', self.temp_dir, h2.name])
165     s = self.getTestSource(h2.name, suffix='.cc')
166     self.compileAndCheck('pnacl-clang++', h2.name, s.name, is_cxx=True)
167
168   def test_h_clangxx(self):
169     """Test what happens when using clang++ but -x c++-header and .h file"""
170     # We cannot test .h with clang++ and without a -x c++-header.
171     # clang will actually say: "warning: treating 'c-header' input as
172     # 'c++-header' when in C++ mode, this behavior is deprecated."
173     # The way the pnacl drivers intercept -x and cache filetypes also
174     # makes that difficult to distinguish between the -x c-header case and the
175     # non-x-case.
176     h = self.getFirstTestHeader(suffix='.h')
177     h2 = self.getSecondTestHeader(h.name, suffix='.h')
178     self.runDriver('pnacl-clang++',
179             ['-x', 'c++-header', '-I', self.temp_dir, h2.name])
180     s = self.getTestSource(h2.name, suffix='.cc')
181     self.compileAndCheck('pnacl-clang++', h2.name, s.name, is_cxx=True)
182
183   def test_hpp_no_xlang_clang(self):
184     """Test what happens when using clang with no -x <...> / .hpp file"""
185     h = self.getFirstTestHeader(suffix='.hpp')
186     h2 = self.getSecondTestHeader(h.name, suffix='.hpp')
187     self.runDriver('pnacl-clang',
188             ['-I', self.temp_dir, h2.name])
189     s = self.getTestSource(h2.name, suffix='.cc')
190     self.compileAndCheck('pnacl-clang', h2.name, s.name, is_cxx=True)
191
192   def test_mixed_headers_other(self):
193     """Test that we throw an error when trying to mix doing PCH w/ compiling"""
194     h = self.getFirstTestHeader(suffix='.hpp')
195     h2 = self.getSecondTestHeader(h.name, suffix='.hpp')
196     s = self.getTestSource(h2.name, suffix='.cc')
197     self.assertRaises(driver_test_utils.DriverExitException,
198             self.runDriver,
199             'pnacl-clang++',
200             ['-I', self.temp_dir, h2.name, '-c', s.name])
201
202   def test_relocatable_header(self):
203     """Tests that the driver accepts --relocatable-header."""
204     h = self.getFirstTestHeader(suffix='.h')
205     h2 = self.getSecondTestHeader(h.name, suffix='.h')
206     driver_tools.RunDriver('pnacl-clang',
207             ['-x', 'c-header', '--relocatable-pch',
208              '-isysroot', self.temp_dir, h2.name])