diff options
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 43 | ||||
-rw-r--r-- | mesonbuild/mparser.py | 23 | ||||
-rw-r--r-- | mesonbuild/rewriter.py | 47 | ||||
-rw-r--r-- | test cases/common/113 ternary/meson.build | 5 | ||||
-rw-r--r-- | test cases/rewrite/1 basic/addSrc.json | 4 |
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", |