summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-06-09 19:08:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-06-09 19:08:19 +0000
commit798321d8eb5630cd4a8f490a4f25e32ef195fb07 (patch)
treea59f5569ef36d00388c0428426abef26aa9105b6 /utils
parent5e20cdd81c44a443562a09007668ffdf76c455af (diff)
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/ClangAttrEmitter.cpp7
-rw-r--r--utils/TableGen/ClangCommentCommandInfoEmitter.cpp2
-rw-r--r--utils/TableGen/ClangCommentHTMLTagsEmitter.cpp3
-rw-r--r--utils/TableGen/NeonEmitter.cpp36
-rwxr-xr-xutils/check_cfc/check_cfc.py32
-rwxr-xr-xutils/check_cfc/obj_diff.py26
-rwxr-xr-xutils/check_cfc/test_check_cfc.py10
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(