diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-06-09 19:08:19 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-06-09 19:08:19 +0000 |
| commit | 798321d8eb5630cd4a8f490a4f25e32ef195fb07 (patch) | |
| tree | a59f5569ef36d00388c0428426abef26aa9105b6 /utils | |
| parent | 5e20cdd81c44a443562a09007668ffdf76c455af (diff) | |
Diffstat (limited to 'utils')
| -rw-r--r-- | utils/TableGen/ClangAttrEmitter.cpp | 7 | ||||
| -rw-r--r-- | utils/TableGen/ClangCommentCommandInfoEmitter.cpp | 2 | ||||
| -rw-r--r-- | utils/TableGen/ClangCommentHTMLTagsEmitter.cpp | 3 | ||||
| -rw-r--r-- | utils/TableGen/NeonEmitter.cpp | 36 | ||||
| -rwxr-xr-x | utils/check_cfc/check_cfc.py | 32 | ||||
| -rwxr-xr-x | utils/check_cfc/obj_diff.py | 26 | ||||
| -rwxr-xr-x | utils/check_cfc/test_check_cfc.py | 10 |
7 files changed, 90 insertions, 26 deletions
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index e6c6d85acd60..11a766c7a4e9 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -64,10 +64,9 @@ GetFlattenedSpellings(const Record &Attr) { for (const auto &Spelling : Spellings) { if (Spelling->getValueAsString("Variety") == "GCC") { // Gin up two new spelling objects to add into the list. - Ret.push_back(FlattenedSpelling("GNU", Spelling->getValueAsString("Name"), - "", true)); - Ret.push_back(FlattenedSpelling( - "CXX11", Spelling->getValueAsString("Name"), "gnu", true)); + Ret.emplace_back("GNU", Spelling->getValueAsString("Name"), "", true); + Ret.emplace_back("CXX11", Spelling->getValueAsString("Name"), "gnu", + true); } else Ret.push_back(FlattenedSpelling(*Spelling)); } diff --git a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp index 857b22e2f0b8..3349030466fc 100644 --- a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp +++ b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp @@ -66,7 +66,7 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { std::string Name = Tag.getValueAsString("Name"); std::string Return; raw_string_ostream(Return) << "return &Commands[" << i << "];"; - Matches.push_back(StringMatcher::StringPair(Name, Return)); + Matches.emplace_back(std::move(Name), std::move(Return)); } OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n" diff --git a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp index 22c6226cfeb3..477bbc8aaa56 100644 --- a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp +++ b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp @@ -24,8 +24,7 @@ void clang::EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS) { std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Tag"); std::vector<StringMatcher::StringPair> Matches; for (Record *Tag : Tags) { - std::string Spelling = Tag->getValueAsString("Spelling"); - Matches.push_back(StringMatcher::StringPair(Spelling, "return true;")); + Matches.emplace_back(Tag->getValueAsString("Spelling"), "return true;"); } emitSourceFileHeader("HTML tag name matcher", OS); diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp index e039ae595607..7644ae2c04da 100644 --- a/utils/TableGen/NeonEmitter.cpp +++ b/utils/TableGen/NeonEmitter.cpp @@ -131,7 +131,7 @@ class Type { private: TypeSpec TS; - bool Float, Signed, Void, Poly, Constant, Pointer; + bool Float, Signed, Immediate, Void, Poly, Constant, Pointer; // ScalarForMangling and NoManglingQ are really not suited to live here as // they are not related to the type. But they live in the TypeSpec (not the // prototype), so this is really the only place to store them. @@ -140,13 +140,13 @@ private: public: Type() - : Float(false), Signed(false), Void(true), Poly(false), Constant(false), - Pointer(false), ScalarForMangling(false), NoManglingQ(false), - Bitwidth(0), ElementBitwidth(0), NumVectors(0) {} + : Float(false), Signed(false), Immediate(false), Void(true), Poly(false), + Constant(false), Pointer(false), ScalarForMangling(false), + NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) {} Type(TypeSpec TS, char CharMod) - : TS(TS), Float(false), Signed(false), Void(false), Poly(false), - Constant(false), Pointer(false), ScalarForMangling(false), + : TS(TS), Float(false), Signed(false), Immediate(false), Void(false), + Poly(false), Constant(false), Pointer(false), ScalarForMangling(false), NoManglingQ(false), Bitwidth(0), ElementBitwidth(0), NumVectors(0) { applyModifier(CharMod); } @@ -167,6 +167,7 @@ public: bool isFloating() const { return Float; } bool isInteger() const { return !Float && !Poly; } bool isSigned() const { return Signed; } + bool isImmediate() const { return Immediate; } bool isScalar() const { return NumVectors == 0; } bool isVector() const { return NumVectors > 0; } bool isFloat() const { return Float && ElementBitwidth == 32; } @@ -192,6 +193,14 @@ public: Float = false; Poly = false; Signed = Sign; + Immediate = false; + ElementBitwidth = ElemWidth; + } + void makeImmediate(unsigned ElemWidth) { + Float = false; + Poly = false; + Signed = true; + Immediate = true; ElementBitwidth = ElemWidth; } void makeScalar() { @@ -337,9 +346,9 @@ public: // Modify the TypeSpec per-argument to get a concrete Type, and create // known variables for each. // Types[0] is the return value. - Types.push_back(Type(OutTS, Proto[0])); + Types.emplace_back(OutTS, Proto[0]); for (unsigned I = 1; I < Proto.size(); ++I) - Types.push_back(Type(InTS, Proto[I])); + Types.emplace_back(InTS, Proto[I]); } /// Get the Record that this intrinsic is based off. @@ -600,6 +609,12 @@ std::string Type::builtin_str() const { else if (isInteger() && !Pointer && !Signed) S = "U" + S; + // Constant indices are "int", but have the "constant expression" modifier. + if (isImmediate()) { + assert(isInteger() && isSigned()); + S = "I" + S; + } + if (isScalar()) { if (Constant) S += "C"; if (Pointer) S += "*"; @@ -853,6 +868,7 @@ void Type::applyModifier(char Mod) { ElementBitwidth = Bitwidth = 32; NumVectors = 0; Signed = true; + Immediate = true; break; case 'l': Float = false; @@ -860,6 +876,7 @@ void Type::applyModifier(char Mod) { ElementBitwidth = Bitwidth = 64; NumVectors = 0; Signed = false; + Immediate = true; break; case 'z': ElementBitwidth /= 2; @@ -1019,9 +1036,8 @@ std::string Intrinsic::getBuiltinTypeStr() { if (LocalCK == ClassI) T.makeSigned(); - // Constant indices are always just "int". if (hasImmediate() && getImmediateIdx() == I) - T.makeInteger(32, true); + T.makeImmediate(32); S += T.builtin_str(); } diff --git a/utils/check_cfc/check_cfc.py b/utils/check_cfc/check_cfc.py index 3def36eb62f4..c6ab9abf2352 100755 --- a/utils/check_cfc/check_cfc.py +++ b/utils/check_cfc/check_cfc.py @@ -213,16 +213,18 @@ def set_input_file(args, input_file): def is_normal_compile(args): """Check if this is a normal compile which will output an object file rather - than a preprocess or link.""" + than a preprocess or link. args is a list of command line arguments.""" compile_step = '-c' in args # Bitcode cannot be disassembled in the same way bitcode = '-flto' in args or '-emit-llvm' in args # Version and help are queries of the compiler and override -c if specified query = '--version' in args or '--help' in args + # Options to output dependency files for make + dependency = '-M' in args or '-MM' in args # Check if the input is recognised as a source file (this may be too # strong a restriction) input_is_valid = bool(get_input_file(args)) - return compile_step and not bitcode and not query and input_is_valid + return compile_step and not bitcode and not query and not dependency and input_is_valid def run_step(command, my_env, error_on_failure): """Runs a step of the compilation. Reports failure as exception.""" @@ -282,12 +284,24 @@ class dash_s_no_change(WrapperCheck): run_step(alternate_command, my_env, "Error compiling with -via-file-asm") - # Compare disassembly (returns first diff if differs) - difference = obj_diff.compare_object_files(self._output_file_a, - output_file_b) - if difference: - raise WrapperCheckException( - "Code difference detected with -S\n{}".format(difference)) + # Compare if object files are exactly the same + exactly_equal = obj_diff.compare_exact(self._output_file_a, output_file_b) + if not exactly_equal: + # Compare disassembly (returns first diff if differs) + difference = obj_diff.compare_object_files(self._output_file_a, + output_file_b) + if difference: + raise WrapperCheckException( + "Code difference detected with -S\n{}".format(difference)) + + # Code is identical, compare debug info + dbgdifference = obj_diff.compare_debug_info(self._output_file_a, + output_file_b) + if dbgdifference: + raise WrapperCheckException( + "Debug info difference detected with -S\n{}".format(dbgdifference)) + + raise WrapperCheckException("Object files not identical with -S\n") # Clean up temp file if comparison okay os.remove(output_file_b) @@ -367,7 +381,7 @@ if __name__ == '__main__': checker.perform_check(arguments_a, my_env) except WrapperCheckException as e: # Check failure - print(e.msg, file=sys.stderr) + print("{} {}".format(get_input_file(arguments_a), e.msg), file=sys.stderr) # Remove file to comply with build system expectations (no # output file if failed) diff --git a/utils/check_cfc/obj_diff.py b/utils/check_cfc/obj_diff.py index 6f932b3172da..cc4c2a97d5e5 100755 --- a/utils/check_cfc/obj_diff.py +++ b/utils/check_cfc/obj_diff.py @@ -4,6 +4,7 @@ from __future__ import print_function import argparse import difflib +import filecmp import os import subprocess import sys @@ -26,6 +27,15 @@ def disassemble(objfile): sys.exit(1) return filter(keep_line, out.split(os.linesep)) +def dump_debug(objfile): + """Dump all of the debug info from a file.""" + p = subprocess.Popen([disassembler, '-WliaprmfsoRt', objfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (out, err) = p.communicate() + if p.returncode or err: + print("Dump debug failed: {}".format(objfile)) + sys.exit(1) + return filter(keep_line, out.split(os.linesep)) + def first_diff(a, b, fromfile, tofile): """Returns the first few lines of a difference, if there is one. Python diff can be very slow with large objects and the most interesting changes @@ -63,6 +73,22 @@ def compare_object_files(objfilea, objfileb): disb = disassemble(objfileb) return first_diff(disa, disb, objfilea, objfileb) +def compare_debug_info(objfilea, objfileb): + """Compare debug info of two different files. + Allowing unavoidable differences, such as filenames. + Return the first difference if the debug info differs, or None. + If there are differences in the code, there will almost certainly be differences in the debug info too. + """ + dbga = dump_debug(objfilea) + dbgb = dump_debug(objfileb) + return first_diff(dbga, dbgb, objfilea, objfileb) + +def compare_exact(objfilea, objfileb): + """Byte for byte comparison between object files. + Returns True if equal, False otherwise. + """ + return filecmp.cmp(objfilea, objfileb) + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('objfilea', nargs=1) diff --git a/utils/check_cfc/test_check_cfc.py b/utils/check_cfc/test_check_cfc.py index 0eee5b83842b..e304ff59277d 100755 --- a/utils/check_cfc/test_check_cfc.py +++ b/utils/check_cfc/test_check_cfc.py @@ -103,6 +103,16 @@ class TestCheckCFC(unittest.TestCase): check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '--version'])) self.assertFalse( check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '--help'])) + # Outputting dependency files is not a normal compile + self.assertFalse( + check_cfc.is_normal_compile(['clang', '-c', '-M', 'test.cpp'])) + self.assertFalse( + check_cfc.is_normal_compile(['clang', '-c', '-MM', 'test.cpp'])) + # Creating a dependency file as a side effect still outputs an object file + self.assertTrue( + check_cfc.is_normal_compile(['clang', '-c', '-MD', 'test.cpp'])) + self.assertTrue( + check_cfc.is_normal_compile(['clang', '-c', '-MMD', 'test.cpp'])) def test_replace_output_file(self): self.assertEqual(check_cfc.replace_output_file( |
