diff options
author | Eli Bendersky <eliben@chromium.org> | 2013-03-11 15:16:37 -0700 |
---|---|---|
committer | Eli Bendersky <eliben@chromium.org> | 2013-03-11 15:16:37 -0700 |
commit | 23c00401dad33ca247d2818e71540079bed63c5b (patch) | |
tree | df9f25d60f9538fbde84b78cf3c4e4a00eb6c3db /utils | |
parent | 79da56afe68a0c5b2c2227681014dd13705d78cc (diff) | |
parent | 279b9184c2ff4fea93b198a3519b8cb3a1d8d195 (diff) |
Merge commit '279b9184c2ff4fea93b198a3519b8cb3a1d8d195'
Conflicts:
include/llvm/CodeGen/LexicalScopes.h
include/llvm/MC/MCAsmInfo.h
lib/Linker/LinkArchives.cpp
lib/Linker/LinkItems.cpp
lib/MC/MCAsmInfo.cpp
lib/MC/MCDwarf.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsDelaySlotFiller.cpp
lib/Target/Mips/MipsISelDAGToDAG.cpp
lib/Target/Mips/MipsSubtarget.cpp
lib/Target/Mips/MipsSubtarget.h
lib/Target/Mips/MipsTargetObjectFile.cpp
lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
lib/Target/X86/X86FastISel.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetMachine.cpp
lib/Transforms/CMakeLists.txt
lib/Transforms/LLVMBuild.txt
lib/Transforms/Makefile
test/MC/ARM/arm_instructions.s
test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s
Diffstat (limited to 'utils')
95 files changed, 1130 insertions, 1052 deletions
diff --git a/utils/FileCheck/FileCheck.cpp b/utils/FileCheck/FileCheck.cpp index a0eeb0edff..563cab0d5d 100644 --- a/utils/FileCheck/FileCheck.cpp +++ b/utils/FileCheck/FileCheck.cpp @@ -242,7 +242,7 @@ bool Pattern::ParsePattern(StringRef PatternStr, SourceMgr &SM, } // Name can't start with a digit. - if (isdigit(Name[0])) { + if (isdigit(static_cast<unsigned char>(Name[0]))) { SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error, "invalid name in named regex"); return true; @@ -587,9 +587,13 @@ struct CheckString { : Pat(P), Loc(L), IsCheckNext(isCheckNext) {} }; -/// CanonicalizeInputFile - Remove duplicate horizontal space from the specified -/// memory buffer, free it, and return a new one. -static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { +/// Canonicalize whitespaces in the input file. Line endings are replaced +/// with UNIX-style '\n'. +/// +/// \param PreserveHorizontal Don't squash consecutive horizontal whitespace +/// characters to a single space. +static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB, + bool PreserveHorizontal) { SmallString<128> NewFile; NewFile.reserve(MB->getBufferSize()); @@ -600,8 +604,9 @@ static MemoryBuffer *CanonicalizeInputFile(MemoryBuffer *MB) { continue; } - // If current char is not a horizontal whitespace, dump it to output as is. - if (*Ptr != ' ' && *Ptr != '\t') { + // If current char is not a horizontal whitespace or if horizontal + // whitespace canonicalization is disabled, dump it to output as is. + if (PreserveHorizontal || (*Ptr != ' ' && *Ptr != '\t')) { NewFile.push_back(*Ptr); continue; } @@ -637,9 +642,8 @@ static bool ReadCheckFile(SourceMgr &SM, MemoryBuffer *F = File.take(); // If we want to canonicalize whitespace, strip excess whitespace from the - // buffer containing the CHECK lines. - if (!NoCanonicalizeWhiteSpace) - F = CanonicalizeInputFile(F); + // buffer containing the CHECK lines. Remove DOS style line endings. + F = CanonicalizeInputFile(F, NoCanonicalizeWhiteSpace); SM.AddNewSourceBuffer(F, SMLoc()); @@ -807,8 +811,8 @@ int main(int argc, char **argv) { } // Remove duplicate spaces in the input file if requested. - if (!NoCanonicalizeWhiteSpace) - F = CanonicalizeInputFile(F); + // Remove DOS style line endings. + F = CanonicalizeInputFile(F, NoCanonicalizeWhiteSpace); SM.AddNewSourceBuffer(F, SMLoc()); diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 6d62d6b1ff..6faf819529 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -2878,6 +2878,15 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "(MatchClassKind)it->Classes[i]);\n"; OS << " if (Diag == Match_Success)\n"; OS << " continue;\n"; + OS << " // If the generic handler indicates an invalid operand\n"; + OS << " // failure, check for a special case.\n"; + OS << " if (Diag == Match_InvalidOperand) {\n"; + OS << " Diag = validateTargetOperandClass(Operands[i+1],\n"; + OS.indent(43); + OS << "(MatchClassKind)it->Classes[i]);\n"; + OS << " if (Diag == Match_Success)\n"; + OS << " continue;\n"; + OS << " }\n"; OS << " // If this operand is broken for all of the instances of this\n"; OS << " // mnemonic, keep track of it so we can report loc info.\n"; OS << " // If we already had a match that only failed due to a\n"; diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index 73b083bd94..ac8d896d36 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -842,8 +842,11 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { if (!IAP->isOpMapped(ROName)) { IAP->addOperand(ROName, i); + Record *R = CGA->ResultOperands[i].getRecord(); + if (R->isSubClassOf("RegisterOperand")) + R = R->getValueAsDef("RegClass"); Cond = std::string("MRI.getRegClass(") + Target.getName() + "::" + - CGA->ResultOperands[i].getRecord()->getName() + "RegClassID)" + R->getName() + "RegClassID)" ".contains(MI->getOperand(" + llvm::utostr(i) + ").getReg())"; IAP->addCond(Cond); } else { diff --git a/utils/TableGen/CodeGenMapTable.cpp b/utils/TableGen/CodeGenMapTable.cpp index 1653d67da9..ee32aa13e0 100644 --- a/utils/TableGen/CodeGenMapTable.cpp +++ b/utils/TableGen/CodeGenMapTable.cpp @@ -533,12 +533,11 @@ static void emitEnums(raw_ostream &OS, RecordKeeper &Records) { II = ColFieldValueMap.begin(), IE = ColFieldValueMap.end(); II != IE; II++) { std::vector<Init*> FieldValues = (*II).second; - unsigned FieldSize = FieldValues.size(); // Delete duplicate entries from ColFieldValueMap - for (unsigned i = 0; i < FieldSize - 1; i++) { + for (unsigned i = 0; i < FieldValues.size() - 1; i++) { Init *CurVal = FieldValues[i]; - for (unsigned j = i+1; j < FieldSize; j++) { + for (unsigned j = i+1; j < FieldValues.size(); j++) { if (CurVal == FieldValues[j]) { FieldValues.erase(FieldValues.begin()+j); } @@ -547,9 +546,9 @@ static void emitEnums(raw_ostream &OS, RecordKeeper &Records) { // Emit enumerated values for the column fields. OS << "enum " << (*II).first << " {\n"; - for (unsigned i = 0; i < FieldSize; i++) { + for (unsigned i = 0, endFV = FieldValues.size(); i < endFV; i++) { OS << "\t" << (*II).first << "_" << FieldValues[i]->getAsUnquotedString(); - if (i != FieldValues.size() - 1) + if (i != endFV - 1) OS << ",\n"; else OS << "\n};\n\n"; diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index e902ce031f..993b8dba42 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -703,7 +703,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; - R->setName("AnonRegClass_"+utostr(AnonCounter++)); + R->setName("AnonRegClass_" + utostr(AnonCounter)); + // MSVC2012 ICEs if AnonCounter++ is directly passed to utostr. + ++AnonCounter; } std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes"); @@ -1198,6 +1200,12 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() { if (Idx->getComposites().empty()) { Idx->LaneMask = 1u << Bit; // Share bit 31 in the unlikely case there are more than 32 leafs. + // + // Sharing bits is harmless; it allows graceful degradation in targets + // with more than 32 vector lanes. They simply get a limited resolution + // view of lanes beyond the 32nd. + // + // See also the comment for getSubRegIndexLaneMask(). if (Bit < 31) ++Bit; } else { Idx->LaneMask = 0; diff --git a/utils/TableGen/CodeGenSchedule.cpp b/utils/TableGen/CodeGenSchedule.cpp index c653c49f25..23b79fcddf 100644 --- a/utils/TableGen/CodeGenSchedule.cpp +++ b/utils/TableGen/CodeGenSchedule.cpp @@ -1380,8 +1380,22 @@ void CodeGenSchedModels::collectProcResources() { SCI != SCE; ++SCI) { if (SCI->ItinClassDef) collectItinProcResources(SCI->ItinClassDef); - else + else { + // This class may have a default ReadWrite list which can be overriden by + // InstRW definitions. + if (!SCI->InstRWs.empty()) { + for (RecIter RWI = SCI->InstRWs.begin(), RWE = SCI->InstRWs.end(); + RWI != RWE; ++RWI) { + Record *RWModelDef = (*RWI)->getValueAsDef("SchedModel"); + IdxVec ProcIndices(1, getProcModel(RWModelDef).Index); + IdxVec Writes, Reads; + findRWs((*RWI)->getValueAsListOfDefs("OperandReadWrites"), + Writes, Reads); + collectRWResources(Writes, Reads, ProcIndices); + } + } collectRWResources(SCI->Writes, SCI->Reads, SCI->ProcIndices); + } } // Add resources separately defined by each subtarget. RecVec WRDefs = Records.getAllDerivedDefinitions("WriteRes"); diff --git a/utils/TableGen/DAGISelMatcherEmitter.cpp b/utils/TableGen/DAGISelMatcherEmitter.cpp index 4345708783..93f84ce6e8 100644 --- a/utils/TableGen/DAGISelMatcherEmitter.cpp +++ b/utils/TableGen/DAGISelMatcherEmitter.cpp @@ -132,7 +132,7 @@ static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) { return NumBytes+1; } -/// EmitMatcherOpcodes - Emit bytes for the specified matcher and return +/// EmitMatcher - Emit bytes for the specified matcher and return /// the number of bytes emitted. unsigned MatcherTableEmitter:: EmitMatcher(const Matcher *N, unsigned Indent, unsigned CurrentIdx, diff --git a/utils/TableGen/DisassemblerEmitter.cpp b/utils/TableGen/DisassemblerEmitter.cpp index 2d11d2480d..5a2a41b456 100644 --- a/utils/TableGen/DisassemblerEmitter.cpp +++ b/utils/TableGen/DisassemblerEmitter.cpp @@ -127,8 +127,9 @@ void EmitDisassembler(RecordKeeper &Records, raw_ostream &OS) { // ARM and Thumb have a CHECK() macro to deal with DecodeStatuses. if (Target.getName() == "ARM" || - Target.getName() == "Thumb") { - EmitFixedLenDecoder(Records, OS, "ARM", + Target.getName() == "Thumb" || + Target.getName() == "AArch64") { + EmitFixedLenDecoder(Records, OS, Target.getName() == "AArch64" ? "AArch64" : "ARM", "if (!Check(S, ", ")) return MCDisassembler::Fail;", "S", "MCDisassembler::Fail", " MCDisassembler::DecodeStatus S = " diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 6054cf8fa0..df4d847a4d 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -534,9 +534,8 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { N = ++AttrNum; } - // Emit an array of AttributeWithIndex. Most intrinsics will have - // at least one entry, for the function itself (index ~1), which is - // usually nounwind. + // Emit an array of AttributeSet. Most intrinsics will have at least one + // entry, for the function itself (index ~1), which is usually nounwind. OS << " static const uint8_t IntrinsicsToAttributesMap[] = {\n"; for (unsigned i = 0, e = Ints.size(); i != e; ++i) { @@ -547,7 +546,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { } OS << " };\n\n"; - OS << " AttributeWithIndex AWI[" << maxArgAttrs+1 << "];\n"; + OS << " AttributeSet AS[" << maxArgAttrs+1 << "];\n"; OS << " unsigned NumAttrs = 0;\n"; OS << " if (id != 0) {\n"; OS << " SmallVector<Attribute::AttrKind, 8> AttrVec;\n"; @@ -585,7 +584,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { ++ai; } while (ai != ae && intrinsic.ArgumentAttributes[ai].first == argNo); - OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(C, " + OS << " AS[" << numAttrs++ << "] = AttributeSet::get(C, " << argNo+1 << ", AttrVec);\n"; } } @@ -609,7 +608,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { OS << " AttrVec.push_back(Attribute::ReadNone);\n"; break; } - OS << " AWI[" << numAttrs++ << "] = AttributeWithIndex::get(C, " + OS << " AS[" << numAttrs++ << "] = AttributeSet::get(C, " << "AttributeSet::FunctionIndex, AttrVec);\n"; } @@ -623,7 +622,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) { OS << " }\n"; OS << " }\n"; - OS << " return AttributeSet::get(C, ArrayRef<AttributeWithIndex>(AWI, " + OS << " return AttributeSet::get(C, ArrayRef<AttributeSet>(AS, " "NumAttrs));\n"; OS << "}\n"; OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; diff --git a/utils/TableGen/PseudoLoweringEmitter.cpp b/utils/TableGen/PseudoLoweringEmitter.cpp index 64aaee756b..1ea6f7932a 100644 --- a/utils/TableGen/PseudoLoweringEmitter.cpp +++ b/utils/TableGen/PseudoLoweringEmitter.cpp @@ -252,6 +252,7 @@ void PseudoLoweringEmitter::emitLoweringEmitter(raw_ostream &o) { MIOpNo += Dest.Operands[OpNo].MINumOperands; } if (Dest.Operands.isVariadic) { + MIOpNo = Source.Operands.size() + 1; o << " // variable_ops\n"; o << " for (unsigned i = " << MIOpNo << ", e = MI->getNumOperands(); i != e; ++i)\n" diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index b99a6eb87e..b00f7ea2ba 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -119,6 +119,7 @@ namespace X86Local { #define TWO_BYTE_EXTENSION_TABLES \ EXTENSION_TABLE(00) \ EXTENSION_TABLE(01) \ + EXTENSION_TABLE(0d) \ EXTENSION_TABLE(18) \ EXTENSION_TABLE(71) \ EXTENSION_TABLE(72) \ diff --git a/utils/buildit/build_llvm b/utils/buildit/build_llvm index 42f8af0ef4..c056b9742b 100755 --- a/utils/buildit/build_llvm +++ b/utils/buildit/build_llvm @@ -154,6 +154,11 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then --program-prefix="" \ || exit 1 + if [ -n "$IPHONEOS_DEPLOYMENT_TARGET" ]; then + COMMON_MAKEFLAGS="$COMMON_MAKEFLAGS \ + DEPLOYMENT_TARGET=-mios-version-min=$IPHONEOS_DEPLOYMENT_TARGET" + fi + make $JOBS_FLAG $COMMON_MAKEFLAGS SDKROOT= UNIVERSAL_ARCH="$HOSTS" \ CXXFLAGS="-DLLVM_VERSION_INFO='\" Apple Build #$LLVM_VERSION\"'" if [ $? != 0 ] ; then @@ -164,12 +169,23 @@ if [ "$ARM_HOSTED_BUILD" = yes ]; then else # not $ARM_HOSTED_BUILD + export CC=`xcrun -find clang` + export CXX=`xcrun -find clang++` + if [ "$IOS_SIM_BUILD" = yes ]; then # Use a non-standard "darwin_sim" host triple to trigger a cross-build. configure_opts="--enable-targets=x86 --host=i686-apple-darwin_sim \ --build=i686-apple-darwin10" + if [ -n "$IPHONEOS_DEPLOYMENT_TARGET" ]; then + COMMON_MAKEFLAGS="$COMMON_MAKEFLAGS \ + DEPLOYMENT_TARGET=-mios-simulator-version-min=$IPHONEOS_DEPLOYMENT_TARGET" + fi else configure_opts="--enable-targets=arm,x86" + if [ -n "$MACOSX_DEPLOYMENT_TARGET" ]; then + COMMON_MAKEFLAGS="$COMMON_MAKEFLAGS \ + DEPLOYMENT_TARGET=-mmacosx-version-min=$MACOSX_DEPLOYMENT_TARGET" + fi fi if [ $SDKROOT ]; then @@ -218,6 +234,16 @@ RC_ProjectSourceSubversion=`printf "%d" $LLVM_MINOR_VERSION` echo "#define LLVM_VERSION ${RC_ProjectSourceVersion}" > $DEST_DIR$DEST_ROOT/include/llvm/Version.h echo "#define LLVM_MINOR_VERSION ${RC_ProjectSourceSubversion}" >> $DEST_DIR$DEST_ROOT/include/llvm/Version.h +# Run unifdef to preprocess the installed headers to reflect whether this +# was a debug or release build. +for file in `find $DEST_DIR$DEST_ROOT/include -type f -print`; do + if [ "$LLVM_ASSERTIONS" = yes ]; then + unifdef -UNDEBUG -D_DEBUG -o $file $file + else + unifdef -DNDEBUG -U_DEBUG -ULLVM_ENABLE_DUMP -o $file $file + fi +done + # Find the right version of strip to use. STRIP=strip if [ -n "$SDKROOT" ]; then diff --git a/utils/git/find-rev b/utils/git/find-rev index a6161db189..059ca0b78d 100755 --- a/utils/git/find-rev +++ b/utils/git/find-rev @@ -5,9 +5,9 @@ import os, sys, subprocess def main(): from optparse import OptionParser, OptionGroup parser = OptionParser("usage: %prog [options] <repo> <revision>") - parser.add_option("", "--dump-section-data", dest="dumpSectionData", - help="Dump the contents of sections", - action="store_true", default=False) + parser.add_option("", "--branch", dest="branch", + help="Ref for the branch to search [%default]", + action="store", default="git-svn") (opts, args) = parser.parse_args() if len(args) != 2: @@ -21,7 +21,7 @@ def main(): parser.error("invalid revision argument (not an integer)") os.chdir(repo) - p = subprocess.Popen(['git', 'rev-list', 'git-svn', '--pretty'], + p = subprocess.Popen(['git', 'rev-list', opts.branch, '--pretty'], stdout=subprocess.PIPE) bestRev = bestCommit = None diff --git a/utils/kate/llvm.xml b/utils/kate/llvm.xml index 074fa16cb8..1778cfce38 100644 --- a/utils/kate/llvm.xml +++ b/utils/kate/llvm.xml @@ -90,6 +90,7 @@ <item> readonly </item> <item> ssp </item> <item> sspreq </item> + <item> sspstrong </item> </list> <list name="types"> <item> float </item> diff --git a/utils/lit/MANIFEST.in b/utils/lit/MANIFEST.in new file mode 100644 index 0000000000..6491a02dd1 --- /dev/null +++ b/utils/lit/MANIFEST.in @@ -0,0 +1,7 @@ +include TODO lit.py +recursive-include tests * +global-exclude *pyc +global-exclude *~ +prune tests/Output +prune tests/*/Output +prune tests/*/*/Output diff --git a/utils/lit/TODO b/utils/lit/TODO index 6d7f7ea529..d2ff842f31 100644 --- a/utils/lit/TODO +++ b/utils/lit/TODO @@ -7,3 +7,20 @@ - Support valgrind in all configs, and LLVM style valgrind. - Support a timeout / ulimit. + + - Rename 'lit' injected variable for config to be lit_config. + + - Allow import of 'lit' in test suite definitions. + + - Create an explicit test suite object (instead of using the top-level + TestingConfig object). + + - Allow 'lit' driver to cooperate with test suites to add options (or at least + sanitize accepted params). + + - Consider move to identifying all tests by path-to-test-suite and then path to + subtest, and don't use test suite names. + + - Consider move to change workflow to always load suites, then resolve command + line arguments. + diff --git a/utils/lit/lit/ExampleTests/Clang/lit.cfg b/utils/lit/lit/ExampleTests/Clang/lit.cfg index 1e1e807f36..9295bd9ddb 100644 --- a/utils/lit/lit/ExampleTests/Clang/lit.cfg +++ b/utils/lit/lit/ExampleTests/Clang/lit.cfg @@ -14,7 +14,7 @@ config.test_format = lit.formats.ShTest(execute_external = True) # suffixes: A list of file extensions to treat as test files. config.suffixes = ['.c', '.cpp', '.m', '.mm'] -# target_triple: Used by ShTest and TclTest formats for XFAIL checks. +# target_triple: Used by ShTest format for XFAIL checks. config.target_triple = 'foo' ### diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/data.txt b/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/data.txt new file mode 100644 index 0000000000..45b983be36 --- /dev/null +++ b/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/data.txt @@ -0,0 +1 @@ +hi diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp b/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp deleted file mode 100644 index 2bda07a31c..0000000000 --- a/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/dg.exp +++ /dev/null @@ -1,6 +0,0 @@ -load_lib llvm.exp - -if { [llvm_supports_target X86] } { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]] -} - diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/pct-S.ll b/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/pct-S.ll new file mode 100644 index 0000000000..3ff363315a --- /dev/null +++ b/utils/lit/lit/ExampleTests/LLVM.InTree/test/Bar/pct-S.ll @@ -0,0 +1 @@ +; RUN: grep "hi" %S/data.txt diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg b/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg index 3fdd63c224..533c44501f 100644 --- a/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg +++ b/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.cfg @@ -8,11 +8,11 @@ import os config.name = 'LLVM' # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.TclTest() +config.test_format = lit.formats.ShTest() # suffixes: A list of file extensions to treat as test files, this is actually # set by on_clone(). -config.suffixes = [] +config.suffixes = [ '.ll' ] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) @@ -64,74 +64,3 @@ if config.test_exec_root is None: lit.load_config(config, site_cfg) raise SystemExit -### - -# Load site data from DejaGNU's site.exp. -import re -site_exp = {} -# FIXME: Implement lit.site.cfg. -for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')): - m = re.match('set ([^ ]+) "([^"]*)"', line) - if m: - site_exp[m.group(1)] = m.group(2) - -excludes = [] - -# Provide target_triple for use in XFAIL. -config.target_triple = site_exp['target_triplet'] - -# Provide llvm_supports_target for use in local configs. -targets = set(site_exp["TARGETS_TO_BUILD"].split()) -def llvm_supports_target(name): - return name in targets - -# Provide on_clone hook for reading 'dg.exp'. -import os -simpleLibData = re.compile(r"""load_lib llvm.exp - -RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""", - re.MULTILINE) -conditionalLibData = re.compile(r"""load_lib llvm.exp - -if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{ - *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\] -\}""", re.MULTILINE) -def on_clone(parent, cfg, for_path): - def addSuffixes(match): - if match[0] == '{' and match[-1] == '}': - cfg.suffixes = ['.' + s for s in match[1:-1].split(',')] - else: - cfg.suffixes = ['.' + match] - - libPath = os.path.join(os.path.dirname(for_path), - 'dg.exp') - if not os.path.exists(libPath): - cfg.unsupported = True - return - - # Reset unsupported, in case we inherited it. - cfg.unsupported = False - lib = open(libPath).read().strip() - - # Check for a simple library. - m = simpleLibData.match(lib) - if m: - addSuffixes(m.group(1)) - return - - # Check for a conditional test set. - m = conditionalLibData.match(lib) - if m: - funcname,arg,match = m.groups() - addSuffixes(match) - - func = globals().get(funcname) - if not func: - lit.error('unsupported predicate %r' % funcname) - elif not func(arg): - cfg.unsupported = True - return - # Otherwise, give up. - lit.error('unable to understand %r:\n%s' % (libPath, lib)) - -config.on_clone = on_clone diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg b/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg index 3bfee547b7..d45f3ac762 100644 --- a/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg +++ b/utils/lit/lit/ExampleTests/LLVM.InTree/test/lit.site.cfg @@ -1,8 +1,5 @@ # -*- Python -*- -## Autogenerated by Makefile ## -# Do not edit! - # Preserve some key paths for use by main LLVM test suite config. config.llvm_obj_root = os.path.dirname(os.path.dirname(__file__)) diff --git a/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp b/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp deleted file mode 100644 index 2b60cb9f20..0000000000 --- a/utils/lit/lit/ExampleTests/LLVM.InTree/test/site.exp +++ /dev/null @@ -1,10 +0,0 @@ -## these variables are automatically generated by make ## -# Do not edit here. If you wish to override these values -# edit the last section -set target_triplet "x86_64-apple-darwin10" -set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips PIC16 XCore MSP430 Blackfin MSIL CppBackend" -set srcroot "/Volumes/Data/ddunbar/llvm" -set objroot "/Volumes/Data/ddunbar/llvm.obj.64" -set srcdir "/Volumes/Data/ddunbar/llvm/test" -set objdir "/Volumes/Data/ddunbar/llvm.obj.64/test" -## All variables above are generated by configure. Do Not Edit ## diff --git a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg index bdcc35e093..94a02d8f85 100644 --- a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg +++ b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/lit.site.cfg @@ -1,8 +1,5 @@ # -*- Python -*- -## Autogenerated by Makefile ## -# Do not edit! - # Preserve some key paths for use by main LLVM test suite config. config.llvm_obj_root = os.path.dirname(os.path.dirname(__file__)) diff --git a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp deleted file mode 100644 index 2b60cb9f20..0000000000 --- a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/obj/test/site.exp +++ /dev/null @@ -1,10 +0,0 @@ -## these variables are automatically generated by make ## -# Do not edit here. If you wish to override these values -# edit the last section -set target_triplet "x86_64-apple-darwin10" -set TARGETS_TO_BUILD "X86 Sparc PowerPC ARM Mips PIC16 XCore MSP430 Blackfin MSIL CppBackend" -set srcroot "/Volumes/Data/ddunbar/llvm" -set objroot "/Volumes/Data/ddunbar/llvm.obj.64" -set srcdir "/Volumes/Data/ddunbar/llvm/test" -set objdir "/Volumes/Data/ddunbar/llvm.obj.64/test" -## All variables above are generated by configure. Do Not Edit ## diff --git a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp deleted file mode 100644 index 2bda07a31c..0000000000 --- a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/Foo/dg.exp +++ /dev/null @@ -1,6 +0,0 @@ -load_lib llvm.exp - -if { [llvm_supports_target X86] } { - RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll}]] -} - diff --git a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg index 3fdd63c224..533c44501f 100644 --- a/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg +++ b/utils/lit/lit/ExampleTests/LLVM.OutOfTree/src/test/lit.cfg @@ -8,11 +8,11 @@ import os config.name = 'LLVM' # testFormat: The test format to use to interpret tests. -config.test_format = lit.formats.TclTest() +config.test_format = lit.formats.ShTest() # suffixes: A list of file extensions to treat as test files, this is actually # set by on_clone(). -config.suffixes = [] +config.suffixes = [ '.ll' ] # test_source_root: The root path where tests are located. config.test_source_root = os.path.dirname(__file__) @@ -64,74 +64,3 @@ if config.test_exec_root is None: lit.load_config(config, site_cfg) raise SystemExit -### - -# Load site data from DejaGNU's site.exp. -import re -site_exp = {} -# FIXME: Implement lit.site.cfg. -for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')): - m = re.match('set ([^ ]+) "([^"]*)"', line) - if m: - site_exp[m.group(1)] = m.group(2) - -excludes = [] - -# Provide target_triple for use in XFAIL. -config.target_triple = site_exp['target_triplet'] - -# Provide llvm_supports_target for use in local configs. -targets = set(site_exp["TARGETS_TO_BUILD"].split()) -def llvm_supports_target(name): - return name in targets - -# Provide on_clone hook for reading 'dg.exp'. -import os -simpleLibData = re.compile(r"""load_lib llvm.exp - -RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""", - re.MULTILINE) -conditionalLibData = re.compile(r"""load_lib llvm.exp - -if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{ - *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\] -\}""", re.MULTILINE) -def on_clone(parent, cfg, for_path): - def addSuffixes(match): - if match[0] == '{' and match[-1] == '}': - cfg.suffixes = ['.' + s for s in match[1:-1].split(',')] - else: - cfg.suffixes = ['.' + match] - - libPath = os.path.join(os.path.dirname(for_path), - 'dg.exp') - if not os.path.exists(libPath): - cfg.unsupported = True - return - - # Reset unsupported, in case we inherited it. - cfg.unsupported = False - lib = open(libPath).read().strip() - - # Check for a simple library. - m = simpleLibData.match(lib) - if m: - addSuffixes(m.group(1)) - return - - # Check for a conditional test set. - m = conditionalLibData.match(lib) - if m: - funcname,arg,match = m.groups() - addSuffixes(match) - - func = globals().get(funcname) - if not func: - lit.error('unsupported predicate %r' % funcname) - elif not func(arg): - cfg.unsupported = True - return - # Otherwise, give up. - lit.error('unable to understand %r:\n%s' % (libPath, lib)) - -config.on_clone = on_clone diff --git a/utils/lit/lit/ExampleTests/TclTest/lit.local.cfg b/utils/lit/lit/ExampleTests/TclTest/lit.local.cfg deleted file mode 100644 index 6a37129acd..0000000000 --- a/utils/lit/lit/ExampleTests/TclTest/lit.local.cfg +++ /dev/null @@ -1,5 +0,0 @@ -# -*- Python -*- - -config.test_format = lit.formats.TclTest() - -config.suffixes = ['.ll'] diff --git a/utils/lit/lit/ExampleTests/TclTest/stderr-pipe.ll b/utils/lit/lit/ExampleTests/TclTest/stderr-pipe.ll deleted file mode 100644 index 6c55fe8a0b..0000000000 --- a/utils/lit/lit/ExampleTests/TclTest/stderr-pipe.ll +++ /dev/null @@ -1 +0,0 @@ -; RUN: gcc -### > /dev/null |& grep {gcc version} diff --git a/utils/lit/lit/ExampleTests/TclTest/tcl-redir-1.ll b/utils/lit/lit/ExampleTests/TclTest/tcl-redir-1.ll deleted file mode 100644 index 61240ba459..0000000000 --- a/utils/lit/lit/ExampleTests/TclTest/tcl-redir-1.ll +++ /dev/null @@ -1,7 +0,0 @@ -; RUN: echo 'hi' > %t.1 | echo 'hello' > %t.2 -; RUN: not grep 'hi' %t.1 -; RUN: grep 'hello' %t.2 - - - - diff --git a/utils/lit/lit/ExampleTests/lit.cfg b/utils/lit/lit/ExampleTests/lit.cfg index 2629918d9f..164daba903 100644 --- a/utils/lit/lit/ExampleTests/lit.cfg +++ b/utils/lit/lit/ExampleTests/lit.cfg @@ -19,8 +19,8 @@ config.test_source_root = None # root). config.test_exec_root = None -# target_triple: Used by ShTest and TclTest formats for XFAIL checks. +# target_triple: Used by ShTest format for XFAIL checks. config.target_triple = 'foo' -# available_features: Used by ShTest and TclTest formats for REQUIRES checks. +# available_features: Used by ShTest format for REQUIRES checks. config.available_features.add('some-feature-name') diff --git a/utils/lit/lit/LitConfig.py b/utils/lit/lit/LitConfig.py index 0a359a3db8..9bcf20b2f1 100644 --- a/utils/lit/lit/LitConfig.py +++ b/utils/lit/lit/LitConfig.py @@ -12,16 +12,15 @@ class LitConfig: import Test # Provide access to built-in formats. - import LitFormats as formats + import TestFormats as formats # Provide access to built-in utility functions. import Util as util def __init__(self, progname, path, quiet, useValgrind, valgrindLeakCheck, valgrindArgs, - useTclAsSh, noExecute, ignoreStdErr, debug, isWindows, - params): + params, config_prefix = None): # The name of the test runner. self.progname = progname # The items to add to the PATH environment variable. @@ -30,7 +29,6 @@ class LitConfig: self.useValgrind = bool(useValgrind) self.valgrindLeakCheck = bool(valgrindLeakCheck) self.valgrindUserArgs = list(valgrindArgs) - self.useTclAsSh = bool(useTclAsSh) self.noExecute = noExecute self.ignoreStdErr = ignoreStdErr self.debug = debug @@ -38,6 +36,12 @@ class LitConfig: self.params = dict(params) self.bashPath = None + # Configuration files to look for when discovering test suites. + self.config_prefix = config_prefix or 'lit' + self.config_name = '%s.cfg' % (self.config_prefix,) + self.site_config_name = '%s.site.cfg' % (self.config_prefix,) + self.local_config_name = '%s.local.cfg' % (self.config_prefix,) + self.numErrors = 0 self.numWarnings = 0 @@ -80,7 +84,7 @@ class LitConfig: break if self.bashPath is None: - self.warning("Unable to find 'bash', running Tcl tests internally.") + self.warning("Unable to find 'bash'.") self.bashPath = '' return self.bashPath diff --git a/utils/lit/lit/LitFormats.py b/utils/lit/lit/LitFormats.py deleted file mode 100644 index 931d107109..0000000000 --- a/utils/lit/lit/LitFormats.py +++ /dev/null @@ -1,3 +0,0 @@ -from TestFormats import FileBasedTest -from TestFormats import GoogleTest, ShTest, TclTest -from TestFormats import SyntaxCheckTest, OneCommandPerFileTest diff --git a/utils/lit/lit/ShUtil.py b/utils/lit/lit/ShUtil.py index dda622a48a..50f7910319 100644 --- a/utils/lit/lit/ShUtil.py +++ b/utils/lit/lit/ShUtil.py @@ -35,7 +35,7 @@ class ShLexer: if ('|' in chunk or '&' in chunk or '<' in chunk or '>' in chunk or "'" in chunk or '"' in chunk or - '\\' in chunk): + ';' in chunk or '\\' in chunk): return None self.pos = self.pos - 1 + len(chunk) @@ -48,7 +48,7 @@ class ShLexer: str = c while self.pos != self.end: c = self.look() - if c.isspace() or c in "|&": + if c.isspace() or c in "|&;": break elif c in '><': # This is an annoying case; we treat '2>' as a single token so @@ -129,7 +129,7 @@ class ShLexer: lex_one_token - Lex a single 'sh' token. """ c = self.eat() - if c in ';!': + if c == ';': return (c,) if c == '|': if self.maybe_eat('|'): @@ -219,9 +219,6 @@ class ShParser: def parse_pipeline(self): negate = False - if self.look() == ('!',): - self.lex() - negate = True commands = [self.parse_command()] while self.look() == ('|',): @@ -253,9 +250,9 @@ class TestShLexer(unittest.TestCase): return list(ShLexer(str, *args, **kwargs).lex()) def test_basic(self): - self.assertEqual(self.lex('a|b>c&d<e'), + self.assertEqual(self.lex('a|b>c&d<e;f'), ['a', ('|',), 'b', ('>',), 'c', ('&',), 'd', - ('<',), 'e']) + ('<',), 'e', (';',), 'f']) def test_redirection_tokens(self): self.assertEqual(self.lex('a2>c'), @@ -317,10 +314,6 @@ class TestShParse(unittest.TestCase): Command(['c'], [])], False)) - self.assertEqual(self.parse('! a'), - Pipeline([Command(['a'], [])], - True)) - def test_list(self): self.assertEqual(self.parse('a ; b'), Seq(Pipeline([Command(['a'], [])], False), @@ -349,5 +342,10 @@ class TestShParse(unittest.TestCase): '||', Pipeline([Command(['c'], [])], False))) + self.assertEqual(self.parse('a; b'), + Seq(Pipeline([Command(['a'], [])], False), + ';', + Pipeline([Command(['b'], [])], False))) + if __name__ == '__main__': unittest.main() diff --git a/utils/lit/lit/TclUtil.py b/utils/lit/lit/TclUtil.py deleted file mode 100644 index 4a3f34508d..0000000000 --- a/utils/lit/lit/TclUtil.py +++ /dev/null @@ -1,322 +0,0 @@ -import itertools - -from ShCommands import Command, Pipeline - -def tcl_preprocess(data): - # Tcl has a preprocessing step to replace escaped newlines. - i = data.find('\\\n') - if i == -1: - return data - - # Replace '\\\n' and subsequent whitespace by a single space. - n = len(data) - str = data[:i] - i += 2 - while i < n and data[i] in ' \t': - i += 1 - return str + ' ' + data[i:] - -class TclLexer: - """TclLexer - Lex a string into "words", following the Tcl syntax.""" - - def __init__(self, data): - self.data = tcl_preprocess(data) - self.pos = 0 - self.end = len(self.data) - - def at_end(self): - return self.pos == self.end - - def eat(self): - c = self.data[self.pos] - self.pos += 1 - return c - - def look(self): - return self.data[self.pos] - - def maybe_eat(self, c): - """ - maybe_eat(c) - Consume the character c if it is the next character, - returning True if a character was consumed. """ - if self.data[self.pos] == c: - self.pos += 1 - return True - return False - - def escape(self, c): - if c == 'a': - return '\x07' - elif c == 'b': - return '\x08' - elif c == 'f': - return '\x0c' - elif c == 'n': - return '\n' - elif c == 'r': - return '\r' - elif c == 't': - return '\t' - elif c == 'v': - return '\x0b' - elif c in 'uxo': - raise ValueError,'Invalid quoted character %r' % c - else: - return c - - def lex_braced(self): - # Lex until whitespace or end of string, the opening brace has already - # been consumed. - - str = '' - while 1: - if self.at_end(): - raise ValueError,"Unterminated '{' quoted word" - - c = self.eat() - if c == '}': - break - elif c == '{': - str += '{' + self.lex_braced() + '}' - elif c == '\\' and self.look() in '{}': - str += self.eat() - else: - str += c - - return str - - def lex_quoted(self): - str = '' - - while 1: - if self.at_end(): - raise ValueError,"Unterminated '\"' quoted word" - - c = self.eat() - if c == '"': - break - elif c == '\\': - if self.at_end(): - raise ValueError,'Missing quoted character' - - str += self.escape(self.eat()) - else: - str += c - - return str - - def lex_unquoted(self, process_all=False): - # Lex until whitespace or end of string. - str = '' - while not self.at_end(): - if not process_all: - if self.look().isspace() or self.look() == ';': - break - - c = self.eat() - if c == '\\': - if self.at_end(): - raise ValueError,'Missing quoted character' - - str += self.escape(self.eat()) - elif c == '[': - raise NotImplementedError, ('Command substitution is ' - 'not supported') - elif c == '$' and not self.at_end() and (self.look().isalpha() or - self.look() == '{'): - raise NotImplementedError, ('Variable substitution is ' - 'not supported') - else: - str += c - - return str - - def lex_one_token(self): - if self.maybe_eat('"'): - return self.lex_quoted() - elif self.maybe_eat('{'): - # Check for argument substitution. - if not self.maybe_eat('*'): - return self.lex_braced() - - if not self.maybe_eat('}'): - return '*' + self.lex_braced() - - if self.at_end() or self.look().isspace(): - return '*' - - raise NotImplementedError, "Argument substitution is unsupported" - else: - return self.lex_unquoted() - - def lex(self): - while not self.at_end(): - c = self.look() - if c in ' \t': - self.eat() - elif c in ';\n': - self.eat() - yield (';',) - else: - yield self.lex_one_token() - -class TclExecCommand: - kRedirectPrefixes1 = ('<', '>') - kRedirectPrefixes2 = ('<@', '<<', '2>', '>&', '>>', '>@') - kRedirectPrefixes3 = ('2>@', '2>>', '>>&', '>&@') - kRedirectPrefixes4 = ('2>@1',) - - def __init__(self, args): - self.args = iter(args) - - def lex(self): - try: - return self.args.next() - except StopIteration: - return None - - def look(self): - next = self.lex() - if next is not None: - self.args = itertools.chain([next], self.args) - return next - - def parse_redirect(self, tok, length): - if len(tok) == length: - arg = self.lex() - if arg is None: - raise ValueError,'Missing argument to %r redirection' % tok - else: - tok,arg = tok[:length],tok[length:] - - if tok[0] == '2': - op = (tok[1:],2) - else: - op = (tok,) - return (op, arg) - - def parse_pipeline(self): - if self.look() is None: - raise ValueError,"Expected at least one argument to exec" - - commands = [Command([],[])] - while 1: - arg = self.lex() - if arg is None: - break - elif arg == '|': - commands.append(Command([],[])) - elif arg == '|&': - # Write this as a redirect of stderr; it must come first because - # stdout may have already been redirected. - commands[-1].redirects.insert(0, (('>&',2),'1')) - commands.append(Command([],[])) - elif arg[:4] in TclExecCommand.kRedirectPrefixes4: - commands[-1].redirects.append(self.parse_redirect(arg, 4)) - elif arg[:3] in TclExecCommand.kRedirectPrefixes3: - commands[-1].redirects.append(self.parse_redirect(arg, 3)) - elif arg[:2] in TclExecCommand.kRedirectPrefixes2: - commands[-1].redirects.append(self.parse_redirect(arg, 2)) - elif arg[:1] in TclExecCommand.kRedirectPrefixes1: - commands[-1].redirects.append(self.parse_redirect(arg, 1)) - else: - commands[-1].args.append(arg) - - return Pipeline(commands, False, pipe_err=True) - - def parse(self): - ignoreStderr = False - keepNewline = False - - # Parse arguments. - while 1: - next = self.look() - if not isinstance(next, str) or next[0] != '-': - break - - if next == '--': - self.lex() - break - elif next == '-ignorestderr': - ignoreStderr = True - elif next == '-keepnewline': - keepNewline = True - else: - raise ValueError,"Invalid exec argument %r" % next - - return (ignoreStderr, keepNewline, self.parse_pipeline()) - -### - -import unittest - -class TestTclLexer(unittest.TestCase): - def lex(self, str, *args, **kwargs): - return list(TclLexer(str, *args, **kwargs).lex()) - - def test_preprocess(self): - self.assertEqual(tcl_preprocess('a b'), 'a b') - self.assertEqual(tcl_preprocess('a\\\nb c'), 'a b c') - - def test_unquoted(self): - self.assertEqual(self.lex('a b c'), - ['a', 'b', 'c']) - self.assertEqual(self.lex(r'a\nb\tc\ '), - ['a\nb\tc ']) - self.assertEqual(self.lex(r'a \\\$b c $\\'), - ['a', r'\$b', 'c', '$\\']) - - def test_braced(self): - self.assertEqual(self.lex('a {b c} {}'), - ['a', 'b c', '']) - self.assertEqual(self.lex(r'a {b {c\n}}'), - ['a', 'b {c\\n}']) - self.assertEqual(self.lex(r'a {b\{}'), - ['a', 'b{']) - self.assertEqual(self.lex(r'{*}'), ['*']) - self.assertEqual(self.lex(r'{*} a'), ['*', 'a']) - self.assertEqual(self.lex(r'{*} a'), ['*', 'a']) - self.assertEqual(self.lex('{a\\\n b}'), - ['a b']) - - def test_quoted(self): - self.assertEqual(self.lex('a "b c"'), - ['a', 'b c']) - - def test_terminators(self): - self.assertEqual(self.lex('a\nb'), - ['a', (';',), 'b']) - self.assertEqual(self.lex('a;b'), - ['a', (';',), 'b']) - self.assertEqual(self.lex('a ; b'), - ['a', (';',), 'b']) - -class TestTclExecCommand(unittest.TestCase): - def parse(self, str): - return TclExecCommand(list(TclLexer(str).lex())).parse() - - def test_basic(self): - self.assertEqual(self.parse('echo hello'), - (False, False, - Pipeline([Command(['echo', 'hello'], [])], - False, True))) - self.assertEqual(self.parse('echo hello | grep hello'), - (False, False, - Pipeline([Command(['echo', 'hello'], []), - Command(['grep', 'hello'], [])], - False, True))) - - def test_redirect(self): - self.assertEqual(self.parse('echo hello > a >b >>c 2> d |& e'), - (False, False, - Pipeline([Command(['echo', 'hello'], - [(('>&',2),'1'), - (('>',),'a'), - (('>',),'b'), - (('>>',),'c'), - (('>',2),'d')]), - Command(['e'], [])], - False, True))) - -if __name__ == '__main__': - unittest.main() diff --git a/utils/lit/lit/Test.py b/utils/lit/lit/Test.py index db2e032465..9471e3a98b 100644 --- a/utils/lit/lit/Test.py +++ b/utils/lit/lit/Test.py @@ -7,6 +7,10 @@ class TestResult: self.name = name self.isFailure = isFailure + def __repr__(self): + return '%s%r' % (self.__class__.__name__, + (self.name, self.isFailure)) + PASS = TestResult('PASS', False) XFAIL = TestResult('XFAIL', False) FAIL = TestResult('FAIL', True) diff --git a/utils/lit/lit/TestFormats.py b/utils/lit/lit/TestFormats.py index d1c0558b5f..a272976ca0 100644 --- a/utils/lit/lit/TestFormats.py +++ b/utils/lit/lit/TestFormats.py @@ -54,28 +54,36 @@ class GoogleTest(object): else: yield ''.join(nested_tests) + ln + def getTestsInExecutable(self, testSuite, path_in_suite, execpath, + litConfig, localConfig): + if not execpath.endswith(self.test_suffix): + return + (dirname, basename) = os.path.split(execpath) + # Discover the tests in this executable. + for testname in self.getGTestTests(execpath, litConfig, localConfig): + testPath = path_in_suite + (dirname, basename, testname) + yield Test.Test(testSuite, testPath, localConfig) + def getTestsInDirectory(self, testSuite, path_in_suite, litConfig, localConfig): source_path = testSuite.getSourcePath(path_in_suite) for filename in os.listdir(source_path): - # Check for the one subdirectory (build directory) tests will be in. - if not '.' in self.test_sub_dir: + filepath = os.path.join(source_path, filename) + if os.path.isdir(filepath): + # Iterate over executables in a directory. if not os.path.normcase(filename) in self.test_sub_dir: continue - - filepath = os.path.join(source_path, filename) - if not os.path.isdir(filepath): - continue - - for subfilename in os.listdir(filepath): - if subfilename.endswith(self.test_suffix): + for subfilename in os.listdir(filepath): execpath = os.path.join(filepath, subfilename) - - # Discover the tests in this executable. - for name in self.getGTestTests(execpath, litConfig, - localConfig): - testPath = path_in_suite + (filename, subfilename, name) - yield Test.Test(testSuite, testPath, localConfig) + for test in self.getTestsInExecutable( + testSuite, path_in_suite, execpath, + litConfig, localConfig): + yield test + elif ('.' in self.test_sub_dir): + for test in self.getTestsInExecutable( + testSuite, path_in_suite, filepath, + litConfig, localConfig): + yield test def execute(self, test, litConfig): testPath,testName = os.path.split(test.getSourcePath()) @@ -124,14 +132,6 @@ class ShTest(FileBasedTest): return TestRunner.executeShTest(test, litConfig, self.execute_external) -class TclTest(FileBasedTest): - def __init__(self, ignoreStdErr=False): - self.ignoreStdErr = ignoreStdErr - - def execute(self, test, litConfig): - litConfig.ignoreStdErr = self.ignoreStdErr - return TestRunner.executeTclTest(test, litConfig) - ### import re @@ -221,12 +221,3 @@ class OneCommandPerFileTest: report += """Output:\n--\n%s--""" % diags return Test.FAIL, report - -class SyntaxCheckTest(OneCommandPerFileTest): - def __init__(self, compiler, dir, extra_cxx_args=[], *args, **kwargs): - cmd = [compiler, '-x', 'c++', '-fsyntax-only'] + extra_cxx_args - OneCommandPerFileTest.__init__(self, cmd, dir, - useTempInput=1, *args, **kwargs) - - def createTempInput(self, tmp, test): - print >>tmp, '#include "%s"' % test.source_path diff --git a/utils/lit/lit/TestRunner.py b/utils/lit/lit/TestRunner.py index 75182b86fd..07fb43f840 100644 --- a/utils/lit/lit/TestRunner.py +++ b/utils/lit/lit/TestRunner.py @@ -49,13 +49,14 @@ def executeShCmd(cmd, cfg, cwd, results): return executeShCmd(cmd.rhs, cfg, cwd, results) if cmd.op == '&': - raise NotImplementedError,"unsupported test command: '&'" + raise InternalShellError(cmd,"unsupported shell operator: '&'") if cmd.op == '||': res = executeShCmd(cmd.lhs, cfg, cwd, results) if res != 0: res = executeShCmd(cmd.rhs, cfg, cwd, results) return res + if cmd.op == '&&': res = executeShCmd(cmd.lhs, cfg, cwd, results) if res is None: @@ -98,7 +99,7 @@ def executeShCmd(cmd, cfg, cwd, results): elif r[0] == ('<',): redirects[0] = [r[1], 'r', None] else: - raise NotImplementedError,"Unsupported redirect: %r" % (r,) + raise InternalShellError(j,"Unsupported redirect: %r" % (r,)) # Map from the final redirections to something subprocess can handle. final_redirects = [] @@ -107,14 +108,14 @@ def executeShCmd(cmd, cfg, cwd, results): result = input elif r == (1,): if index == 0: - raise NotImplementedError,"Unsupported redirect for stdin" + raise InternalShellError(j,"Unsupported redirect for stdin") elif index == 1: result = subprocess.PIPE else: result = subprocess.STDOUT elif r == (2,): if index != 2: - raise NotImplementedError,"Unsupported redirect on stdout" + raise InternalShellError(j,"Unsupported redirect on stdout") result = subprocess.PIPE else: if r[2] is None: @@ -256,9 +257,8 @@ def executeScriptInternal(test, litConfig, tmpBase, commands, cwd): try: exitCode = executeShCmd(cmd, test.config, cwd, results) except InternalShellError,e: - out = '' - err = e.message - exitCode = 255 + exitCode = 127 + results.append((e.command, '', e.message, exitCode)) out = err = '' for i,(cmd, cmd_out,cmd_err,res) in enumerate(results): @@ -269,82 +269,6 @@ def executeScriptInternal(test, litConfig, tmpBase, commands, cwd): return out, err, exitCode -def executeTclScriptInternal(test, litConfig, tmpBase, commands, cwd): - import TclUtil - cmds = [] - for ln in commands: - # Given the unfortunate way LLVM's test are written, the line gets - # backslash substitution done twice. - ln = TclUtil.TclLexer(ln).lex_unquoted(process_all = True) - - try: - tokens = list(TclUtil.TclLexer(ln).lex()) - except: - return (Test.FAIL, "Tcl lexer error on: %r" % ln) - - # Validate there are no control tokens. - for t in tokens: - if not isinstance(t, str): - return (Test.FAIL, - "Invalid test line: %r containing %r" % (ln, t)) - - try: - cmds.append(TclUtil.TclExecCommand(tokens).parse_pipeline()) - except: - return (Test.FAIL, "Tcl 'exec' parse error on: %r" % ln) - - if litConfig.useValgrind: - for pipeline in cmds: - if pipeline.commands: - # Only valgrind the first command in each pipeline, to avoid - # valgrinding things like grep, not, and FileCheck. - cmd = pipeline.commands[0] - cmd.args = litConfig.valgrindArgs + cmd.args - - cmd = cmds[0] - for c in cmds[1:]: - cmd = ShUtil.Seq(cmd, '&&', c) - - # FIXME: This is lame, we shouldn't need bash. See PR5240. - bashPath = litConfig.getBashPath() - if litConfig.useTclAsSh and bashPath: - script = tmpBase + '.script' - - # Write script file - f = open(script,'w') - print >>f, 'set -o pipefail' - cmd.toShell(f, pipefail = True) - f.close() - - if 0: - print >>sys.stdout, cmd - print >>sys.stdout, open(script).read() - print >>sys.stdout - return '', '', 0 - - command = [litConfig.getBashPath(), script] - out,err,exitCode = executeCommand(command, cwd=cwd, - env=test.config.environment) - - return out,err,exitCode - else: - results = [] - try: - exitCode = executeShCmd(cmd, test.config, cwd, results) - except InternalShellError,e: - results.append((e.command, '', e.message + '\n', 255)) - exitCode = 255 - - out = err = '' - - for i,(cmd, cmd_out, cmd_err, res) in enumerate(results): - out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args)) - out += 'Command %d Result: %r\n' % (i, res) - out += 'Command %d Output:\n%s\n\n' % (i, cmd_out) - out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err) - - return out, err, exitCode - def executeScript(test, litConfig, tmpBase, commands, cwd): bashPath = litConfig.getBashPath(); isWin32CMDEXE = (litConfig.isWindows and not bashPath) @@ -429,8 +353,6 @@ def parseIntegratedTestScript(test, normalize_slashes=False, ('%{pathsep}', os.pathsep), ('%t', tmpBase + '.tmp'), ('%T', tmpDir), - # FIXME: Remove this once we kill DejaGNU. - ('%abs_tmp', tmpBase + '.tmp'), ('#_MARKER_#', '%')]) # Collect the test lines from the script. @@ -506,17 +428,14 @@ def parseIntegratedTestScript(test, normalize_slashes=False, isXFail = isExpectedFail(test, xfails) return script,isXFail,tmpBase,execdir -def formatTestOutput(status, out, err, exitCode, failDueToStderr, script): +def formatTestOutput(status, out, err, exitCode, script): output = StringIO.StringIO() print >>output, "Script:" print >>output, "--" print >>output, '\n'.join(script) print >>output, "--" print >>output, "Exit Code: %r" % exitCode, - if failDueToStderr: - print >>output, "(but there was output on stderr)" - else: - print >>output + print >>output if out: print >>output, "Command Output (stdout):" print >>output, "--" @@ -529,53 +448,6 @@ def formatTestOutput(status, out, err, exitCode, failDueToStderr, script): print >>output, "--" return (status, output.getvalue()) -def executeTclTest(test, litConfig): - if test.config.unsupported: - return (Test.UNSUPPORTED, 'Test is unsupported') - - # Parse the test script, normalizing slashes in substitutions on Windows - # (since otherwise Tcl style lexing will treat them as escapes). - res = parseIntegratedTestScript(test, normalize_slashes=kIsWindows) - if len(res) == 2: - return res - - script, isXFail, tmpBase, execdir = res - - if litConfig.noExecute: - return (Test.PASS, '') - - # Create the output directory if it does not already exist. - Util.mkdir_p(os.path.dirname(tmpBase)) - - res = executeTclScriptInternal(test, litConfig, tmpBase, script, execdir) - if len(res) == 2: - return res - - # Test for failure. In addition to the exit code, Tcl commands are - # considered to fail if there is any standard error output. - out,err,exitCode = res - if isXFail: - ok = exitCode != 0 or err and not litConfig.ignoreStdErr - if ok: - status = Test.XFAIL - else: - status = Test.XPASS - else: - ok = exitCode == 0 and (not err or litConfig.ignoreStdErr) - if ok: - status = Test.PASS - else: - status = Test.FAIL - - if ok: - return (status,'') - - # Set a flag for formatTestOutput so it can explain why the test was - # considered to have failed, despite having an exit code of 0. - failDueToStderr = exitCode == 0 and err and not litConfig.ignoreStdErr - - return formatTestOutput(status, out, err, exitCode, failDueToStderr, script) - def executeShTest(test, litConfig, useExternalSh, extra_substitutions=[]): if test.config.unsupported: @@ -617,7 +489,4 @@ def executeShTest(test, litConfig, useExternalSh, if ok: return (status,'') - # Sh tests are not considered to fail just from stderr output. - failDueToStderr = False - - return formatTestOutput(status, out, err, exitCode, failDueToStderr, script) + return formatTestOutput(status, out, err, exitCode, script) diff --git a/utils/lit/lit/discovery.py b/utils/lit/lit/discovery.py new file mode 100644 index 0000000000..c869a671ef --- /dev/null +++ b/utils/lit/lit/discovery.py @@ -0,0 +1,234 @@ +""" +Test discovery functions. +""" + +import os +import sys + +from lit.TestingConfig import TestingConfig +from lit import LitConfig, Test + +def dirContainsTestSuite(path, lit_config): + cfgpath = os.path.join(path, lit_config.site_config_name) + if os.path.exists(cfgpath): + return cfgpath + cfgpath = os.path.join(path, lit_config.config_name) + if os.path.exists(cfgpath): + return cfgpath + +def getTestSuite(item, litConfig, cache): + """getTestSuite(item, litConfig, cache) -> (suite, relative_path) + + Find the test suite containing @arg item. + + @retval (None, ...) - Indicates no test suite contains @arg item. + @retval (suite, relative_path) - The suite that @arg item is in, and its + relative path inside that suite. + """ + def search1(path): + # Check for a site config or a lit config. + cfgpath = dirContainsTestSuite(path, litConfig) + + # If we didn't find a config file, keep looking. + if not cfgpath: + parent,base = os.path.split(path) + if parent == path: + return (None, ()) + + ts, relative = search(parent) + return (ts, relative + (base,)) + + # We found a config file, load it. + if litConfig.debug: + litConfig.note('loading suite config %r' % cfgpath) + + cfg = TestingConfig.frompath(cfgpath, None, litConfig, mustExist = True) + source_root = os.path.realpath(cfg.test_source_root or path) + exec_root = os.path.realpath(cfg.test_exec_root or path) + return Test.TestSuite(cfg.name, source_root, exec_root, cfg), () + + def search(path): + # Check for an already instantiated test suite. + res = cache.get(path) + if res is None: + cache[path] = res = search1(path) + return res + + # Canonicalize the path. + item = os.path.realpath(item) + + # Skip files and virtual components. + components = [] + while not os.path.isdir(item): + parent,base = os.path.split(item) + if parent == item: + return (None, ()) + components.append(base) + item = parent + components.reverse() + + ts, relative = search(item) + return ts, tuple(relative + tuple(components)) + +def getLocalConfig(ts, path_in_suite, litConfig, cache): + def search1(path_in_suite): + # Get the parent config. + if not path_in_suite: + parent = ts.config + else: + parent = search(path_in_suite[:-1]) + + # Load the local configuration. + source_path = ts.getSourcePath(path_in_suite) + cfgpath = os.path.join(source_path, litConfig.local_config_name) + if litConfig.debug: + litConfig.note('loading local config %r' % cfgpath) + return TestingConfig.frompath(cfgpath, parent, litConfig, + mustExist = False, + config = parent.clone(cfgpath)) + + def search(path_in_suite): + key = (ts, path_in_suite) + res = cache.get(key) + if res is None: + cache[key] = res = search1(path_in_suite) + return res + + return search(path_in_suite) + +def getTests(path, litConfig, testSuiteCache, localConfigCache): + # Find the test suite for this input and its relative path. + ts,path_in_suite = getTestSuite(path, litConfig, testSuiteCache) + if ts is None: + litConfig.warning('unable to find test suite for %r' % path) + return (),() + + if litConfig.debug: + litConfig.note('resolved input %r to %r::%r' % (path, ts.name, + path_in_suite)) + + return ts, getTestsInSuite(ts, path_in_suite, litConfig, + testSuiteCache, localConfigCache) + +def getTestsInSuite(ts, path_in_suite, litConfig, + testSuiteCache, localConfigCache): + # Check that the source path exists (errors here are reported by the + # caller). + source_path = ts.getSourcePath(path_in_suite) + if not os.path.exists(source_path): + return + + # Check if the user named a test directly. + if not os.path.isdir(source_path): + lc = getLocalConfig(ts, path_in_suite[:-1], litConfig, localConfigCache) + yield Test.Test(ts, path_in_suite, lc) + return + + # Otherwise we have a directory to search for tests, start by getting the + # local configuration. + lc = getLocalConfig(ts, path_in_suite, litConfig, localConfigCache) + + # Search for tests. + if lc.test_format is not None: + for res in lc.test_format.getTestsInDirectory(ts, path_in_suite, + litConfig, lc): + yield res + + # Search subdirectories. + for filename in os.listdir(source_path): + # FIXME: This doesn't belong here? + if filename in ('Output', '.svn') or filename in lc.excludes: + continue + + # Ignore non-directories. + file_sourcepath = os.path.join(source_path, filename) + if not os.path.isdir(file_sourcepath): + continue + + # Check for nested test suites, first in the execpath in case there is a + # site configuration and then in the source path. + file_execpath = ts.getExecPath(path_in_suite + (filename,)) + if dirContainsTestSuite(file_execpath, litConfig): + sub_ts, subiter = getTests(file_execpath, litConfig, + testSuiteCache, localConfigCache) + elif dirContainsTestSuite(file_sourcepath, litConfig): + sub_ts, subiter = getTests(file_sourcepath, litConfig, + testSuiteCache, localConfigCache) + else: + # Otherwise, continue loading from inside this test suite. + subiter = getTestsInSuite(ts, path_in_suite + (filename,), + litConfig, testSuiteCache, + localConfigCache) + sub_ts = None + + N = 0 + for res in subiter: + N += 1 + yield res + if sub_ts and not N: + litConfig.warning('test suite %r contained no tests' % sub_ts.name) + +def find_tests_for_inputs(lit_config, inputs): + """ + find_tests_for_inputs(lit_config, inputs) -> [Test] + + Given a configuration object and a list of input specifiers, find all the + tests to execute. + """ + + # Expand '@...' form in inputs. + actual_inputs = [] + for input in inputs: + if os.path.exists(input) or not input.startswith('@'): + actual_inputs.append(input) + else: + f = open(input[1:]) + try: + for ln in f: + ln = ln.strip() + if ln: + actual_inputs.append(ln) + finally: + f.close() + + # Load the tests from the inputs. + tests = [] + test_suite_cache = {} + local_config_cache = {} + for input in actual_inputs: + prev = len(tests) + tests.extend(getTests(input, lit_config, + test_suite_cache, local_config_cache)[1]) + if prev == len(tests): + lit_config.warning('input %r contained no tests' % input) + + # If there were any errors during test discovery, exit now. + if lit_config.numErrors: + print >>sys.stderr, '%d errors, exiting.' % lit_config.numErrors + sys.exit(2) + + return tests + +def load_test_suite(inputs): + import platform + import unittest + from lit.LitTestCase import LitTestCase + + # Create the global config object. + litConfig = LitConfig.LitConfig(progname = 'lit', + path = [], + quiet = False, + useValgrind = False, + valgrindLeakCheck = False, + valgrindArgs = [], + noExecute = False, + ignoreStdErr = False, + debug = False, + isWindows = (platform.system()=='Windows'), + params = {}) + + tests = find_tests_for_inputs(litConfig, inputs) + + # Return a unittest test suite which just runs the tests in order. + return unittest.TestSuite([LitTestCase(test, litConfig) for test in tests]) + diff --git a/utils/lit/lit/main.py b/utils/lit/lit/main.py index 25bbcbd9f2..da961eeedc 100755 --- a/utils/lit/lit/main.py +++ b/utils/lit/lit/main.py @@ -12,18 +12,10 @@ import ProgressBar import TestRunner import Util -from TestingConfig import TestingConfig import LitConfig import Test -# Configuration files to look for when discovering test suites. These can be -# overridden with --config-prefix. -# -# FIXME: Rename to 'config.lit', 'site.lit', and 'local.lit' ? -gConfigName = 'lit.cfg' -gSiteConfigName = 'lit.site.cfg' - -kLocalConfigName = 'lit.local.cfg' +import lit.discovery class TestingProgressDisplay: def __init__(self, opts, numTests, progressBar=None): @@ -137,166 +129,6 @@ class Tester(threading.Thread): test.setResult(result, output, elapsed) self.display.update(test) -def dirContainsTestSuite(path): - cfgpath = os.path.join(path, gSiteConfigName) - if os.path.exists(cfgpath): - return cfgpath - cfgpath = os.path.join(path, gConfigName) - if os.path.exists(cfgpath): - return cfgpath - -def getTestSuite(item, litConfig, cache): - """getTestSuite(item, litConfig, cache) -> (suite, relative_path) - - Find the test suite containing @arg item. - - @retval (None, ...) - Indicates no test suite contains @arg item. - @retval (suite, relative_path) - The suite that @arg item is in, and its - relative path inside that suite. - """ - def search1(path): - # Check for a site config or a lit config. - cfgpath = dirContainsTestSuite(path) - - # If we didn't find a config file, keep looking. - if not cfgpath: - parent,base = os.path.split(path) - if parent == path: - return (None, ()) - - ts, relative = search(parent) - return (ts, relative + (base,)) - - # We found a config file, load it. - if litConfig.debug: - litConfig.note('loading suite config %r' % cfgpath) - - cfg = TestingConfig.frompath(cfgpath, None, litConfig, mustExist = True) - source_root = os.path.realpath(cfg.test_source_root or path) - exec_root = os.path.realpath(cfg.test_exec_root or path) - return Test.TestSuite(cfg.name, source_root, exec_root, cfg), () - - def search(path): - # Check for an already instantiated test suite. - res = cache.get(path) - if res is None: - cache[path] = res = search1(path) - return res - - # Canonicalize the path. - item = os.path.realpath(item) - - # Skip files and virtual components. - components = [] - while not os.path.isdir(item): - parent,base = os.path.split(item) - if parent == item: - return (None, ()) - components.append(base) - item = parent - components.reverse() - - ts, relative = search(item) - return ts, tuple(relative + tuple(components)) - -def getLocalConfig(ts, path_in_suite, litConfig, cache): - def search1(path_in_suite): - # Get the parent config. - if not path_in_suite: - parent = ts.config - else: - parent = search(path_in_suite[:-1]) - - # Load the local configuration. - source_path = ts.getSourcePath(path_in_suite) - cfgpath = os.path.join(source_path, kLocalConfigName) - if litConfig.debug: - litConfig.note('loading local config %r' % cfgpath) - return TestingConfig.frompath(cfgpath, parent, litConfig, - mustExist = False, - config = parent.clone(cfgpath)) - - def search(path_in_suite): - key = (ts, path_in_suite) - res = cache.get(key) - if res is None: - cache[key] = res = search1(path_in_suite) - return res - - return search(path_in_suite) - -def getTests(path, litConfig, testSuiteCache, localConfigCache): - # Find the test suite for this input and its relative path. - ts,path_in_suite = getTestSuite(path, litConfig, testSuiteCache) - if ts is None: - litConfig.warning('unable to find test suite for %r' % path) - return (),() - - if litConfig.debug: - litConfig.note('resolved input %r to %r::%r' % (path, ts.name, - path_in_suite)) - - return ts, getTestsInSuite(ts, path_in_suite, litConfig, - testSuiteCache, localConfigCache) - -def getTestsInSuite(ts, path_in_suite, litConfig, - testSuiteCache, localConfigCache): - # Check that the source path exists (errors here are reported by the - # caller). - source_path = ts.getSourcePath(path_in_suite) - if not os.path.exists(source_path): - return - - # Check if the user named a test directly. - if not os.path.isdir(source_path): - lc = getLocalConfig(ts, path_in_suite[:-1], litConfig, localConfigCache) - yield Test.Test(ts, path_in_suite, lc) - return - - # Otherwise we have a directory to search for tests, start by getting the - # local configuration. - lc = getLocalConfig(ts, path_in_suite, litConfig, localConfigCache) - - # Search for tests. - if lc.test_format is not None: - for res in lc.test_format.getTestsInDirectory(ts, path_in_suite, - litConfig, lc): - yield res - - # Search subdirectories. - for filename in os.listdir(source_path): - # FIXME: This doesn't belong here? - if filename in ('Output', '.svn') or filename in lc.excludes: - continue - - # Ignore non-directories. - file_sourcepath = os.path.join(source_path, filename) - if not os.path.isdir(file_sourcepath): - continue - - # Check for nested test suites, first in the execpath in case there is a - # site configuration and then in the source path. - file_execpath = ts.getExecPath(path_in_suite + (filename,)) - if dirContainsTestSuite(file_execpath): - sub_ts, subiter = getTests(file_execpath, litConfig, - testSuiteCache, localConfigCache) - elif dirContainsTestSuite(file_sourcepath): - sub_ts, subiter = getTests(file_sourcepath, litConfig, - testSuiteCache, localConfigCache) - else: - # Otherwise, continue loading from inside this test suite. - subiter = getTestsInSuite(ts, path_in_suite + (filename,), - litConfig, testSuiteCache, - localConfigCache) - sub_ts = None - - N = 0 - for res in subiter: - N += 1 - yield res - if sub_ts and not N: - litConfig.warning('test suite %r contained no tests' % sub_ts.name) - def runTests(numThreads, litConfig, provider, display): # If only using one testing thread, don't use threads at all; this lets us # profile, among other things. @@ -316,50 +148,8 @@ def runTests(numThreads, litConfig, provider, display): except KeyboardInterrupt: sys.exit(2) -def load_test_suite(inputs): - import unittest - - # Create the global config object. - litConfig = LitConfig.LitConfig(progname = 'lit', - path = [], - quiet = False, - useValgrind = False, - valgrindLeakCheck = False, - valgrindArgs = [], - useTclAsSh = False, - noExecute = False, - ignoreStdErr = False, - debug = False, - isWindows = (platform.system()=='Windows'), - params = {}) - - # Load the tests from the inputs. - tests = [] - testSuiteCache = {} - localConfigCache = {} - for input in inputs: - prev = len(tests) - tests.extend(getTests(input, litConfig, - testSuiteCache, localConfigCache)[1]) - if prev == len(tests): - litConfig.warning('input %r contained no tests' % input) - - # If there were any errors during test discovery, exit now. - if litConfig.numErrors: - print >>sys.stderr, '%d errors, exiting.' % litConfig.numErrors - sys.exit(2) - - # Return a unittest test suite which just runs the tests in order. - def get_test_fn(test): - return unittest.FunctionTestCase( - lambda: test.config.test_format.execute( - test, litConfig), - description = test.getFullName()) - - from LitTestCase import LitTestCase - return unittest.TestSuite([LitTestCase(test, litConfig) for test in tests]) - -def main(builtinParameters = {}): # Bump the GIL check interval, its more important to get any one thread to a +def main(builtinParameters = {}): + # Bump the GIL check interval, its more important to get any one thread to a # blocking operation (hopefully exec) than to try and unblock other threads. # # FIXME: This is a hack. @@ -442,9 +232,6 @@ def main(builtinParameters = {}): # Bump the GIL check interval, its more imp group.add_option("", "--show-suites", dest="showSuites", help="Show discovered test suites", action="store_true", default=False) - group.add_option("", "--no-tcl-as-sh", dest="useTclAsSh", - help="Don't run Tcl scripts using 'sh'", - action="store_false", default=True) group.add_option("", "--repeat", dest="repeatTests", metavar="N", help="Repeat tests N times (for timing)", action="store", default=None, type=int) @@ -455,12 +242,6 @@ def main(builtinParameters = {}): # Bump the GIL check interval, its more imp if not args: parser.error('No inputs specified') - if opts.configPrefix is not None: - global gConfigName, gSiteConfigName, kLocalConfigName - gConfigName = '%s.cfg' % opts.configPrefix - gSiteConfigName = '%s.site.cfg' % opts.configPrefix - kLocalConfigName = '%s.local.cfg' % opts.configPrefix - if opts.numThreads is None: # Python <2.5 has a race condition causing lit to always fail with numThreads>1 # http://bugs.python.org/issue1731717 @@ -489,50 +270,20 @@ def main(builtinParameters = {}): # Bump the GIL check interval, its more imp useValgrind = opts.useValgrind, valgrindLeakCheck = opts.valgrindLeakCheck, valgrindArgs = opts.valgrindArgs, - useTclAsSh = opts.useTclAsSh, noExecute = opts.noExecute, ignoreStdErr = False, debug = opts.debug, isWindows = (platform.system()=='Windows'), - params = userParams) + params = userParams, + config_prefix = opts.configPrefix) - # Expand '@...' form in inputs. - actual_inputs = [] - for input in inputs: - if os.path.exists(input) or not input.startswith('@'): - actual_inputs.append(input) - else: - f = open(input[1:]) - try: - for ln in f: - ln = ln.strip() - if ln: - actual_inputs.append(ln) - finally: - f.close() - - - # Load the tests from the inputs. - tests = [] - testSuiteCache = {} - localConfigCache = {} - for input in actual_inputs: - prev = len(tests) - tests.extend(getTests(input, litConfig, - testSuiteCache, localConfigCache)[1]) - if prev == len(tests): - litConfig.warning('input %r contained no tests' % input) - - # If there were any errors during test discovery, exit now. - if litConfig.numErrors: - print >>sys.stderr, '%d errors, exiting.' % litConfig.numErrors - sys.exit(2) + tests = lit.discovery.find_tests_for_inputs(litConfig, inputs) if opts.showSuites: - suitesAndTests = dict([(ts,[]) - for ts,_ in testSuiteCache.values() - if ts]) + suitesAndTests = {} for t in tests: + if t.suite not in suitesAndTests: + suitesAndTests[t.suite] = [] suitesAndTests[t.suite].append(t) print '-- Test Suites --' diff --git a/utils/lit/tests/.coveragerc b/utils/lit/tests/.coveragerc new file mode 100644 index 0000000000..c886d0ac1a --- /dev/null +++ b/utils/lit/tests/.coveragerc @@ -0,0 +1,11 @@ +# .coveragerc to control coverage.py +[run] +branch = False +parallel = True +source = lit + +[html] +directory = coverage_html_report + +[report] +omit = Inputs diff --git a/utils/lit/tests/Inputs/discovery/lit.cfg b/utils/lit/tests/Inputs/discovery/lit.cfg new file mode 100644 index 0000000000..3513bfffd1 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/lit.cfg @@ -0,0 +1,5 @@ +config.name = 'top-level-suite' +config.suffixes = ['.txt'] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None diff --git a/utils/lit/tests/Inputs/discovery/subdir/lit.local.cfg b/utils/lit/tests/Inputs/discovery/subdir/lit.local.cfg new file mode 100644 index 0000000000..5ae6b3cd01 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/subdir/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.py'] diff --git a/utils/lit/tests/Inputs/discovery/subdir/test-three.py b/utils/lit/tests/Inputs/discovery/subdir/test-three.py new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/subdir/test-three.py @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/discovery/subsuite/lit.cfg b/utils/lit/tests/Inputs/discovery/subsuite/lit.cfg new file mode 100644 index 0000000000..0c2979d74a --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/subsuite/lit.cfg @@ -0,0 +1,5 @@ +config.name = 'sub-suite' +config.suffixes = ['.txt'] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None diff --git a/utils/lit/tests/Inputs/discovery/subsuite/test-one.txt b/utils/lit/tests/Inputs/discovery/subsuite/test-one.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/subsuite/test-one.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/discovery/subsuite/test-two.txt b/utils/lit/tests/Inputs/discovery/subsuite/test-two.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/subsuite/test-two.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/discovery/test-one.txt b/utils/lit/tests/Inputs/discovery/test-one.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/test-one.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/discovery/test-two.txt b/utils/lit/tests/Inputs/discovery/test-two.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/discovery/test-two.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/shtest-format/external_shell/fail.txt b/utils/lit/tests/Inputs/shtest-format/external_shell/fail.txt new file mode 100644 index 0000000000..1e74be5dbd --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/external_shell/fail.txt @@ -0,0 +1,3 @@ +# Run a command that fails with error on stdout. +# +# RUN: cat "does-not-exist" diff --git a/utils/lit/tests/Inputs/shtest-format/external_shell/lit.local.cfg b/utils/lit/tests/Inputs/shtest-format/external_shell/lit.local.cfg new file mode 100644 index 0000000000..d14d147977 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/external_shell/lit.local.cfg @@ -0,0 +1 @@ +config.test_format = lit.formats.ShTest(execute_external=True) diff --git a/utils/lit/tests/Inputs/shtest-format/external_shell/pass.txt b/utils/lit/tests/Inputs/shtest-format/external_shell/pass.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/external_shell/pass.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/shtest-format/fail.txt b/utils/lit/tests/Inputs/shtest-format/fail.txt new file mode 100644 index 0000000000..49932c3006 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/fail.txt @@ -0,0 +1 @@ +# RUN: false diff --git a/utils/lit/tests/Inputs/shtest-format/lit.cfg b/utils/lit/tests/Inputs/shtest-format/lit.cfg new file mode 100644 index 0000000000..78dd1bfb2e --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/lit.cfg @@ -0,0 +1,7 @@ +config.name = 'shtest-format' +config.suffixes = ['.txt'] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None +config.target_triple = 'x86_64-unknown-unknown' +config.available_features.add('a-present-feature') diff --git a/utils/lit/tests/Inputs/shtest-format/no-test-line.txt b/utils/lit/tests/Inputs/shtest-format/no-test-line.txt new file mode 100644 index 0000000000..f2316bd73a --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/no-test-line.txt @@ -0,0 +1 @@ +# Empty! diff --git a/utils/lit/tests/Inputs/shtest-format/pass.txt b/utils/lit/tests/Inputs/shtest-format/pass.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/pass.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/shtest-format/requires-missing.txt b/utils/lit/tests/Inputs/shtest-format/requires-missing.txt new file mode 100644 index 0000000000..9e6648d8b8 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/requires-missing.txt @@ -0,0 +1,2 @@ +RUN: true +REQUIRES: a-missing-feature diff --git a/utils/lit/tests/Inputs/shtest-format/requires-present.txt b/utils/lit/tests/Inputs/shtest-format/requires-present.txt new file mode 100644 index 0000000000..064f7074a7 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/requires-present.txt @@ -0,0 +1,2 @@ +RUN: true +REQUIRES: a-present-feature diff --git a/utils/lit/tests/Inputs/shtest-format/unsupported_dir/lit.local.cfg b/utils/lit/tests/Inputs/shtest-format/unsupported_dir/lit.local.cfg new file mode 100644 index 0000000000..462e3dc5d1 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/unsupported_dir/lit.local.cfg @@ -0,0 +1 @@ +config.unsupported = True diff --git a/utils/lit/tests/Inputs/shtest-format/unsupported_dir/some-test.txt b/utils/lit/tests/Inputs/shtest-format/unsupported_dir/some-test.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/unsupported_dir/some-test.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/shtest-format/xfail-feature.txt b/utils/lit/tests/Inputs/shtest-format/xfail-feature.txt new file mode 100644 index 0000000000..bd6241f8e4 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/xfail-feature.txt @@ -0,0 +1,2 @@ +# RUN: false +# XFAIL: a-present-feature diff --git a/utils/lit/tests/Inputs/shtest-format/xfail-target.txt b/utils/lit/tests/Inputs/shtest-format/xfail-target.txt new file mode 100644 index 0000000000..36760bee43 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/xfail-target.txt @@ -0,0 +1,2 @@ +RUN: false +XFAIL: x86_64 diff --git a/utils/lit/tests/Inputs/shtest-format/xfail.txt b/utils/lit/tests/Inputs/shtest-format/xfail.txt new file mode 100644 index 0000000000..6814cda401 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/xfail.txt @@ -0,0 +1,2 @@ +RUN: false +XFAIL: * diff --git a/utils/lit/tests/Inputs/shtest-format/xpass.txt b/utils/lit/tests/Inputs/shtest-format/xpass.txt new file mode 100644 index 0000000000..764d21798b --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-format/xpass.txt @@ -0,0 +1,2 @@ +RUN: true +XFAIL: x86_64 diff --git a/utils/lit/tests/Inputs/shtest-shell/error-0.txt b/utils/lit/tests/Inputs/shtest-shell/error-0.txt new file mode 100644 index 0000000000..631c8df233 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/error-0.txt @@ -0,0 +1,3 @@ +# Check error on an internal shell error (unable to find command). +# +# RUN: not-a-real-command diff --git a/utils/lit/tests/Inputs/shtest-shell/error-1.txt b/utils/lit/tests/Inputs/shtest-shell/error-1.txt new file mode 100644 index 0000000000..e5c8be6b66 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/error-1.txt @@ -0,0 +1,3 @@ +# Check error on a shell parsing failure. +# +# RUN: echo "missing quote diff --git a/utils/lit/tests/Inputs/shtest-shell/error-2.txt b/utils/lit/tests/Inputs/shtest-shell/error-2.txt new file mode 100644 index 0000000000..a976286bdd --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/error-2.txt @@ -0,0 +1,3 @@ +# Check error on a unsupported redirect. +# +# RUN: echo "hello" 3>&1 diff --git a/utils/lit/tests/Inputs/shtest-shell/lit.cfg b/utils/lit/tests/Inputs/shtest-shell/lit.cfg new file mode 100644 index 0000000000..4878b65609 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/lit.cfg @@ -0,0 +1,5 @@ +config.name = 'shtest-shell' +config.suffixes = ['.txt'] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None diff --git a/utils/lit/tests/Inputs/shtest-shell/redirects.txt b/utils/lit/tests/Inputs/shtest-shell/redirects.txt new file mode 100644 index 0000000000..6be88b67ce --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/redirects.txt @@ -0,0 +1,41 @@ +# Check stdout redirect (> and >>). +# +# RUN: echo "not-present" > %t.stdout-write +# RUN: echo "is-present" > %t.stdout-write +# RUN: FileCheck --check-prefix=STDOUT-WRITE < %t.stdout-write %s +# +# STDOUT-WRITE-NOT: not-present +# STDOUT-WRITE: is-present +# +# RUN: echo "appended-line" >> %t.stdout-write +# RUN: FileCheck --check-prefix=STDOUT-APPEND < %t.stdout-write %s +# +# STDOUT-APPEND: is-present +# STDOUT-APPEND: appended-line + + +# Check stderr redirect (2> and 2>>). +# +# RUN: echo "not-present" > %t.stderr-write +# RUN: %S/write-to-stderr.sh 2> %t.stderr-write +# RUN: FileCheck --check-prefix=STDERR-WRITE < %t.stderr-write %s +# +# STDERR-WRITE-NOT: not-present +# STDERR-WRITE: a line on stderr +# +# RUN: %S/write-to-stderr.sh 2>> %t.stderr-write +# RUN: FileCheck --check-prefix=STDERR-APPEND < %t.stderr-write %s +# +# STDERR-APPEND: a line on stderr +# STDERR-APPEND: a line on stderr + + +# Check combined redirect (&>). +# +# RUN: echo "not-present" > %t.combined +# RUN: %S/write-to-stdout-and-stderr.sh &> %t.combined +# RUN: FileCheck --check-prefix=COMBINED-WRITE < %t.combined %s +# +# COMBINED-WRITE-NOT: not-present +# COMBINED-WRITE: a line on stdout +# COMBINED-WRITE: a line on stderr diff --git a/utils/lit/tests/Inputs/shtest-shell/sequencing-0.txt b/utils/lit/tests/Inputs/shtest-shell/sequencing-0.txt new file mode 100644 index 0000000000..6578db25af --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/sequencing-0.txt @@ -0,0 +1,28 @@ +# Check sequencing operations. +# +# RUN: echo "first-line" > %t.out && echo "second-line" >> %t.out +# RUN: FileCheck --check-prefix CHECK-AND < %t.out %s +# +# CHECK-AND: first-line +# CHECK-AND: second-line +# +# The false case of && is tested in sequencing-2.txt + + +# RUN: echo "first-line" > %t.out || echo "second-line" >> %t.out +# RUN: FileCheck --check-prefix CHECK-OR-1 < %t.out %s +# +# CHECK-OR-1: first-line +# CHECK-OR-1-NOT: second-line + +# RUN: false || echo "second-line" > %t.out +# RUN: FileCheck --check-prefix CHECK-OR-2 < %t.out %s +# +# CHECK-OR-2: second-line + + +# RUN: echo "first-line" > %t.out; echo "second-line" >> %t.out +# RUN: FileCheck --check-prefix CHECK-SEQ < %t.out %s +# +# CHECK-SEQ: first-line +# CHECK-SEQ: second-line diff --git a/utils/lit/tests/Inputs/shtest-shell/sequencing-1.txt b/utils/lit/tests/Inputs/shtest-shell/sequencing-1.txt new file mode 100644 index 0000000000..5a1794c26c --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/sequencing-1.txt @@ -0,0 +1,2 @@ +# RUN: false && true +# XFAIL: * diff --git a/utils/lit/tests/Inputs/shtest-shell/write-to-stderr.sh b/utils/lit/tests/Inputs/shtest-shell/write-to-stderr.sh new file mode 100755 index 0000000000..ead3fd3ce3 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/write-to-stderr.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "a line on stderr" 1>&2 diff --git a/utils/lit/tests/Inputs/shtest-shell/write-to-stdout-and-stderr.sh b/utils/lit/tests/Inputs/shtest-shell/write-to-stdout-and-stderr.sh new file mode 100755 index 0000000000..f20de5d904 --- /dev/null +++ b/utils/lit/tests/Inputs/shtest-shell/write-to-stdout-and-stderr.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +echo "a line on stdout" +echo "a line on stderr" 1>&2 diff --git a/utils/lit/tests/Inputs/unittest-adaptor/lit.cfg b/utils/lit/tests/Inputs/unittest-adaptor/lit.cfg new file mode 100644 index 0000000000..52de709662 --- /dev/null +++ b/utils/lit/tests/Inputs/unittest-adaptor/lit.cfg @@ -0,0 +1,5 @@ +config.name = 'unittest-adaptor' +config.suffixes = ['.txt'] +config.test_format = lit.formats.ShTest() +config.test_source_root = None +config.test_exec_root = None diff --git a/utils/lit/tests/Inputs/unittest-adaptor/test-one.txt b/utils/lit/tests/Inputs/unittest-adaptor/test-one.txt new file mode 100644 index 0000000000..b80b60b7a2 --- /dev/null +++ b/utils/lit/tests/Inputs/unittest-adaptor/test-one.txt @@ -0,0 +1 @@ +# RUN: true diff --git a/utils/lit/tests/Inputs/unittest-adaptor/test-two.txt b/utils/lit/tests/Inputs/unittest-adaptor/test-two.txt new file mode 100644 index 0000000000..49932c3006 --- /dev/null +++ b/utils/lit/tests/Inputs/unittest-adaptor/test-two.txt @@ -0,0 +1 @@ +# RUN: false diff --git a/utils/lit/tests/discovery.py b/utils/lit/tests/discovery.py new file mode 100644 index 0000000000..54b99d3945 --- /dev/null +++ b/utils/lit/tests/discovery.py @@ -0,0 +1,25 @@ +# Check the basic discovery process, including a sub-suite. +# +# RUN: %{lit} %{inputs}/discovery \ +# RUN: -j 1 --debug --no-execute --show-suites -v > %t.out 2> %t.err +# RUN: FileCheck --check-prefix=CHECK-BASIC-OUT < %t.out %s +# RUN: FileCheck --check-prefix=CHECK-BASIC-ERR < %t.err %s +# +# CHECK-BASIC-ERR: loading suite config '{{.*}}/tests/Inputs/discovery/lit.cfg' +# CHECK-BASIC-ERR: loading local config '{{.*}}/tests/Inputs/discovery/subdir/lit.local.cfg' +# CHECK-BASIC-ERR: loading suite config '{{.*}}/tests/Inputs/discovery/subsuite/lit.cfg' +# +# CHECK-BASIC-OUT: -- Test Suites -- +# CHECK-BASIC-OUT: sub-suite - 2 tests +# CHECK-BASIC-OUT: Source Root: +# CHECK-BASIC-OUT: Exec Root : +# CHECK-BASIC-OUT: top-level-suite - 3 tests +# CHECK-BASIC-OUT: Source Root: +# CHECK-BASIC-OUT: Exec Root : +# +# CHECK-BASIC-OUT: -- Testing: 5 tests, 1 threads -- +# CHECK-BASIC-OUT: PASS: sub-suite :: test-one +# CHECK-BASIC-OUT: PASS: sub-suite :: test-two +# CHECK-BASIC-OUT: PASS: top-level-suite :: subdir/test-three +# CHECK-BASIC-OUT: PASS: top-level-suite :: test-one +# CHECK-BASIC-OUT: PASS: top-level-suite :: test-two diff --git a/utils/lit/tests/lit.cfg b/utils/lit/tests/lit.cfg new file mode 100644 index 0000000000..32760ceb27 --- /dev/null +++ b/utils/lit/tests/lit.cfg @@ -0,0 +1,36 @@ +# -*- Python -*- + +import os + +# Configuration file for the 'lit' test runner. + +# name: The name of this test suite. +config.name = 'lit' + +# testFormat: The test format to use to interpret tests. +config.test_format = lit.formats.ShTest(execute_external=False) + +# suffixes: A list of file extensions to treat as test files. +config.suffixes = ['.py'] + +# excludes: A list of individual files to exclude. +config.excludes = ['Inputs'] + +# test_source_root: The root path where tests are located. +config.test_source_root = os.path.dirname(__file__) +config.test_exec_root = config.test_source_root + +config.target_triple = None + +src_root = os.path.join(config.test_source_root, '..') +config.environment['PYTHONPATH'] = src_root +config.substitutions.append(('%{src_root}', src_root)) +config.substitutions.append(('%{inputs}', os.path.join( + src_root, 'tests', 'Inputs'))) +config.substitutions.append(('%{lit}', os.path.join(src_root, 'lit.py'))) + +# Enable coverage.py reporting, assuming the coverage module has been installed +# and sitecustomize.py in the virtualenv has been modified appropriately. +if lit.params.get('check-coverage', None): + config.environment['COVERAGE_PROCESS_START'] = os.path.join( + os.path.dirname(__file__), ".coveragerc") diff --git a/utils/lit/tests/shell-parsing.py b/utils/lit/tests/shell-parsing.py new file mode 100644 index 0000000000..f644132f29 --- /dev/null +++ b/utils/lit/tests/shell-parsing.py @@ -0,0 +1,3 @@ +# Just run the ShUtil unit tests. +# +# RUN: python -m lit.ShUtil diff --git a/utils/lit/tests/shtest-format.py b/utils/lit/tests/shtest-format.py new file mode 100644 index 0000000000..4b36873a3d --- /dev/null +++ b/utils/lit/tests/shtest-format.py @@ -0,0 +1,43 @@ +# Check the various features of the ShTest format. +# +# RUN: not %{lit} -j 1 -v %{inputs}/shtest-format > %t.out +# RUN: FileCheck < %t.out %s +# +# END. + +# CHECK: -- Testing: + +# CHECK: FAIL: shtest-format :: external_shell/fail.txt +# CHECK: *** TEST 'shtest-format :: external_shell/fail.txt' FAILED *** +# CHECK: Command Output (stderr): +# CHECK: cat: does-not-exist: No such file or directory +# CHECK: -- + +# CHECK: PASS: shtest-format :: external_shell/pass.txt + +# CHECK: FAIL: shtest-format :: fail.txt + +# CHECK: UNRESOLVED: shtest-format :: no-test-line.txt +# CHECK: PASS: shtest-format :: pass.txt +# CHECK: UNSUPPORTED: shtest-format :: requires-missing.txt +# CHECK: PASS: shtest-format :: requires-present.txt +# CHECK: UNSUPPORTED: shtest-format :: unsupported_dir/some-test.txt +# CHECK: XFAIL: shtest-format :: xfail-feature.txt +# CHECK: XFAIL: shtest-format :: xfail-target.txt +# CHECK: XFAIL: shtest-format :: xfail.txt +# CHECK: XPASS: shtest-format :: xpass.txt +# CHECK: Testing Time + +# CHECK: Unexpected Passing Tests (1) +# CHECK: shtest-format :: xpass.txt + +# CHECK: Failing Tests (2) +# CHECK: shtest-format :: external_shell/fail.txt +# CHECK: shtest-format :: fail.txt + +# CHECK: Expected Passes : 3 +# CHECK: Expected Failures : 3 +# CHECK: Unsupported Tests : 2 +# CHECK: Unresolved Tests : 1 +# CHECK: Unexpected Passes : 1 +# CHECK: Unexpected Failures: 2 diff --git a/utils/lit/tests/shtest-shell.py b/utils/lit/tests/shtest-shell.py new file mode 100644 index 0000000000..32479e19a1 --- /dev/null +++ b/utils/lit/tests/shtest-shell.py @@ -0,0 +1,33 @@ +# Check the internal shell handling component of the ShTest format. +# +# RUN: not %{lit} -j 1 -v %{inputs}/shtest-shell > %t.out +# RUN: FileCheck < %t.out %s +# +# END. + +# CHECK: -- Testing: + +# CHECK: FAIL: shtest-shell :: error-0.txt +# CHECK: *** TEST 'shtest-shell :: error-0.txt' FAILED *** +# CHECK: Command 0: "not-a-real-command" +# CHECK: Command 0 Result: 127 +# CHECK: Command 0 Stderr: +# CHECK: 'not-a-real-command': command not found +# CHECK: *** + +# FIXME: The output here sucks. +# +# CHECK: FAIL: shtest-shell :: error-1.txt +# CHECK: *** TEST 'shtest-shell :: error-1.txt' FAILED *** +# CHECK: shell parser error on: 'echo "missing quote' +# CHECK: *** + +# CHECK: FAIL: shtest-shell :: error-2.txt +# CHECK: *** TEST 'shtest-shell :: error-2.txt' FAILED *** +# CHECK: Unsupported redirect: +# CHECK: *** + +# CHECK: PASS: shtest-shell :: redirects.txt +# CHECK: PASS: shtest-shell :: sequencing-0.txt +# CHECK: XFAIL: shtest-shell :: sequencing-1.txt +# CHECK: Failing Tests (3) diff --git a/utils/lit/tests/unittest-adaptor.py b/utils/lit/tests/unittest-adaptor.py new file mode 100644 index 0000000000..243dd4191d --- /dev/null +++ b/utils/lit/tests/unittest-adaptor.py @@ -0,0 +1,18 @@ +# Check the lit adaption to run under unittest. +# +# RUN: python %s %{inputs}/unittest-adaptor 2> %t.err +# RUN: FileCheck < %t.err %s +# +# CHECK: unittest-adaptor :: test-one.txt ... ok +# CHECK: unittest-adaptor :: test-two.txt ... FAIL + +import unittest +import sys + +import lit +import lit.discovery + +input_path = sys.argv[1] +unittest_suite = lit.discovery.load_test_suite([input_path]) +runner = unittest.TextTestRunner(verbosity=2) +runner.run(unittest_suite) diff --git a/utils/lit/tests/usage.py b/utils/lit/tests/usage.py new file mode 100644 index 0000000000..e10d6134a0 --- /dev/null +++ b/utils/lit/tests/usage.py @@ -0,0 +1,6 @@ +# Basic sanity check that usage works. +# +# RUN: %{lit} --help > %t.out +# RUN: FileCheck < %t.out %s +# +# CHECK: Usage: lit.py [options] {file-or-path} diff --git a/utils/lit/utils/README.txt b/utils/lit/utils/README.txt new file mode 100644 index 0000000000..81862ba099 --- /dev/null +++ b/utils/lit/utils/README.txt @@ -0,0 +1,2 @@ +Utilities for the project that aren't intended to be part of a source +distribution. diff --git a/utils/lit/utils/check-coverage b/utils/lit/utils/check-coverage new file mode 100755 index 0000000000..bb3d17e757 --- /dev/null +++ b/utils/lit/utils/check-coverage @@ -0,0 +1,50 @@ +#!/bin/sh + +prog=$(basename $0) + +# Expect to be run from the parent lit directory. +if [ ! -f setup.py ] || [ ! -d lit ]; then + printf 1>&2 "%s: expected to be run from base lit directory\n" "$prog" + exit 1 +fi + +# Parse command line arguments. +if [ "$1" == "--generate-html" ]; then + GENERATE_HTML=1 + shift +fi + +# If invoked with no arguments, run all the tests. +if [ $# == "0" ]; then + set -- "tests" +fi + +# Check that the active python has been modified to enable coverage in its +# sitecustomize. +if ! python -c \ + 'import sitecustomize, sys; sys.exit("coverage" not in dir(sitecustomize))' \ + &> /dev/null; then + printf 1>&2 "error: active python does not appear to enable coverage in its 'sitecustomize.py'\n" + exit 1 +fi + +# First, remove any existing coverage data files. +rm -f tests/.coverage +find tests -name .coverage.\* -exec rm {} \; + +# Next, run the tests. +lit -sv --param check-coverage=1 "$@" + +# Next, move all the data files from subdirectories up. +find tests/* -name .coverage.\* -exec mv {} tests \; + +# Combine all the data files. +(cd tests && python -m coverage combine) + +# Finally, generate the report. +(cd tests && python -m coverage report) + +# Generate the HTML report, if requested. +if [ ! -z "$GENERATE_HTML" ]; then + (cd tests && python -m coverage html) +fi diff --git a/utils/lit/utils/check-sdist b/utils/lit/utils/check-sdist new file mode 100755 index 0000000000..6186446aba --- /dev/null +++ b/utils/lit/utils/check-sdist @@ -0,0 +1,44 @@ +#!/bin/sh + +if [ $# == 1 ]; then + cd $1 +fi + +# Create a list of all the files in the source tree, excluding various things we +# know don't belong. +echo "Creating current directory contents list." +find . | \ + grep -v '^\./.gitignore' | \ + grep -v '^\./dist' | \ + grep -v '^\./utils' | \ + grep -v '^\./venv' | \ + grep -v '^\./lit.egg-info' | \ + grep -v '^\./lit/ExampleTests' | \ + grep -v '/Output' | \ + grep -v '__pycache__' | \ + grep -v '.pyc$' | grep -v '~$' | \ + sort > /tmp/lit_source_files.txt + +# Create the source distribution. +echo "Creating source distribution." +rm -rf lit.egg-info dist +python setup.py sdist > /tmp/lit_sdist_log.txt + +# Creating list of files in source distribution. +echo "Creating source distribution file list." +tar zft dist/lit*.tar.gz | \ + sed -e 's#lit-[0-9.dev]*/#./#' | \ + sed -e 's#/$##' | \ + grep -v '^\./PKG-INFO' | \ + grep -v '^\./setup.cfg' | \ + grep -v '^\./lit.egg-info' | \ + sort > /tmp/lit_sdist_files.txt + +# Diff the files. +echo "Running diff..." +if (diff /tmp/lit_source_files.txt /tmp/lit_sdist_files.txt); then + echo "Diff is clean!" +else + echo "error: there were differences in the source lists!" + exit 1 +fi diff --git a/utils/llvm-compilers-check b/utils/llvm-compilers-check index 623ebc6a32..3173027759 100755 --- a/utils/llvm-compilers-check +++ b/utils/llvm-compilers-check @@ -1,11 +1,11 @@ #!/usr/bin/python3 ##===- utils/llvmbuild - Build the LLVM project ----------------*-python-*-===## -# +# # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. -# +# ##===----------------------------------------------------------------------===## # # This script builds many different flavors of the LLVM ecosystem. It @@ -147,6 +147,8 @@ def add_options(parser): help=("Do not build dragonegg")) parser.add_option("--no-install", default=False, action="store_true", help=("Do not do installs")) + parser.add_option("--keep-going", default=False, action="store_true", + help=("Keep going after failures")) return def check_options(parser, options, valid_builds): @@ -282,7 +284,7 @@ class Builder(threading.Thread): for key, value in env.items(): execenv[key] = value - + self.logger.debug("[" + prefix + "] " + "env " + str(env) + " " + " ".join(command)); @@ -299,6 +301,11 @@ class Builder(threading.Thread): + str(line, "utf-8").rstrip()) line = proc.stdout.readline() + (stdoutdata, stderrdata) = proc.communicate() + retcode = proc.wait() + + return retcode + except: traceback.print_exc() @@ -327,6 +334,7 @@ class Builder(threading.Thread): self.logger.debug("Start Gather") gather = True line = proc.stdout.readline() + except: traceback.print_exc() self.logger.debug(includes) @@ -353,16 +361,16 @@ class Builder(threading.Thread): configure_flags = dict( llvm=dict(debug=["--prefix=" + self.install_prefix, - "--with-extra-options=-Werror", + "--enable-werror", "--enable-assertions", "--disable-optimized", "--with-gcc-toolchain=" + cxxroot], release=["--prefix=" + self.install_prefix, - "--with-extra-options=-Werror", + "--enable-werror", "--enable-optimized", "--with-gcc-toolchain=" + cxxroot], paranoid=["--prefix=" + self.install_prefix, - "--with-extra-options=-Werror", + "--enable-werror", "--enable-assertions", "--enable-expensive-checks", "--disable-optimized", @@ -438,7 +446,7 @@ class Builder(threading.Thread): for component in components: comp = component[:] - + if (self.options.no_dragonegg): if (comp == 'dragonegg'): self.logger.info("Skipping " + component + " in " @@ -458,43 +466,74 @@ class Builder(threading.Thread): "").split()) self.logger.info("Configuring " + component + " in " + builddir) - self.configure(component, srcdir, builddir, - config_args, - configure_env[comp_key][build]) - - self.logger.info("Building " + component + " in " + builddir) - self.logger.info("Build: make " + str(make_flags[comp_key][build])) - self.make(component, srcdir, builddir, - make_flags[comp_key][build], - make_env[comp_key][build]) - - if (not self.options.no_install): - self.logger.info("Installing " + component + " in " + installdir) - self.make(component, srcdir, builddir, - make_install_flags[comp_key][build], - make_install_env[comp_key][build]) - - self.logger.info("Testing " + component + " in " + builddir) - self.logger.info("Test: make " - + str(make_check_flags[comp_key][build])) - self.make(component, srcdir, builddir, - make_check_flags[comp_key][build], - make_check_env[comp_key][build]) - + configrc = self.configure(component, srcdir, builddir, + config_args, + configure_env[comp_key][build]) + + if (configrc == None) : + self.logger.info("[None] Failed to configure " + component + " in " + installdir) + + if (configrc == 0 or self.options.keep_going) : + self.logger.info("Building " + component + " in " + builddir) + self.logger.info("Build: make " + str(make_flags[comp_key][build])) + buildrc = self.make(component, srcdir, builddir, + make_flags[comp_key][build], + make_env[comp_key][build]) + + if (buildrc == None) : + self.logger.info("[None] Failed to build " + component + " in " + installdir) + + if (buildrc == 0 or self.options.keep_going) : + self.logger.info("Testing " + component + " in " + builddir) + self.logger.info("Test: make " + + str(make_check_flags[comp_key][build])) + testrc = self.make(component, srcdir, builddir, + make_check_flags[comp_key][build], + make_check_env[comp_key][build]) + + if (testrc == None) : + self.logger.info("[None] Failed to test " + component + " in " + installdir) + + if ((testrc == 0 or self.options.keep_going) + and not self.options.no_install): + self.logger.info("Installing " + component + " in " + installdir) + self.make(component, srcdir, builddir, + make_install_flags[comp_key][build], + make_install_env[comp_key][build]) + else : + self.logger.info("Failed testing " + component + " in " + installdir) + + else : + self.logger.info("Failed to build " + component + " in " + installdir) + + else : + self.logger.info("Failed to configure " + component + " in " + installdir) def configure(self, component, srcdir, builddir, flags, env): + prefix = self.component_abbrev[component.replace("-", "_")] + self.logger.debug("Configure " + str(flags) + " " + str(srcdir) + " -> " + str(builddir)) configure_files = dict( llvm=[(srcdir + "/configure", builddir + "/Makefile")], - dragonegg=[("","")]) + dragonegg=[(None,None)]) doconfig = False for conf, mf in configure_files[component.replace("-", "_")]: + if conf is None: + # No configure necessary + return 0 + if not os.path.exists(conf): - return + self.logger.info("[" + prefix + "] Configure failed, no configure script " + conf) + return -1 + + if not os.path.exists(mf): + self.logger.info("[" + prefix + "] Configure failed, no makefile " + mf) + return -1 + if os.path.exists(conf) and os.path.exists(mf): confstat = os.stat(conf) makestat = os.stat(mf) @@ -506,16 +545,17 @@ class Builder(threading.Thread): break if not doconfig and not self.options.force_configure: - return + return 0 program = srcdir + "/configure" if not is_executable(program): - return + self.logger.info("[" + prefix + "] Configure failed, cannot execute " + program) + return -1 args = [program] args += ["--verbose"] args += flags - self.execute(args, builddir, env, component) + return self.execute(args, builddir, env, component) def make(self, component, srcdir, builddir, flags, env): program = find_executable("make") @@ -527,7 +567,7 @@ class Builder(threading.Thread): args = [program] args += flags - self.execute(args, builddir, env, component) + return self.execute(args, builddir, env, component) # Global constants build_abbrev = dict(debug="dbg", release="opt", paranoid="par") diff --git a/utils/llvm-lit/llvm-lit.in b/utils/llvm-lit/llvm-lit.in index 768dc5103c..87878d5638 100755 --- a/utils/llvm-lit/llvm-lit.in +++ b/utils/llvm-lit/llvm-lit.in @@ -13,8 +13,7 @@ sys.path.insert(0, os.path.join(llvm_source_root, 'utils', 'lit')) # Set up some builtin parameters, so that by default the LLVM test suite # configuration file knows how to find the object tree. builtin_parameters = { - 'build_config' : "@CMAKE_CFG_INTDIR@", - 'build_mode' : "@RUNTIME_BUILD_MODE@", + 'build_mode' : "@CMAKE_CFG_INTDIR@", 'llvm_site_config' : os.path.join(llvm_obj_root, 'test', 'lit.site.cfg') } diff --git a/utils/llvm.grm b/utils/llvm.grm index 322036b2c2..d65f075076 100644 --- a/utils/llvm.grm +++ b/utils/llvm.grm @@ -174,7 +174,9 @@ FuncAttr ::= noreturn | sspreq | returns_twice | nonlazybind - | address_safety + | sanitize_address + | sanitize_thread + | sanitize_memory ; OptFuncAttrs ::= + _ | OptFuncAttrs FuncAttr ; diff --git a/utils/llvm.natvis b/utils/llvm.natvis new file mode 100644 index 0000000000..6b4ef83c67 --- /dev/null +++ b/utils/llvm.natvis @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!--
+Visual Studio 2012 Native Debugging Visualizers for LLVM
+
+Put this file into "%USERPROFILE%\Documents\Visual Studio 2012\Visualizers"
+or create a symbolic link so it updates automatically.
+-->
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+ <Type Name="llvm::SmallVector<*,*>">
+ <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) == 0">empty</DisplayString>
+ <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) != 0">{{ size={($T1*)EndX - ($T1*)BeginX} }}</DisplayString>
+ <Expand>
+ <Item Name="[size]">($T1*)EndX - ($T1*)BeginX</Item>
+ <Item Name="[capacity]">($T1*)CapacityX - ($T1*)BeginX</Item>
+ <ArrayItems>
+ <Size>($T1*)EndX - ($T1*)BeginX</Size>
+ <ValuePointer>($T1*)BeginX</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::SmallVectorImpl<*>">
+ <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) == 0">empty</DisplayString>
+ <DisplayString Condition="(($T1*)EndX - ($T1*)BeginX) != 0">[{($T1*)EndX - ($T1*)BeginX}]</DisplayString>
+ <Expand>
+ <Item Name="[size]">($T1*)EndX - ($T1*)BeginX</Item>
+ <Item Name="[capacity]">($T1*)CapacityX - ($T1*)BeginX</Item>
+ <ArrayItems>
+ <Size>($T1*)EndX - ($T1*)BeginX</Size>
+ <ValuePointer>($T1*)BeginX</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::SmallString<*>">
+ <DisplayString>{BeginX,s}</DisplayString>
+ <StringView>BeginX,s</StringView>
+ <Expand>
+ <Item Name="[size]">(char*)EndX - (char*)BeginX</Item>
+ <Item Name="[capacity]">(char*)CapacityX - (char*)BeginX</Item>
+ <ArrayItems>
+ <Size>(char*)EndX - (char*)BeginX</Size>
+ <ValuePointer>(char*)BeginX</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::StringRef">
+ <DisplayString>[{Length}] {Data,s}</DisplayString>
+ <StringView>Data,s</StringView>
+ <Expand>
+ <Item Name="[length]">Length</Item>
+ <ArrayItems>
+ <Size>Length</Size>
+ <ValuePointer>Data</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::PointerIntPair<*,*,*,*>">
+ <DisplayString>{Value & PointerBitMask} [{(Value >> IntShift) & IntMask}]</DisplayString>
+ <Expand>
+ <Item Name="[ptr]">Value & PointerBitMask</Item>
+ <Item Name="[int]">(Value >> IntShift) & IntMask</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::PointerUnion<*,*>">
+ <DisplayString Condition="((Val.Value >> Val.IntShift) & Val.IntMask) == 0">[P1] {($T1)(Val.Value & Val.PointerBitMask)}</DisplayString>
+ <DisplayString Condition="((Val.Value >> Val.IntShift) & Val.IntMask) != 0">[P2] {($T2)(Val.Value & Val.PointerBitMask)}</DisplayString>
+ <Expand>
+ <Item Name="[ptr]" Condition="((Val.Value >> Val.IntShift) & Val.IntMask) == 0">($T1)(Val.Value & Val.PointerBitMask)</Item>
+ <Item Name="[ptr]" Condition="((Val.Value >> Val.IntShift) & Val.IntMask) != 0">($T2)(Val.Value & Val.PointerBitMask)</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::PointerUnion3<*,*,*>">
+ <DisplayString Condition="(Val.Val.Value & 2) != 2 && (Val.Val.Value & 1) != 1">[P1] {($T1)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value & 2) == 2">[P2] {($T2)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value & 1) == 1">[P3] {($T3)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <Expand>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 2) != 2 && (Val.Val.Value & 1) != 1">($T1)((Val.Val.Value >> 2) << 2)</Item>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 2) == 2">($T2)((Val.Val.Value >> 2) << 2)</Item>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 1) == 1">($T3)((Val.Val.Value >> 2) << 2)</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::PointerUnion4<*,*,*,*>">
+ <DisplayString Condition="(Val.Val.Value & 3) != 3 && (Val.Val.Value & 2) != 2 && (Val.Val.Value & 1) != 1">[P1] {($T1)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value & 3) != 3 && (Val.Val.Value & 2) == 2">[P2] {($T2)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value & 3) != 3 && (Val.Val.Value & 1) == 1">[P3] {($T3)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <DisplayString Condition="(Val.Val.Value & 3) == 3">[P4] {($T4)((Val.Val.Value >> 2) << 2)}</DisplayString>
+ <Expand>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 3) != 3 && (Val.Val.Value & 2) != 2 && (Val.Val.Value & 1) != 1">($T1)((Val.Val.Value >> 2) << 2)</Item>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 3) != 3 && (Val.Val.Value & 2) == 2">($T2)((Val.Val.Value >> 2) << 2)</Item>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 3) != 3 && (Val.Val.Value & 1) == 1">($T3)((Val.Val.Value >> 2) << 2)</Item>
+ <Item Name="[ptr]" Condition="(Val.Val.Value & 3) == 3">($T4)((Val.Val.Value >> 2) << 2)</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::iplist<*,*>">
+ <DisplayString Condition="Head == 0">{{ empty }}</DisplayString>
+ <DisplayString Condition="Head != 0">{{ head={Head} }}</DisplayString>
+ <Expand>
+ <LinkedListItems>
+ <HeadPointer>Head</HeadPointer>
+ <NextPointer>Next</NextPointer>
+ <ValueNode>this</ValueNode>
+ </LinkedListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::IntrusiveRefCntPtr<*>">
+ <DisplayString Condition="Obj == 0">empty</DisplayString>
+ <DisplayString Condition="(Obj != 0) && (Obj->ref_cnt == 1)">RefPtr [1 ref] {*Obj}</DisplayString>
+ <DisplayString Condition="(Obj != 0) && (Obj->ref_cnt != 1)">RefPtr [{Obj->ref_cnt} refs] {*Obj}</DisplayString>
+ <Expand>
+ <Item Condition="Obj != 0" Name="[refs]">Obj->ref_cnt</Item>
+ <Item Condition="Obj != 0" Name="[ptr]">Obj</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::OwningPtr<*>">
+ <DisplayString Condition="Ptr == 0">empty</DisplayString>
+ <DisplayString Condition="Ptr != 0">OwningPtr {*Ptr}</DisplayString>
+ <Expand>
+ <Item Condition="Ptr != 0" Name="[ptr]">Ptr</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::SmallPtrSet<*,*>">
+ <DisplayString Condition="CurArray == SmallArray">{{ [Small Mode] elements={NumElements}, arraySize={CurArraySize} }}</DisplayString>
+ <DisplayString Condition="CurArray != SmallArray">{{ [Big Mode] elements={NumElements}, arraySize={CurArraySize} }}</DisplayString>
+ <Expand>
+ <Item Name="[NumElements]">NumElements</Item>
+ <Item Name="[CurArraySize]">CurArraySize</Item>
+ <IndexListItems>
+ <Size>CurArraySize + 1</Size>
+ <ValueNode>($T1*)&CurArray[$i]</ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::DenseMap<*,*,*>">
+ <DisplayString Condition="NumEntries == 0">empty</DisplayString>
+ <DisplayString Condition="NumEntries != 0">{{ entries={NumEntries}, buckets={NumBuckets} }}</DisplayString>
+ <Expand>
+ <Item Name="[NumEntries]">NumEntries</Item>
+ <Item Name="[NumBuckets]">NumBuckets</Item>
+ <ArrayItems>
+ <Size>NumBuckets</Size>
+ <ValuePointer>Buckets</ValuePointer>
+ </ArrayItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::StringMap<*,*>">
+ <DisplayString>{{ NumBuckets={NumBuckets}, ItemSize={ItemSize} }}</DisplayString>
+ <Expand>
+ <Item Name="[NumBuckets]">NumBuckets</Item>
+ <Item Name="[ItemSize]">ItemSize</Item>
+ <IndexListItems>
+ <Size>NumBuckets</Size>
+ <ValueNode>(llvm::StringMapEntry<$T1>*)TheTable[$i]</ValueNode>
+ </IndexListItems>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::StringMapEntry<*>">
+ <DisplayString Condition="StrLen == 0">empty</DisplayString>
+ <DisplayString Condition="StrLen != 0">({((llvm::StringMapEntry<$T1>*)this)+1,s}, {second})</DisplayString>
+ <Expand>
+ <Item Name="[key]">((llvm::StringMapEntry<$T1>*)this)+1,s</Item>
+ <Item Name="[value]" Condition="StrLen != 0">second</Item>
+ </Expand>
+ </Type>
+
+ <Type Name="llvm::Triple">
+ <DisplayString>{Data}</DisplayString>
+ </Type>
+</AutoVisualizer>
diff --git a/utils/unittest/UnitTestMain/TestMain.cpp b/utils/unittest/UnitTestMain/TestMain.cpp index b35bae5abf..ce32b7380f 100644 --- a/utils/unittest/UnitTestMain/TestMain.cpp +++ b/utils/unittest/UnitTestMain/TestMain.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Config/config.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Signals.h" #include "gtest/gtest.h" @@ -22,6 +23,7 @@ int main(int argc, char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); testing::InitGoogleTest(&argc, argv); + llvm::cl::ParseCommandLineOptions(argc, argv); # if defined(LLVM_ON_WIN32) // Disable all of the possible ways Windows conspires to make automated diff --git a/utils/unittest/googletest/gtest-printers.cc b/utils/unittest/googletest/gtest-printers.cc index ed63c7b3b9..205a39425f 100644 --- a/utils/unittest/googletest/gtest-printers.cc +++ b/utils/unittest/googletest/gtest-printers.cc @@ -127,7 +127,7 @@ namespace internal { // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), -// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a hexadecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). enum CharFormat { kAsIs, @@ -230,7 +230,7 @@ void PrintCharAndCodeTo(Char c, ostream* os) { return; *os << " (" << String::Format("%d", c).c_str(); - // For more convenience, we print c's code again in hexidecimal, + // For more convenience, we print c's code again in hexadecimal, // unless c was already printed in the form '\x##' or the code is in // [1, 9]. if (format == kHexEscape || (1 <= c && c <= 9)) { diff --git a/utils/valgrind/x86_64-pc-linux-gnu.supp b/utils/valgrind/x86_64-pc-linux-gnu.supp index fc863b85e2..c8e5cd0917 100644 --- a/utils/valgrind/x86_64-pc-linux-gnu.supp +++ b/utils/valgrind/x86_64-pc-linux-gnu.supp @@ -33,6 +33,12 @@ } { + We don't care of cmp + Memcheck:Cond + obj:/usr/bin/cmp +} + +{ We don't care if grep leaks Memcheck:Leak obj:/bin/grep diff --git a/utils/vim/llvm.vim b/utils/vim/llvm.vim index 753549fd72..830476f158 100644 --- a/utils/vim/llvm.vim +++ b/utils/vim/llvm.vim @@ -35,7 +35,7 @@ syn keyword llvmStatement uitofp ule ult umax umin une uno unreachable unwind syn keyword llvmStatement urem va_arg xchg xor zext " Keywords. -syn keyword llvmKeyword acq_rel acquire address_safety addrspace alias align +syn keyword llvmKeyword acq_rel acquire sanitize_address addrspace alias align syn keyword llvmKeyword alignstack alwaysinline appending arm_aapcs_vfpcc syn keyword llvmKeyword arm_aapcscc arm_apcscc asm atomic available_externally syn keyword llvmKeyword blockaddress byval c catch cc ccc cleanup coldcc common @@ -51,10 +51,11 @@ syn keyword llvmKeyword noimplicitfloat noinline nonlazybind noredzone noreturn syn keyword llvmKeyword nounwind optsize personality private protected syn keyword llvmKeyword ptx_device ptx_kernel readnone readonly release syn keyword llvmKeyword returns_twice section seq_cst sideeffect signext -syn keyword llvmKeyword singlethread spir_func spir_kernel sret ssp sspreq tail -syn keyword llvmKeyword target thread_local to triple unnamed_addr unordered -syn keyword llvmKeyword uwtable volatile weak weak_odr x86_fastcallcc -syn keyword llvmKeyword x86_stdcallcc x86_thiscallcc zeroext +syn keyword llvmKeyword singlethread spir_func spir_kernel sret ssp sspreq +syn keyword llvmKeyword sspstrong tail target thread_local to triple +syn keyword llvmKeyword unnamed_addr unordered uwtable volatile weak weak_odr +syn keyword llvmKeyword x86_fastcallcc x86_stdcallcc x86_thiscallcc zeroext +syn keyword llvmKeyword sanitize_thread sanitize_memory " Obsolete keywords. syn keyword llvmError getresult begin end diff --git a/utils/vim/vimrc b/utils/vim/vimrc index 3ef54c08cf..fd87d767d6 100644 --- a/utils/vim/vimrc +++ b/utils/vim/vimrc @@ -85,6 +85,13 @@ augroup filetype au! BufRead,BufNewFile *.td set filetype=tablegen augroup END +" Enable syntax highlighting for reStructuredText files. To use, copy +" rest.vim (http://www.vim.org/scripts/script.php?script_id=973) +" to ~/.vim/syntax . +augroup filetype + au! BufRead,BufNewFile *.rst set filetype=rest +augroup END + " Additional vim features to optionally uncomment. "set showcmd "set showmatch |