aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/vs2010backend.py43
-rw-r--r--mesonbuild/mparser.py23
-rw-r--r--mesonbuild/rewriter.py47
-rw-r--r--test cases/common/113 ternary/meson.build5
-rw-r--r--test cases/rewrite/1 basic/addSrc.json4
5 files changed, 60 insertions, 62 deletions
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index dd99125..6d62553 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -794,19 +794,6 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(type_config, 'WholeProgramOptimization').text = 'false'
# Let VS auto-set the RTC level
ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'Default'
- o_flags = split_o_flags_args(buildtype_args)
- if '/Oi' in o_flags:
- ET.SubElement(type_config, 'IntrinsicFunctions').text = 'true'
- if '/Ob1' in o_flags:
- ET.SubElement(type_config, 'InlineFunctionExpansion').text = 'OnlyExplicitInline'
- elif '/Ob2' in o_flags:
- ET.SubElement(type_config, 'InlineFunctionExpansion').text = 'AnySuitable'
- # In modern MSVC parlance "/O1" means size optimization.
- # "/Os" has been deprecated.
- if '/O1' in o_flags:
- ET.SubElement(type_config, 'FavorSizeOrSpeed').text = 'Size'
- else:
- ET.SubElement(type_config, 'FavorSizeOrSpeed').text = 'Speed'
# Incremental linking increases code size
if '/INCREMENTAL:NO' in buildtype_link_args:
ET.SubElement(type_config, 'LinkIncremental').text = 'false'
@@ -846,15 +833,6 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'UninitializedLocalUsageCheck'
elif '/RTCs' in buildtype_args:
ET.SubElement(type_config, 'BasicRuntimeChecks').text = 'StackFrameRuntimeCheck'
- # Optimization flags
- if '/Ox' in o_flags:
- ET.SubElement(type_config, 'Optimization').text = 'Full'
- elif '/O2' in o_flags:
- ET.SubElement(type_config, 'Optimization').text = 'MaxSpeed'
- elif '/O1' in o_flags:
- ET.SubElement(type_config, 'Optimization').text = 'MinSpace'
- elif '/Od' in o_flags:
- ET.SubElement(type_config, 'Optimization').text = 'Disabled'
# End configuration
ET.SubElement(root, 'Import', Project=r'$(VCTargetsPath)\Microsoft.Cpp.props')
generated_files, custom_target_output_files, generated_files_include_dirs = self.generate_custom_generator_commands(target, root)
@@ -1026,6 +1004,27 @@ class Vs2010Backend(backends.Backend):
ET.SubElement(clconf, 'WarningLevel').text = 'Level' + str(1 + int(warning_level))
if self.get_option_for_target('werror', target):
ET.SubElement(clconf, 'TreatWarningAsError').text = 'true'
+ # Optimization flags
+ o_flags = split_o_flags_args(buildtype_args)
+ if '/Ox' in o_flags:
+ ET.SubElement(clconf, 'Optimization').text = 'Full'
+ elif '/O2' in o_flags:
+ ET.SubElement(clconf, 'Optimization').text = 'MaxSpeed'
+ elif '/O1' in o_flags:
+ ET.SubElement(clconf, 'Optimization').text = 'MinSpace'
+ elif '/Od' in o_flags:
+ ET.SubElement(clconf, 'Optimization').text = 'Disabled'
+ if '/Oi' in o_flags:
+ ET.SubElement(clconf, 'IntrinsicFunctions').text = 'true'
+ if '/Ob1' in o_flags:
+ ET.SubElement(clconf, 'InlineFunctionExpansion').text = 'OnlyExplicitInline'
+ elif '/Ob2' in o_flags:
+ ET.SubElement(clconf, 'InlineFunctionExpansion').text = 'AnySuitable'
+ # Size-preserving flags
+ if '/Os' in o_flags:
+ ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Size'
+ else:
+ ET.SubElement(clconf, 'FavorSizeOrSpeed').text = 'Speed'
# Note: SuppressStartupBanner is /NOLOGO and is 'true' by default
pch_sources = {}
if self.environment.coredata.base_options.get('b_pch', False):
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index f18352b..17783ce 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -262,17 +262,21 @@ class BreakNode(ElementaryNode):
pass
class ArrayNode(BaseNode):
- def __init__(self, args, lineno, colno):
+ def __init__(self, args, lineno, colno, end_lineno, end_colno):
self.subdir = args.subdir
self.lineno = lineno
self.colno = colno
+ self.end_lineno = end_lineno
+ self.end_colno = end_colno
self.args = args
class DictNode(BaseNode):
- def __init__(self, args, lineno, colno):
+ def __init__(self, args, lineno, colno, end_lineno, end_colno):
self.subdir = args.subdir
self.lineno = lineno
self.colno = colno
+ self.end_lineno = end_lineno
+ self.end_colno = end_colno
self.args = args
class EmptyNode(BaseNode):
@@ -349,10 +353,12 @@ class MethodNode(BaseNode):
self.args = args
class FunctionNode(BaseNode):
- def __init__(self, subdir, lineno, colno, func_name, args):
+ def __init__(self, subdir, lineno, colno, end_lineno, end_colno, func_name, args):
self.subdir = subdir
self.lineno = lineno
self.colno = colno
+ self.end_lineno = end_lineno
+ self.end_colno = end_colno
self.func_name = func_name
assert(isinstance(func_name, str))
self.args = args
@@ -405,7 +411,8 @@ class IfNode(BaseNode):
self.block = block
class TernaryNode(BaseNode):
- def __init__(self, lineno, colno, condition, trueblock, falseblock):
+ def __init__(self, subdir, lineno, colno, condition, trueblock, falseblock):
+ self.subdir = subdir
self.lineno = lineno
self.colno = colno
self.condition = condition
@@ -540,7 +547,7 @@ class Parser:
self.expect('colon')
falseblock = self.e1()
self.in_ternary = False
- return TernaryNode(left.lineno, left.colno, left, trueblock, falseblock)
+ return TernaryNode(left.subdir, left.lineno, left.colno, left, trueblock, falseblock)
return left
def e2(self):
@@ -619,7 +626,7 @@ class Parser:
if not isinstance(left, IdNode):
raise ParseException('Function call must be applied to plain id',
self.getline(), left.lineno, left.colno)
- left = FunctionNode(left.subdir, left.lineno, left.colno, left.value, args)
+ left = FunctionNode(left.subdir, left.lineno, left.colno, self.current.lineno, self.current.colno, left.value, args)
go_again = True
while go_again:
go_again = False
@@ -640,11 +647,11 @@ class Parser:
elif self.accept('lbracket'):
args = self.args()
self.block_expect('rbracket', block_start)
- return ArrayNode(args, block_start.lineno, block_start.colno)
+ return ArrayNode(args, block_start.lineno, block_start.colno, self.current.lineno, self.current.colno)
elif self.accept('lcurl'):
key_values = self.key_values()
self.block_expect('rcurl', block_start)
- return DictNode(key_values, block_start.lineno, block_start.colno)
+ return DictNode(key_values, block_start.lineno, block_start.colno, self.current.lineno, self.current.colno)
else:
return self.e9()
diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py
index bd00ff8..ec78521 100644
--- a/mesonbuild/rewriter.py
+++ b/mesonbuild/rewriter.py
@@ -157,7 +157,7 @@ class MTypeList(MTypeBase):
super().__init__(node)
def _new_node(self):
- return mparser.ArrayNode(mparser.ArgumentNode(mparser.Token('', '', 0, 0, 0, None, '')), 0, 0)
+ return mparser.ArrayNode(mparser.ArgumentNode(mparser.Token('', '', 0, 0, 0, None, '')), 0, 0, 0, 0)
def _new_element_node(self, value):
# Overwrite in derived class
@@ -573,9 +573,19 @@ class Rewriter:
node = target['node']
assert(node is not None)
+ # Generate the current source list
+ src_list = []
+ for i in target['sources']:
+ for j in arg_list_from_node(i):
+ if isinstance(j, StringNode):
+ src_list += [j.value]
+
# Generate the new String nodes
to_append = []
- for i in cmd['sources']:
+ for i in sorted(set(cmd['sources'])):
+ if i in src_list:
+ mlog.log(' -- Source', mlog.green(i), 'is already defined for the target --> skipping')
+ continue
mlog.log(' -- Adding source', mlog.green(i), 'at',
mlog.yellow('{}:{}'.format(os.path.join(node.subdir, environment.build_filename), node.lineno)))
token = Token('string', node.subdir, 0, 0, 0, None, i)
@@ -634,16 +644,16 @@ class Rewriter:
# Build src list
src_arg_node = ArgumentNode(Token('string', cmd['subdir'], 0, 0, 0, None, ''))
- src_arr_node = ArrayNode(src_arg_node, 0, 0)
+ src_arr_node = ArrayNode(src_arg_node, 0, 0, 0, 0)
src_far_node = ArgumentNode(Token('string', cmd['subdir'], 0, 0, 0, None, ''))
- src_fun_node = FunctionNode(cmd['subdir'], 0, 0, 'files', src_far_node)
+ src_fun_node = FunctionNode(cmd['subdir'], 0, 0, 0, 0, 'files', src_far_node)
src_ass_node = AssignmentNode(cmd['subdir'], 0, 0, '{}_src'.format(cmd['target']), src_fun_node)
src_arg_node.arguments = [StringNode(Token('string', cmd['subdir'], 0, 0, 0, None, x)) for x in cmd['sources']]
src_far_node.arguments = [src_arr_node]
# Build target
tgt_arg_node = ArgumentNode(Token('string', cmd['subdir'], 0, 0, 0, None, ''))
- tgt_fun_node = FunctionNode(cmd['subdir'], 0, 0, cmd['target_type'], tgt_arg_node)
+ tgt_fun_node = FunctionNode(cmd['subdir'], 0, 0, 0, 0, cmd['target_type'], tgt_arg_node)
tgt_ass_node = AssignmentNode(cmd['subdir'], 0, 0, '{}_tgt'.format(cmd['target']), tgt_fun_node)
tgt_arg_node.arguments = [
StringNode(Token('string', cmd['subdir'], 0, 0, 0, None, cmd['target'])),
@@ -748,31 +758,8 @@ class Rewriter:
col = node.colno
start = offsets[line] + col
end = start
- if isinstance(node, ArrayNode):
- if raw[end] != '[':
- mlog.warning('Internal error: expected "[" at {}:{} but got "{}"'.format(line, col, raw[end]))
- return
- counter = 1
- while counter > 0:
- end += 1
- if raw[end] == '[':
- counter += 1
- elif raw[end] == ']':
- counter -= 1
- end += 1
-
- elif isinstance(node, FunctionNode):
- while raw[end] != '(':
- end += 1
- end += 1
- counter = 1
- while counter > 0:
- end += 1
- if raw[end] == '(':
- counter += 1
- elif raw[end] == ')':
- counter -= 1
- end += 1
+ if isinstance(node, (ArrayNode, FunctionNode)):
+ end = offsets[node.end_lineno - 1] + node.end_colno
# Only removal is supported for assignments
elif isinstance(node, AssignmentNode) and i['action'] == 'rm':
diff --git a/test cases/common/113 ternary/meson.build b/test cases/common/113 ternary/meson.build
index 3e65046..7539d56 100644
--- a/test cases/common/113 ternary/meson.build
+++ b/test cases/common/113 ternary/meson.build
@@ -1,7 +1,12 @@
project('ternary operator', 'c')
+x = true
one = true ? 1 : error('False branch should not be evaluated')
two = false ? error('True branch should not be evaluated.') : 2
+three = '@0@'.format(x ? 'yes' : 'no')
+four = [x ? '0' : '1']
assert(one == 1, 'Return value from ternary true is wrong.')
assert(two == 2, 'Return value from ternary false is wrong.')
+assert(three == 'yes', 'Return value for ternary inside method call is wrong.')
+assert(four == ['0'], 'Return value for ternary inside of list is wrong.')
diff --git a/test cases/rewrite/1 basic/addSrc.json b/test cases/rewrite/1 basic/addSrc.json
index 9d6dafd..7b6144a 100644
--- a/test cases/rewrite/1 basic/addSrc.json
+++ b/test cases/rewrite/1 basic/addSrc.json
@@ -3,7 +3,7 @@
"type": "target",
"target": "trivialprog1",
"operation": "src_add",
- "sources": ["a1.cpp", "a2.cpp"]
+ "sources": ["a1.cpp", "a2.cpp", "a1.cpp"]
},
{
"type": "target",
@@ -39,7 +39,7 @@
"type": "target",
"target": "trivialprog9",
"operation": "src_add",
- "sources": ["a6.cpp"]
+ "sources": ["a6.cpp", "a1.cpp"]
},
{
"type": "target",