Importing rustc-1.56.0
Change-Id: I98941481270706fa55f8fb2cb91686ae3bd30f38
diff --git a/src/llvm-project/llvm/utils/FileCheck/FileCheck.cpp b/src/llvm-project/llvm/utils/FileCheck/FileCheck.cpp
index be27756..4dcc481 100644
--- a/src/llvm-project/llvm/utils/FileCheck/FileCheck.cpp
+++ b/src/llvm-project/llvm/utils/FileCheck/FileCheck.cpp
@@ -22,6 +22,7 @@
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <cmath>
+#include <map>
using namespace llvm;
static cl::extrahelp FileCheckOptsEnv(
@@ -78,7 +79,7 @@
"checks that some error message does not occur, for example."));
static cl::opt<bool> AllowUnusedPrefixes(
- "allow-unused-prefixes", cl::init(true),
+ "allow-unused-prefixes", cl::init(false), cl::ZeroOrMore,
cl::desc("Allow prefixes to be specified but not appear in the test."));
static cl::opt<bool> MatchFullLines(
@@ -212,11 +213,20 @@
case FileCheckDiag::MatchFoundButDiscarded:
return MarkerStyle('!', raw_ostream::CYAN,
"discard: overlaps earlier match");
+ case FileCheckDiag::MatchFoundErrorNote:
+ // Note should always be overridden within the FileCheckDiag.
+ return MarkerStyle('!', raw_ostream::RED,
+ "error: unknown error after match",
+ /*FiltersAsError=*/true);
case FileCheckDiag::MatchNoneAndExcluded:
return MarkerStyle('X', raw_ostream::GREEN);
case FileCheckDiag::MatchNoneButExpected:
return MarkerStyle('X', raw_ostream::RED, "error: no match found",
/*FiltersAsError=*/true);
+ case FileCheckDiag::MatchNoneForInvalidPattern:
+ return MarkerStyle('X', raw_ostream::RED,
+ "error: match failed for invalid pattern",
+ /*FiltersAsError=*/true);
case FileCheckDiag::MatchFuzzy:
return MarkerStyle('?', raw_ostream::MAGENTA, "possible intended match",
/*FiltersAsError=*/true);
@@ -248,7 +258,10 @@
// Labels for input lines.
OS << " - ";
WithColor(OS, raw_ostream::SAVEDCOLOR, true) << "L:";
- OS << " labels line number L of the input file\n";
+ OS << " labels line number L of the input file\n"
+ << " An extra space is added after each input line to represent"
+ << " the\n"
+ << " newline character\n";
// Labels for annotation lines.
OS << " - ";
@@ -366,16 +379,25 @@
const std::vector<FileCheckDiag> &Diags,
std::vector<InputAnnotation> &Annotations,
unsigned &LabelWidth) {
- // How many diagnostics have we seen so far?
- unsigned DiagCount = 0;
- // How many diagnostics has the current check seen so far?
- unsigned CheckDiagCount = 0;
+ struct CompareSMLoc {
+ bool operator()(const SMLoc &LHS, const SMLoc &RHS) const {
+ return LHS.getPointer() < RHS.getPointer();
+ }
+ };
+ // How many diagnostics does each pattern have?
+ std::map<SMLoc, unsigned, CompareSMLoc> DiagCountPerPattern;
+ for (auto Diag : Diags)
+ ++DiagCountPerPattern[Diag.CheckLoc];
+ // How many diagnostics have we seen so far per pattern?
+ std::map<SMLoc, unsigned, CompareSMLoc> DiagIndexPerPattern;
+ // How many total diagnostics have we seen so far?
+ unsigned DiagIndex = 0;
// What's the widest label?
LabelWidth = 0;
for (auto DiagItr = Diags.begin(), DiagEnd = Diags.end(); DiagItr != DiagEnd;
++DiagItr) {
InputAnnotation A;
- A.DiagIndex = DiagCount++;
+ A.DiagIndex = DiagIndex++;
// Build label, which uniquely identifies this check result.
unsigned CheckBufferID = SM.FindBufferContainingLoc(DiagItr->CheckLoc);
@@ -391,17 +413,8 @@
else
llvm_unreachable("expected diagnostic's check location to be either in "
"the check file or for an implicit pattern");
- unsigned CheckDiagIndex = UINT_MAX;
- auto DiagNext = std::next(DiagItr);
- if (DiagNext != DiagEnd && DiagItr->CheckTy == DiagNext->CheckTy &&
- DiagItr->CheckLoc == DiagNext->CheckLoc)
- CheckDiagIndex = CheckDiagCount++;
- else if (CheckDiagCount) {
- CheckDiagIndex = CheckDiagCount;
- CheckDiagCount = 0;
- }
- if (CheckDiagIndex != UINT_MAX)
- Label << "'" << CheckDiagIndex;
+ if (DiagCountPerPattern[DiagItr->CheckLoc] > 1)
+ Label << "'" << DiagIndexPerPattern[DiagItr->CheckLoc]++;
Label.flush();
LabelWidth = std::max((std::string::size_type)LabelWidth, A.Label.size());
@@ -418,6 +431,11 @@
DiagItr->InputStartCol == DiagItr->InputEndCol)
A.Marker.Lead = ' ';
}
+ if (DiagItr->MatchTy == FileCheckDiag::MatchFoundErrorNote) {
+ assert(!DiagItr->Note.empty() &&
+ "expected custom note for MatchFoundErrorNote");
+ A.Marker.Note = "error: " + A.Marker.Note;
+ }
A.FoundAndExpectedMatch =
DiagItr->MatchTy == FileCheckDiag::MatchFoundAndExpected;
@@ -662,15 +680,16 @@
COS.resetColor();
else if (WasInMatch && !InMatch)
COS.changeColor(raw_ostream::CYAN, true, true);
- if (*InputFilePtr == '\n')
+ if (*InputFilePtr == '\n') {
Newline = true;
- else
+ COS << ' ';
+ } else
COS << *InputFilePtr;
++InputFilePtr;
}
}
*LineOS << '\n';
- unsigned InputLineWidth = InputFilePtr - InputFileLine - Newline;
+ unsigned InputLineWidth = InputFilePtr - InputFileLine;
// Print any annotations.
while (AnnotationItr != AnnotationEnd &&
@@ -745,14 +764,11 @@
}
FileCheckRequest Req;
- for (StringRef Prefix : CheckPrefixes)
- Req.CheckPrefixes.push_back(Prefix);
+ append_range(Req.CheckPrefixes, CheckPrefixes);
- for (StringRef Prefix : CommentPrefixes)
- Req.CommentPrefixes.push_back(Prefix);
+ append_range(Req.CommentPrefixes, CommentPrefixes);
- for (StringRef CheckNot : ImplicitCheckNot)
- Req.ImplicitCheckNot.push_back(CheckNot);
+ append_range(Req.ImplicitCheckNot, ImplicitCheckNot);
bool GlobalDefineError = false;
for (StringRef G : GlobalDefines) {
@@ -806,7 +822,7 @@
// Read the expected strings from the check file.
ErrorOr<std::unique_ptr<MemoryBuffer>> CheckFileOrErr =
- MemoryBuffer::getFileOrSTDIN(CheckFilename);
+ MemoryBuffer::getFileOrSTDIN(CheckFilename, /*IsText=*/true);
if (std::error_code EC = CheckFileOrErr.getError()) {
errs() << "Could not open check file '" << CheckFilename
<< "': " << EC.message() << '\n';
@@ -828,7 +844,7 @@
// Open the file to check and add it to SourceMgr.
ErrorOr<std::unique_ptr<MemoryBuffer>> InputFileOrErr =
- MemoryBuffer::getFileOrSTDIN(InputFilename);
+ MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true);
if (InputFilename == "-")
InputFilename = "<stdin>"; // Overwrite for improved diagnostic messages
if (std::error_code EC = InputFileOrErr.getError()) {
diff --git a/src/llvm-project/llvm/utils/GenLibDeps.pl b/src/llvm-project/llvm/utils/GenLibDeps.pl
index 42afa6a..e283465 100755
--- a/src/llvm-project/llvm/utils/GenLibDeps.pl
+++ b/src/llvm-project/llvm/utils/GenLibDeps.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# Program: GenLibDeps.pl
#
diff --git a/src/llvm-project/llvm/utils/LLVMVisualizers/llvm.natvis b/src/llvm-project/llvm/utils/LLVMVisualizers/llvm.natvis
index 69d2026..6e75ebd 100644
--- a/src/llvm-project/llvm/utils/LLVMVisualizers/llvm.natvis
+++ b/src/llvm-project/llvm/utils/LLVMVisualizers/llvm.natvis
@@ -289,14 +289,18 @@
</Expand>
</Synthetic>
- <Item Name="ElementType" Condition="ID == llvm::Type::TypeID::ArrayTyID || ID == llvm::Type::TypeID::VectorTyID">*ContainedTys</Item>
+ <Item Name="ElementType" Condition="ID == llvm::Type::TypeID::ArrayTyID">*ContainedTys</Item>
<Item Name="NumElements" Condition="ID == llvm::Type::TypeID::ArrayTyID">((llvm::ArrayType*)this)->NumElements</Item>
+ <Item Name="ElementType" Condition="ID == llvm::Type::TypeID::FixedVectorTyID">*ContainedTys</Item>
+ <Item Name="NumElements" Condition="ID == llvm::Type::TypeID::FixedVectorTyID">((llvm::VectorType*)this)->ElementQuantity</Item>
+
+ <Item Name="ElementType" Condition="ID == llvm::Type::TypeID::ScalableVectorTyID">*ContainedTys</Item>
+ <Item Name="MinNumElements" Condition="ID == llvm::Type::TypeID::ScalableVectorTyID">((llvm::VectorType*)this)->ElementQuantity</Item>
+
<Item Name="AddressSpace" Condition="ID == llvm::Type::TypeID::PointerTyID">SubclassData</Item>
<Item Name="PointeeType" Condition="ID == llvm::Type::TypeID::PointerTyID">*ContainedTys</Item>
- <Item Name="NumElements" Condition="ID == llvm::Type::TypeID::VectorTyID">((llvm::VectorType*)this)->NumElements</Item>
-
<Item Name="Context">Context</Item>
</Expand>
</Type>
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 9d30491..00bdd12 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -612,7 +612,7 @@
/// operator< - Compare two matchables.
bool operator<(const MatchableInfo &RHS) const {
// The primary comparator is the instruction mnemonic.
- if (int Cmp = Mnemonic.compare_lower(RHS.Mnemonic))
+ if (int Cmp = Mnemonic.compare_insensitive(RHS.Mnemonic))
return Cmp == -1;
if (AsmOperands.size() != RHS.AsmOperands.size())
@@ -1100,8 +1100,8 @@
static std::string getEnumNameForToken(StringRef Str) {
std::string Res;
- for (StringRef::iterator it = Str.begin(), ie = Str.end(); it != ie; ++it) {
- switch (*it) {
+ for (char C : Str) {
+ switch (C) {
case '*': Res += "_STAR_"; break;
case '%': Res += "_PCT_"; break;
case ':': Res += "_COLON_"; break;
@@ -1112,10 +1112,10 @@
case '-': Res += "_MINUS_"; break;
case '#': Res += "_HASH_"; break;
default:
- if (isAlnum(*it))
- Res += *it;
+ if (isAlnum(C))
+ Res += C;
else
- Res += "_" + utostr((unsigned) *it) + "_";
+ Res += "_" + utostr((unsigned)C) + "_";
}
}
@@ -1322,9 +1322,8 @@
}
// Populate the map for individual registers.
- for (std::map<Record*, RegisterSet>::iterator it = RegisterMap.begin(),
- ie = RegisterMap.end(); it != ie; ++it)
- RegisterClasses[it->first] = RegisterSetClasses[it->second];
+ for (auto &It : RegisterMap)
+ RegisterClasses[It.first] = RegisterSetClasses[It.second];
// Name the register classes which correspond to singleton registers.
for (Record *Rec : SingletonRegisters) {
@@ -1529,9 +1528,8 @@
// matchables.
std::vector<Record*> AllInstAliases =
Records.getAllDerivedDefinitions("InstAlias");
- for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
- auto Alias = std::make_unique<CodeGenInstAlias>(AllInstAliases[i],
- Target);
+ for (Record *InstAlias : AllInstAliases) {
+ auto Alias = std::make_unique<CodeGenInstAlias>(InstAlias, Target);
// If the tblgen -match-prefix option is specified (for tblgen hackers),
// filter the set of instruction aliases we consider, based on the target
@@ -2726,7 +2724,7 @@
StringRef AsmVariantName = R->getValueAsString("AsmVariantName");
if (AsmVariantName != AsmParserVariantName)
continue;
- AliasesFromMnemonic[std::string(R->getValueAsString("FromMnemonic"))]
+ AliasesFromMnemonic[R->getValueAsString("FromMnemonic").lower()]
.push_back(R);
}
if (AliasesFromMnemonic.empty())
@@ -2751,10 +2749,14 @@
// If this unconditionally matches, remember it for later and diagnose
// duplicates.
if (FeatureMask.empty()) {
- if (AliasWithNoPredicate != -1) {
- // We can't have two aliases from the same mnemonic with no predicate.
- PrintError(ToVec[AliasWithNoPredicate]->getLoc(),
- "two MnemonicAliases with the same 'from' mnemonic!");
+ if (AliasWithNoPredicate != -1 &&
+ R->getValueAsString("ToMnemonic") !=
+ ToVec[AliasWithNoPredicate]->getValueAsString("ToMnemonic")) {
+ // We can't have two different aliases from the same mnemonic with no
+ // predicate.
+ PrintError(
+ ToVec[AliasWithNoPredicate]->getLoc(),
+ "two different MnemonicAliases with the same 'from' mnemonic!");
PrintFatalError(R->getLoc(), "this is the other MnemonicAlias.");
}
@@ -2768,7 +2770,7 @@
MatchCode += "else ";
MatchCode += "if (" + FeatureMask + ")\n";
MatchCode += " Mnemonic = \"";
- MatchCode += R->getValueAsString("ToMnemonic");
+ MatchCode += R->getValueAsString("ToMnemonic").lower();
MatchCode += "\";\n";
}
@@ -2777,7 +2779,7 @@
if (!MatchCode.empty())
MatchCode += "else\n ";
MatchCode += "Mnemonic = \"";
- MatchCode += R->getValueAsString("ToMnemonic");
+ MatchCode += R->getValueAsString("ToMnemonic").lower();
MatchCode += "\";\n";
}
@@ -2883,14 +2885,10 @@
OS << OMI.OperandMask;
OS << " /* ";
- bool printComma = false;
+ ListSeparator LS;
for (int i = 0, e = 31; i !=e; ++i)
- if (OMI.OperandMask & (1 << i)) {
- if (printComma)
- OS << ", ";
- OS << i;
- printComma = true;
- }
+ if (OMI.OperandMask & (1 << i))
+ OS << LS << i;
OS << " */, ";
OS << OMI.CI->Name;
@@ -3513,12 +3511,9 @@
OS << '_' << MI->RequiredFeatures[i]->TheDef->getName();
OS << ", { ";
- for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
- const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];
-
- if (i) OS << ", ";
- OS << Op.Class->Name;
- }
+ ListSeparator LS;
+ for (const MatchableInfo::AsmOperand &Op : MI->AsmOperands)
+ OS << LS << Op.Class->Name;
OS << " }, },\n";
}
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp
index 92df204..94fd8f7 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/AsmWriterEmitter.cpp
@@ -994,8 +994,7 @@
});
}
- for (auto I = ReqFeatures.cbegin(); I != ReqFeatures.cend(); I++) {
- Record *R = *I;
+ for (Record *const R : ReqFeatures) {
const DagInit *D = R->getValueAsDag("AssemblerCondDag");
std::string CombineType = D->getOperator()->getAsString();
if (CombineType != "any_of" && CombineType != "all_of")
diff --git a/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h b/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h
index 366c9ec..fe2b934 100644
--- a/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h
+++ b/src/llvm-project/llvm/utils/TableGen/AsmWriterInst.h
@@ -66,7 +66,8 @@
bool operator!=(const AsmWriterOperand &Other) const {
if (OperandType != Other.OperandType || Str != Other.Str) return true;
if (OperandType == isMachineInstrOperand)
- return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier;
+ return MIOpNo != Other.MIOpNo || MiModifier != Other.MiModifier ||
+ PCRel != Other.PCRel;
return false;
}
bool operator==(const AsmWriterOperand &Other) const {
diff --git a/src/llvm-project/llvm/utils/TableGen/Attributes.cpp b/src/llvm-project/llvm/utils/TableGen/Attributes.cpp
index f3f875e..5deac4b 100644
--- a/src/llvm-project/llvm/utils/TableGen/Attributes.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/Attributes.cpp
@@ -25,6 +25,7 @@
private:
void emitTargetIndependentNames(raw_ostream &OS);
void emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr);
+ void emitAttributeProperties(raw_ostream &OF);
RecordKeeper &Records;
};
@@ -58,7 +59,20 @@
Emit({"StrBoolAttr"}, "ATTRIBUTE_STRBOOL");
OS << "#undef ATTRIBUTE_ALL\n";
- OS << "#endif\n";
+ OS << "#endif\n\n";
+
+ OS << "#ifdef GET_ATTR_ENUM\n";
+ OS << "#undef GET_ATTR_ENUM\n";
+ unsigned Value = 1; // Leave zero for AttrKind::None.
+ for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) {
+ OS << "First" << KindName << " = " << Value << ",\n";
+ for (auto A : Records.getAllDerivedDefinitions(KindName)) {
+ OS << A->getName() << " = " << Value << ",\n";
+ Value++;
+ }
+ OS << "Last" << KindName << " = " << (Value - 1) << ",\n";
+ }
+ OS << "#endif\n\n";
}
void Attributes::emitFnAttrCompatCheck(raw_ostream &OS, bool IsStringAttr) {
@@ -96,9 +110,26 @@
OS << "#endif\n";
}
+void Attributes::emitAttributeProperties(raw_ostream &OS) {
+ OS << "#ifdef GET_ATTR_PROP_TABLE\n";
+ OS << "#undef GET_ATTR_PROP_TABLE\n";
+ OS << "static const uint8_t AttrPropTable[] = {\n";
+ for (StringRef KindName : {"EnumAttr", "TypeAttr", "IntAttr"}) {
+ for (auto A : Records.getAllDerivedDefinitions(KindName)) {
+ OS << "0";
+ for (Init *P : *A->getValueAsListInit("Properties"))
+ OS << " | AttributeProperty::" << cast<DefInit>(P)->getDef()->getName();
+ OS << ",\n";
+ }
+ }
+ OS << "};\n";
+ OS << "#endif\n";
+}
+
void Attributes::emit(raw_ostream &OS) {
emitTargetIndependentNames(OS);
emitFnAttrCompatCheck(OS, false);
+ emitAttributeProperties(OS);
}
namespace llvm {
diff --git a/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt b/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt
index 8673a25..9e91885 100644
--- a/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt
+++ b/src/llvm-project/llvm/utils/TableGen/CMakeLists.txt
@@ -8,6 +8,7 @@
AsmWriterInst.cpp
Attributes.cpp
CallingConvEmitter.cpp
+ CodeBeadsGen.cpp
CodeEmitterGen.cpp
CodeGenDAGPatterns.cpp
CodeGenHwModes.cpp
diff --git a/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp
index 9e99748..127ae62 100644
--- a/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CallingConvEmitter.cpp
@@ -131,10 +131,9 @@
O << IndentStr << "static const MCPhysReg RegList" << ++Counter
<< "[] = {\n";
O << IndentStr << " ";
- for (unsigned i = 0, e = RegList->size(); i != e; ++i) {
- if (i != 0) O << ", ";
- O << getQualifiedName(RegList->getElementAsRecord(i));
- }
+ ListSeparator LS;
+ for (unsigned i = 0, e = RegList->size(); i != e; ++i)
+ O << LS << getQualifiedName(RegList->getElementAsRecord(i));
O << "\n" << IndentStr << "};\n";
O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
<< Counter << ")) {\n";
@@ -162,19 +161,17 @@
O << IndentStr << "static const MCPhysReg RegList" << RegListNumber
<< "[] = {\n";
O << IndentStr << " ";
- for (unsigned i = 0, e = RegList->size(); i != e; ++i) {
- if (i != 0) O << ", ";
- O << getQualifiedName(RegList->getElementAsRecord(i));
- }
+ ListSeparator LS;
+ for (unsigned i = 0, e = RegList->size(); i != e; ++i)
+ O << LS << getQualifiedName(RegList->getElementAsRecord(i));
O << "\n" << IndentStr << "};\n";
O << IndentStr << "static const MCPhysReg RegList"
<< ShadowRegListNumber << "[] = {\n";
O << IndentStr << " ";
- for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i) {
- if (i != 0) O << ", ";
- O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
- }
+ ListSeparator LSS;
+ for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
+ O << LSS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
O << "\n" << IndentStr << "};\n";
O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
@@ -220,10 +217,9 @@
O << IndentStr << "static const MCPhysReg ShadowRegList"
<< ShadowRegListNumber << "[] = {\n";
O << IndentStr << " ";
- for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i) {
- if (i != 0) O << ", ";
- O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
- }
+ ListSeparator LS;
+ for (unsigned i = 0, e = ShadowRegList->size(); i != e; ++i)
+ O << LS << getQualifiedName(ShadowRegList->getElementAsRecord(i));
O << "\n" << IndentStr << "};\n";
O << IndentStr << "unsigned Offset" << ++Counter
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeBeadsGen.cpp b/src/llvm-project/llvm/utils/TableGen/CodeBeadsGen.cpp
new file mode 100644
index 0000000..18a6d6d
--- /dev/null
+++ b/src/llvm-project/llvm/utils/TableGen/CodeBeadsGen.cpp
@@ -0,0 +1,137 @@
+//===---------- CodeBeadsGen.cpp - Code Beads Generator -------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// CodeBeads are data fields carrying auxiliary information for instructions.
+//
+// Under the hood it's simply implemented by a `bits` field (with arbitrary
+// length) in each TG instruction description, where this TG backend will
+// generate a helper function to access it.
+//
+// This is especially useful for expressing variable length encoding
+// instructions and complex addressing modes. Since in those cases each
+// instruction is usually associated with large amount of information like
+// addressing mode details used on a specific operand. Instead of retreating to
+// ad-hoc methods to figure out these information when encoding an instruction,
+// CodeBeads provide a clean table for the instruction encoder to lookup.
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenTarget.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/TableGen/Error.h"
+#include "llvm/TableGen/Record.h"
+#include "llvm/TableGen/TableGenBackend.h"
+#include <map>
+#include <string>
+#include <vector>
+using namespace llvm;
+
+namespace {
+
+class CodeBeadsGen {
+ RecordKeeper &Records;
+
+public:
+ CodeBeadsGen(RecordKeeper &R) : Records(R) {}
+ void run(raw_ostream &OS);
+};
+
+void CodeBeadsGen::run(raw_ostream &OS) {
+ CodeGenTarget Target(Records);
+ std::vector<Record *> Insts = Records.getAllDerivedDefinitions("Instruction");
+
+ // For little-endian instruction bit encodings, reverse the bit order
+ Target.reverseBitsForLittleEndianEncoding();
+
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions =
+ Target.getInstructionsByEnumValue();
+
+ // Emit function declaration
+ OS << "const uint8_t *llvm::" << Target.getInstNamespace();
+ OS << "::getMCInstrBeads(unsigned Opcode) {\n";
+
+ // First, get the maximum bit length among all beads. And do some
+ // simple validation
+ unsigned MaxBitLength = 0;
+
+ for (const CodeGenInstruction *CGI : NumberedInstructions) {
+ Record *R = CGI->TheDef;
+ if (!R->getValue("Beads"))
+ continue;
+
+ BitsInit *BI = R->getValueAsBitsInit("Beads");
+ if (!BI->isComplete()) {
+ PrintFatalError(R->getLoc(), "Record `" + R->getName() +
+ "', bit field 'Beads' is not complete");
+ }
+
+ MaxBitLength = std::max(MaxBitLength, BI->getNumBits());
+ }
+
+ // Number of bytes
+ unsigned Parts = MaxBitLength / 8;
+
+ // Emit instruction base values
+ OS << " static const uint8_t InstBits[][" << Parts << "] = {\n";
+ for (const CodeGenInstruction *CGI : NumberedInstructions) {
+ Record *R = CGI->TheDef;
+
+ if (R->getValueAsString("Namespace") == "TargetOpcode" ||
+ !R->getValue("Beads")) {
+ OS << "\t{ 0x0 },\t// ";
+ if (R->getValueAsBit("isPseudo"))
+ OS << "(Pseudo) ";
+ OS << R->getName() << "\n";
+ continue;
+ }
+
+ BitsInit *BI = R->getValueAsBitsInit("Beads");
+
+ // Convert to byte array:
+ // [dcba] -> [a][b][c][d]
+ OS << "\t{";
+ for (unsigned p = 0; p < Parts; ++p) {
+ unsigned Right = 8 * p;
+ unsigned Left = Right + 8;
+
+ uint8_t Value = 0;
+ for (unsigned i = Right; i != Left; ++i) {
+ unsigned Shift = i % 8;
+ if (auto *B = dyn_cast<BitInit>(BI->getBit(i))) {
+ Value |= (static_cast<uint8_t>(B->getValue()) << Shift);
+ } else {
+ PrintFatalError(R->getLoc(), "Record `" + R->getName() +
+ "', bit 'Beads[" + Twine(i) +
+ "]' is not defined");
+ }
+ }
+
+ if (p)
+ OS << ',';
+ OS << " 0x";
+ OS.write_hex(Value);
+ OS << "";
+ }
+ OS << " }," << '\t' << "// " << R->getName() << "\n";
+ }
+ OS << "\t{ 0x0 }\n };\n";
+
+ // Emit initial function code
+ OS << " return InstBits[Opcode];\n"
+ << "}\n\n";
+}
+
+} // End anonymous namespace
+
+namespace llvm {
+
+void EmitCodeBeads(RecordKeeper &RK, raw_ostream &OS) {
+ emitSourceFileHeader("Machine Code Beads", OS);
+ CodeBeadsGen(RK).run(OS);
+}
+
+} // namespace llvm
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp b/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp
index 53bf953..ffc2878 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeEmitterGen.cpp
@@ -272,7 +272,7 @@
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
Case += " switch (HwMode) {\n";
Case += " default: llvm_unreachable(\"Unhandled HwMode\");\n";
- for (auto &KV : EBM.Map) {
+ for (auto &KV : EBM) {
Case += " case " + itostr(KV.first) + ": {\n";
Case += getInstructionCaseForEncoding(R, KV.second, Target);
Case += " break;\n";
@@ -409,7 +409,7 @@
if (const RecordVal *RV = R->getValue("EncodingInfos")) {
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
- for (auto &KV : EBM.Map) {
+ for (auto &KV : EBM) {
BitsInit *BI = KV.second->getValueAsBitsInit("Inst");
BitWidth = std::max(BitWidth, BI->getNumBits());
HwModes.insert(KV.first);
@@ -461,9 +461,7 @@
std::map<std::string, std::vector<std::string>> CaseMap;
// Construct all cases statement for each opcode
- for (std::vector<Record*>::iterator IC = Insts.begin(), EC = Insts.end();
- IC != EC; ++IC) {
- Record *R = *IC;
+ for (Record *R : Insts) {
if (R->getValueAsString("Namespace") == "TargetOpcode" ||
R->getValueAsBit("isPseudo"))
continue;
@@ -483,8 +481,8 @@
<< " Inst = Inst.zext(" << BitWidth << ");\n"
<< " if (Scratch.getBitWidth() != " << BitWidth << ")\n"
<< " Scratch = Scratch.zext(" << BitWidth << ");\n"
- << " LoadIntFromMemory(Inst, (uint8_t *)&InstBits[opcode * " << NumWords
- << "], " << NumBytes << ");\n"
+ << " LoadIntFromMemory(Inst, (const uint8_t *)&InstBits[opcode * "
+ << NumWords << "], " << NumBytes << ");\n"
<< " APInt &Value = Inst;\n"
<< " APInt &op = Scratch;\n"
<< " switch (opcode) {\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index 1ca4a68..c1a3a34 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "CodeGenDAGPatterns.h"
-#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
@@ -111,10 +110,8 @@
bool ContainsDefault = false;
MVT DT = MVT::Other;
- SmallDenseSet<unsigned, 4> Modes;
for (const auto &P : VVT) {
unsigned M = P.first;
- Modes.insert(M);
// Make sure there exists a set for each specific mode from VVT.
Changed |= getOrCreate(M).insert(P.second).second;
// Cache VVT's default mode.
@@ -128,7 +125,7 @@
// modes in "this" that do not exist in VVT.
if (ContainsDefault)
for (auto &I : *this)
- if (!Modes.count(I.first))
+ if (!VVT.hasMode(I.first))
Changed |= I.second.insert(DT).second;
return Changed;
@@ -205,11 +202,9 @@
array_pod_sort(Types.begin(), Types.end());
OS << '[';
- for (unsigned i = 0, e = Types.size(); i != e; ++i) {
- OS << ValueTypeByHwMode::getMVTName(Types[i]);
- if (i != e-1)
- OS << ' ';
- }
+ ListSeparator LS(" ");
+ for (const MVT &T : Types)
+ OS << LS << ValueTypeByHwMode::getMVTName(T);
OS << ']';
}
@@ -226,7 +221,7 @@
if (HaveDefault != VTSHaveDefault)
return false;
- SmallDenseSet<unsigned, 4> Modes;
+ SmallSet<unsigned, 4> Modes;
for (auto &I : *this)
Modes.insert(I.first);
for (const auto &I : VTS)
@@ -470,7 +465,8 @@
assert(Small.hasDefault() && Big.hasDefault());
- std::vector<unsigned> Modes = union_modes(Small, Big);
+ SmallVector<unsigned, 4> Modes;
+ union_modes(Small, Big, Modes);
// 1. Only allow integer or floating point types and make sure that
// both sides are both integer or both floating point.
@@ -577,7 +573,9 @@
if (Elem.empty())
Changed |= EnforceScalar(Elem);
- for (unsigned M : union_modes(Vec, Elem)) {
+ SmallVector<unsigned, 4> Modes;
+ union_modes(Vec, Elem, Modes);
+ for (unsigned M : Modes) {
TypeSetByHwMode::SetType &V = Vec.get(M);
TypeSetByHwMode::SetType &E = Elem.get(M);
@@ -585,7 +583,7 @@
Changed |= berase_if(E, isVector); // Vector = !scalar
assert(!V.empty() && !E.empty());
- SmallSet<MVT,4> VT, ST;
+ MachineValueTypeSet VT, ST;
// Collect element types from the "vector" set.
for (MVT T : V)
VT.insert(T.getVectorElementType());
@@ -632,7 +630,7 @@
return false;
if (B.getVectorElementType() != P.getVectorElementType())
return false;
- return B.getVectorNumElements() < P.getVectorNumElements();
+ return B.getVectorMinNumElements() < P.getVectorMinNumElements();
};
/// Return true if S has no element (vector type) that T is a sub-vector of,
@@ -660,7 +658,9 @@
if (Sub.empty())
Changed |= EnforceVector(Sub);
- for (unsigned M : union_modes(Vec, Sub)) {
+ SmallVector<unsigned, 4> Modes;
+ union_modes(Vec, Sub, Modes);
+ for (unsigned M : Modes) {
TypeSetByHwMode::SetType &S = Sub.get(M);
TypeSetByHwMode::SetType &V = Vec.get(M);
@@ -696,19 +696,25 @@
// An actual vector type cannot have 0 elements, so we can treat scalars
// as zero-length vectors. This way both vectors and scalars can be
// processed identically.
- auto NoLength = [](const SmallSet<unsigned,2> &Lengths, MVT T) -> bool {
- return !Lengths.count(T.isVector() ? T.getVectorNumElements() : 0);
+ auto NoLength = [](const SmallDenseSet<ElementCount> &Lengths,
+ MVT T) -> bool {
+ return !Lengths.count(T.isVector() ? T.getVectorElementCount()
+ : ElementCount::getNull());
};
- for (unsigned M : union_modes(V, W)) {
+ SmallVector<unsigned, 4> Modes;
+ union_modes(V, W, Modes);
+ for (unsigned M : Modes) {
TypeSetByHwMode::SetType &VS = V.get(M);
TypeSetByHwMode::SetType &WS = W.get(M);
- SmallSet<unsigned,2> VN, WN;
+ SmallDenseSet<ElementCount> VN, WN;
for (MVT T : VS)
- VN.insert(T.isVector() ? T.getVectorNumElements() : 0);
+ VN.insert(T.isVector() ? T.getVectorElementCount()
+ : ElementCount::getNull());
for (MVT T : WS)
- WN.insert(T.isVector() ? T.getVectorNumElements() : 0);
+ WN.insert(T.isVector() ? T.getVectorElementCount()
+ : ElementCount::getNull());
Changed |= berase_if(VS, std::bind(NoLength, WN, std::placeholders::_1));
Changed |= berase_if(WS, std::bind(NoLength, VN, std::placeholders::_1));
@@ -716,6 +722,15 @@
return Changed;
}
+namespace {
+struct TypeSizeComparator {
+ bool operator()(const TypeSize &LHS, const TypeSize &RHS) const {
+ return std::make_tuple(LHS.isScalable(), LHS.getKnownMinValue()) <
+ std::make_tuple(RHS.isScalable(), RHS.getKnownMinValue());
+ }
+};
+} // end anonymous namespace
+
/// 1. Ensure that for each type T in A, there exists a type U in B,
/// such that T and U have equal size in bits.
/// 2. Ensure that for each type U in B, there exists a type T in A
@@ -730,14 +745,18 @@
if (B.empty())
Changed |= EnforceAny(B);
- auto NoSize = [](const SmallSet<TypeSize, 2> &Sizes, MVT T) -> bool {
+ typedef SmallSet<TypeSize, 2, TypeSizeComparator> TypeSizeSet;
+
+ auto NoSize = [](const TypeSizeSet &Sizes, MVT T) -> bool {
return !Sizes.count(T.getSizeInBits());
};
- for (unsigned M : union_modes(A, B)) {
+ SmallVector<unsigned, 4> Modes;
+ union_modes(A, B, Modes);
+ for (unsigned M : Modes) {
TypeSetByHwMode::SetType &AS = A.get(M);
TypeSetByHwMode::SetType &BS = B.get(M);
- SmallSet<TypeSize, 2> AN, BN;
+ TypeSizeSet AN, BN;
for (MVT T : AS)
AN.insert(T.getSizeInBits());
@@ -837,7 +856,11 @@
"(use -print-records with llvm-tblgen to see all "
"expanded records).\n";
Infer.TP.dump();
- llvm_unreachable(nullptr);
+ dbgs() << "Generated from record:\n";
+ Infer.TP.getRecord()->dump();
+ PrintFatalError(Infer.TP.getRecord()->getLoc(),
+ "Type set is empty for each HW mode in '" +
+ Infer.TP.getRecord()->getName() + "'");
}
}
#endif
@@ -980,12 +1003,9 @@
Code += "unsigned AddrSpace = cast<MemSDNode>(N)->getAddressSpace();\n"
" if (";
- bool First = true;
+ ListSeparator LS(" && ");
for (Init *Val : AddressSpaces->getValues()) {
- if (First)
- First = false;
- else
- Code += " && ";
+ Code += LS;
IntInit *IntVal = dyn_cast<IntInit>(Val);
if (!IntVal) {
@@ -1015,33 +1035,33 @@
}
if (isAtomic() && isAtomicOrderingMonotonic())
- Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != "
"AtomicOrdering::Monotonic) return false;\n";
if (isAtomic() && isAtomicOrderingAcquire())
- Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != "
"AtomicOrdering::Acquire) return false;\n";
if (isAtomic() && isAtomicOrderingRelease())
- Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != "
"AtomicOrdering::Release) return false;\n";
if (isAtomic() && isAtomicOrderingAcquireRelease())
- Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != "
"AtomicOrdering::AcquireRelease) return false;\n";
if (isAtomic() && isAtomicOrderingSequentiallyConsistent())
- Code += "if (cast<AtomicSDNode>(N)->getOrdering() != "
+ Code += "if (cast<AtomicSDNode>(N)->getMergedOrdering() != "
"AtomicOrdering::SequentiallyConsistent) return false;\n";
if (isAtomic() && isAtomicOrderingAcquireOrStronger())
- Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ Code += "if (!isAcquireOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) "
"return false;\n";
if (isAtomic() && isAtomicOrderingWeakerThanAcquire())
- Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ Code += "if (isAcquireOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) "
"return false;\n";
if (isAtomic() && isAtomicOrderingReleaseOrStronger())
- Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ Code += "if (!isReleaseOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) "
"return false;\n";
if (isAtomic() && isAtomicOrderingWeakerThanRelease())
- Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getOrdering())) "
+ Code += "if (isReleaseOrStronger(cast<AtomicSDNode>(N)->getMergedOrdering())) "
"return false;\n";
if (isLoad() || isStore()) {
@@ -1242,7 +1262,7 @@
StringRef TreePredicateFn::getImmTypeIdentifier() const {
if (immCodeUsesAPInt())
return "APInt";
- else if (immCodeUsesAPFloat())
+ if (immCodeUsesAPFloat())
return "APFloat";
return "I64";
}
@@ -1423,24 +1443,50 @@
return getPatternSize(getSrcPattern(), CGP) + getAddedComplexity();
}
+void PatternToMatch::getPredicateRecords(
+ SmallVectorImpl<Record *> &PredicateRecs) const {
+ for (Init *I : Predicates->getValues()) {
+ if (DefInit *Pred = dyn_cast<DefInit>(I)) {
+ Record *Def = Pred->getDef();
+ if (!Def->isSubClassOf("Predicate")) {
+#ifndef NDEBUG
+ Def->dump();
+#endif
+ llvm_unreachable("Unknown predicate type!");
+ }
+ PredicateRecs.push_back(Def);
+ }
+ }
+ // Sort so that different orders get canonicalized to the same string.
+ llvm::sort(PredicateRecs, LessRecord());
+}
+
/// getPredicateCheck - Return a single string containing all of this
/// pattern's predicates concatenated with "&&" operators.
///
std::string PatternToMatch::getPredicateCheck() const {
- SmallVector<const Predicate*,4> PredList;
- for (const Predicate &P : Predicates) {
- if (!P.getCondString().empty())
- PredList.push_back(&P);
- }
- llvm::sort(PredList, deref<std::less<>>());
+ SmallVector<Record *, 4> PredicateRecs;
+ getPredicateRecords(PredicateRecs);
- std::string Check;
- for (unsigned i = 0, e = PredList.size(); i != e; ++i) {
- if (i != 0)
- Check += " && ";
- Check += '(' + PredList[i]->getCondString() + ')';
+ SmallString<128> PredicateCheck;
+ for (Record *Pred : PredicateRecs) {
+ StringRef CondString = Pred->getValueAsString("CondString");
+ if (CondString.empty())
+ continue;
+ if (!PredicateCheck.empty())
+ PredicateCheck += " && ";
+ PredicateCheck += "(";
+ PredicateCheck += CondString;
+ PredicateCheck += ")";
}
- return Check;
+
+ if (!HwModeFeatures.empty()) {
+ if (!PredicateCheck.empty())
+ PredicateCheck += " && ";
+ PredicateCheck += HwModeFeatures;
+ }
+
+ return std::string(PredicateCheck);
}
//===----------------------------------------------------------------------===//
@@ -1791,7 +1837,7 @@
// The number of results of a fragment with alternative records is the
// maximum number of results across all alternatives.
unsigned NumResults = 0;
- for (auto T : PFRec->getTrees())
+ for (const auto &T : PFRec->getTrees())
NumResults = std::max(NumResults, T->getNumTypes());
return NumResults;
}
@@ -1857,9 +1903,9 @@
if (!isLeaf()) {
if (getNumChildren() != 0) {
OS << " ";
- getChild(0)->print(OS);
- for (unsigned i = 1, e = getNumChildren(); i != e; ++i) {
- OS << ", ";
+ ListSeparator LS;
+ for (unsigned i = 0, e = getNumChildren(); i != e; ++i) {
+ OS << LS;
getChild(i)->print(OS);
}
}
@@ -2013,10 +2059,13 @@
if (ChildAlternatives[i].empty())
return;
- for (auto NewChild : ChildAlternatives[i])
- assert((Child->getPredicateCalls().empty() ||
- NewChild->getPredicateCalls() == Child->getPredicateCalls()) &&
- "Non-empty child predicate clobbered!");
+ assert((Child->getPredicateCalls().empty() ||
+ llvm::all_of(ChildAlternatives[i],
+ [&](const TreePatternNodePtr &NewChild) {
+ return NewChild->getPredicateCalls() ==
+ Child->getPredicateCalls();
+ })) &&
+ "Non-empty child predicate clobbered!");
}
// The end result is an all-pairs construction of the resultant pattern.
@@ -2088,7 +2137,7 @@
}
// Loop over all fragment alternatives.
- for (auto Alternative : Frag->getTrees()) {
+ for (const auto &Alternative : Frag->getTrees()) {
TreePatternNodePtr FragTree = Alternative->clone();
if (!PredFn.isAlwaysTrue())
@@ -2637,6 +2686,8 @@
return true;
if (N->isLeaf() && isa<IntInit>(N->getLeafValue()))
return true;
+ if (isImmAllOnesAllZerosMatch(N))
+ return true;
return false;
}
@@ -2802,7 +2853,8 @@
ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0));
// Apply the type cast.
- assert(New->getNumTypes() == 1 && "FIXME: Unhandled");
+ if (New->getNumTypes() != 1)
+ error("Type cast can only have one type!");
const CodeGenHwModes &CGH = getDAGPatterns().getTargetInfo().getHwModes();
New->UpdateNodeType(0, getValueTypeByHwMode(Operator, CGH), *this);
@@ -3030,9 +3082,10 @@
void TreePattern::print(raw_ostream &OS) const {
OS << getRecord()->getName();
if (!Args.empty()) {
- OS << "(" << Args[0];
- for (unsigned i = 1, e = Args.size(); i != e; ++i)
- OS << ", " << Args[i];
+ OS << "(";
+ ListSeparator LS;
+ for (const std::string &Arg : Args)
+ OS << LS << Arg;
OS << ")";
}
OS << ": ";
@@ -3070,15 +3123,15 @@
ParsePatternFragments(/*OutFrags*/true);
ParsePatterns();
+ // Generate variants. For example, commutative patterns can match
+ // multiple ways. Add them to PatternsToMatch as well.
+ GenerateVariants();
+
// Break patterns with parameterized types into a series of patterns,
// where each one has a fixed type and is predicated on the conditions
// of the associated HW mode.
ExpandHwModeBasedTypes();
- // Generate variants. For example, commutative patterns can match
- // multiple ways. Add them to PatternsToMatch as well.
- GenerateVariants();
-
// Infer instruction flags. For example, we can detect loads,
// stores, and side effects in many cases by examining an
// instruction's pattern.
@@ -3201,7 +3254,7 @@
// it.
Record *Transform = Frag->getValueAsDef("OperandTransform");
if (!getSDNodeTransform(Transform).second.empty()) // not noop xform?
- for (auto T : P->getTrees())
+ for (const auto &T : P->getTrees())
T->setTransformFn(Transform);
}
@@ -3470,6 +3523,9 @@
if (N->getNumChildren() != 1 || !N->getChild(0)->isLeaf())
return false;
+ if (N->getOperator()->isSubClassOf("ComplexPattern"))
+ return false;
+
const SDNodeInfo &OpInfo = CDP.getSDNodeInfo(N->getOperator());
if (OpInfo.getNumResults() != 1 || OpInfo.getNumOperands() != 1)
return false;
@@ -3671,9 +3727,9 @@
TreePatternNodePtr Pat = I.getTree(j);
if (Pat->getNumTypes() != 0) {
raw_svector_ostream OS(TypesString);
+ ListSeparator LS;
for (unsigned k = 0, ke = Pat->getNumTypes(); k != ke; ++k) {
- if (k > 0)
- OS << ", ";
+ OS << LS;
Pat->getExtType(k).writeToStream(OS);
}
I.error("Top-level forms in instruction pattern should have"
@@ -3904,20 +3960,6 @@
}
}
-std::vector<Predicate> CodeGenDAGPatterns::makePredList(ListInit *L) {
- std::vector<Predicate> Preds;
- for (Init *I : L->getValues()) {
- if (DefInit *Pred = dyn_cast<DefInit>(I))
- Preds.push_back(Pred->getDef());
- else
- llvm_unreachable("Non-def on the list");
- }
-
- // Sort so that different orders get canonicalized to the same string.
- llvm::sort(Preds);
- return Preds;
-}
-
void CodeGenDAGPatterns::AddPatternToMatch(TreePattern *Pattern,
PatternToMatch &&PTM) {
// Do some sanity checking on the pattern we're about to match.
@@ -3958,7 +4000,7 @@
SrcNames[Entry.first].second == 1)
Pattern->error("Pattern has dead named input: $" + Entry.first);
- PatternsToMatch.push_back(PTM);
+ PatternsToMatch.push_back(std::move(PTM));
}
void CodeGenDAGPatterns::InferInstructionFlags() {
@@ -4030,8 +4072,7 @@
/// Verify instruction flags against pattern node properties.
void CodeGenDAGPatterns::VerifyInstructionFlags() {
unsigned Errors = 0;
- for (ptm_iterator I = ptm_begin(), E = ptm_end(); I != E; ++I) {
- const PatternToMatch &PTM = *I;
+ for (const PatternToMatch &PTM : ptms()) {
SmallVector<Record*, 8> Instrs;
getInstructionsInTree(PTM.getDstPattern(), Instrs);
if (Instrs.empty())
@@ -4172,7 +4213,7 @@
// resolve cases where the input type is known to be a pointer type (which
// is considered resolved), but the result knows it needs to be 32- or
// 64-bits. Infer the other way for good measure.
- for (auto T : Pattern.getTrees())
+ for (const auto &T : Pattern.getTrees())
for (unsigned i = 0, e = std::min(Result.getOnlyTree()->getNumTypes(),
T->getNumTypes());
i != e; ++i) {
@@ -4226,11 +4267,10 @@
// will lead to a contradiction, which is not an error however, but
// a sign that this pattern will simply never match.
if (Temp.getOnlyTree()->hasPossibleType())
- for (auto T : Pattern.getTrees())
+ for (const auto &T : Pattern.getTrees())
if (T->hasPossibleType())
AddPatternToMatch(&Pattern,
- PatternToMatch(TheDef, makePredList(Preds),
- T, Temp.getOnlyTree(),
+ PatternToMatch(TheDef, Preds, T, Temp.getOnlyTree(),
InstImpResults, Complexity,
TheDef->getID()));
}
@@ -4281,32 +4321,29 @@
void CodeGenDAGPatterns::ExpandHwModeBasedTypes() {
const CodeGenHwModes &CGH = getTargetInfo().getHwModes();
- std::map<unsigned,std::vector<Predicate>> ModeChecks;
- std::vector<PatternToMatch> Copy = PatternsToMatch;
- PatternsToMatch.clear();
+ std::vector<PatternToMatch> Copy;
+ PatternsToMatch.swap(Copy);
- auto AppendPattern = [this, &ModeChecks](PatternToMatch &P, unsigned Mode) {
- TreePatternNodePtr NewSrc = P.SrcPattern->clone();
- TreePatternNodePtr NewDst = P.DstPattern->clone();
+ auto AppendPattern = [this](PatternToMatch &P, unsigned Mode,
+ StringRef Check) {
+ TreePatternNodePtr NewSrc = P.getSrcPattern()->clone();
+ TreePatternNodePtr NewDst = P.getDstPattern()->clone();
if (!NewSrc->setDefaultMode(Mode) || !NewDst->setDefaultMode(Mode)) {
return;
}
- std::vector<Predicate> Preds = P.Predicates;
- const std::vector<Predicate> &MC = ModeChecks[Mode];
- llvm::append_range(Preds, MC);
- PatternsToMatch.emplace_back(P.getSrcRecord(), Preds, std::move(NewSrc),
- std::move(NewDst), P.getDstRegs(),
- P.getAddedComplexity(), Record::getNewUID(),
- Mode);
+ PatternsToMatch.emplace_back(P.getSrcRecord(), P.getPredicates(),
+ std::move(NewSrc), std::move(NewDst),
+ P.getDstRegs(), P.getAddedComplexity(),
+ Record::getNewUID(), Mode, Check);
};
for (PatternToMatch &P : Copy) {
TreePatternNodePtr SrcP = nullptr, DstP = nullptr;
- if (P.SrcPattern->hasProperTypeByHwMode())
- SrcP = P.SrcPattern;
- if (P.DstPattern->hasProperTypeByHwMode())
- DstP = P.DstPattern;
+ if (P.getSrcPattern()->hasProperTypeByHwMode())
+ SrcP = P.getSrcPatternShared();
+ if (P.getDstPattern()->hasProperTypeByHwMode())
+ DstP = P.getDstPatternShared();
if (!SrcP && !DstP) {
PatternsToMatch.push_back(P);
continue;
@@ -4329,31 +4366,27 @@
// duplicated patterns with different predicate checks, construct the
// default check as a negation of all predicates that are actually present
// in the source/destination patterns.
- std::vector<Predicate> DefaultPred;
+ SmallString<128> DefaultCheck;
for (unsigned M : Modes) {
if (M == DefaultMode)
continue;
- if (ModeChecks.find(M) != ModeChecks.end())
- continue;
// Fill the map entry for this mode.
const HwMode &HM = CGH.getMode(M);
- ModeChecks[M].emplace_back(Predicate(HM.Features, true));
+ AppendPattern(P, M, "(MF->getSubtarget().checkFeatures(\"" + HM.Features + "\"))");
// Add negations of the HM's predicates to the default predicate.
- DefaultPred.emplace_back(Predicate(HM.Features, false));
- }
-
- for (unsigned M : Modes) {
- if (M == DefaultMode)
- continue;
- AppendPattern(P, M);
+ if (!DefaultCheck.empty())
+ DefaultCheck += " && ";
+ DefaultCheck += "(!(MF->getSubtarget().checkFeatures(\"";
+ DefaultCheck += HM.Features;
+ DefaultCheck += "\")))";
}
bool HasDefault = Modes.count(DefaultMode);
if (HasDefault)
- AppendPattern(P, DefaultMode);
+ AppendPattern(P, DefaultMode, DefaultCheck);
}
}
@@ -4635,17 +4668,7 @@
// intentionally do not reconsider these. Any variants of added patterns have
// already been added.
//
- const unsigned NumOriginalPatterns = PatternsToMatch.size();
- BitVector MatchedPatterns(NumOriginalPatterns);
- std::vector<BitVector> MatchedPredicates(NumOriginalPatterns,
- BitVector(NumOriginalPatterns));
-
- typedef std::pair<MultipleUseVarSet, std::vector<TreePatternNodePtr>>
- DepsAndVariants;
- std::map<unsigned, DepsAndVariants> PatternsWithVariants;
-
- // Collect patterns with more than one variant.
- for (unsigned i = 0; i != NumOriginalPatterns; ++i) {
+ for (unsigned i = 0, e = PatternsToMatch.size(); i != e; ++i) {
MultipleUseVarSet DepVars;
std::vector<TreePatternNodePtr> Variants;
FindDepVars(PatternsToMatch[i].getSrcPattern(), DepVars);
@@ -4655,6 +4678,9 @@
GenerateVariantsOf(PatternsToMatch[i].getSrcPatternShared(), Variants,
*this, DepVars);
+ assert(PatternsToMatch[i].getHwModeFeatures().empty() &&
+ "HwModes should not have been expanded yet!");
+
assert(!Variants.empty() && "Must create at least original variant!");
if (Variants.size() == 1) // No additional variants for this pattern.
continue;
@@ -4662,40 +4688,8 @@
LLVM_DEBUG(errs() << "FOUND VARIANTS OF: ";
PatternsToMatch[i].getSrcPattern()->dump(); errs() << "\n");
- PatternsWithVariants[i] = std::make_pair(DepVars, Variants);
-
- // Cache matching predicates.
- if (MatchedPatterns[i])
- continue;
-
- const std::vector<Predicate> &Predicates =
- PatternsToMatch[i].getPredicates();
-
- BitVector &Matches = MatchedPredicates[i];
- MatchedPatterns.set(i);
- Matches.set(i);
-
- // Don't test patterns that have already been cached - it won't match.
- for (unsigned p = 0; p != NumOriginalPatterns; ++p)
- if (!MatchedPatterns[p])
- Matches[p] = (Predicates == PatternsToMatch[p].getPredicates());
-
- // Copy this to all the matching patterns.
- for (int p = Matches.find_first(); p != -1; p = Matches.find_next(p))
- if (p != (int)i) {
- MatchedPatterns.set(p);
- MatchedPredicates[p] = Matches;
- }
- }
-
- for (auto it : PatternsWithVariants) {
- unsigned i = it.first;
- const MultipleUseVarSet &DepVars = it.second.first;
- const std::vector<TreePatternNodePtr> &Variants = it.second.second;
-
for (unsigned v = 0, e = Variants.size(); v != e; ++v) {
TreePatternNodePtr Variant = Variants[v];
- BitVector &Matches = MatchedPredicates[i];
LLVM_DEBUG(errs() << " VAR#" << v << ": "; Variant->dump();
errs() << "\n");
@@ -4704,7 +4698,8 @@
bool AlreadyExists = false;
for (unsigned p = 0, e = PatternsToMatch.size(); p != e; ++p) {
// Skip if the top level predicates do not match.
- if (!Matches[p])
+ if ((i != p) && (PatternsToMatch[i].getPredicates() !=
+ PatternsToMatch[p].getPredicates()))
continue;
// Check to see if this variant already exists.
if (Variant->isIsomorphicTo(PatternsToMatch[p].getSrcPattern(),
@@ -4718,16 +4713,13 @@
if (AlreadyExists) continue;
// Otherwise, add it to the list of patterns we have.
- PatternsToMatch.push_back(PatternToMatch(
+ PatternsToMatch.emplace_back(
PatternsToMatch[i].getSrcRecord(), PatternsToMatch[i].getPredicates(),
Variant, PatternsToMatch[i].getDstPatternShared(),
PatternsToMatch[i].getDstRegs(),
- PatternsToMatch[i].getAddedComplexity(), Record::getNewUID()));
- MatchedPredicates.push_back(Matches);
-
- // Add a new match the same as this pattern.
- for (auto &P : MatchedPredicates)
- P.push_back(P[i]);
+ PatternsToMatch[i].getAddedComplexity(), Record::getNewUID(),
+ PatternsToMatch[i].getForceMode(),
+ PatternsToMatch[i].getHwModeFeatures());
}
LLVM_DEBUG(errs() << "\n");
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h
index bc939fe..a69f1e2 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenDAGPatterns.h
@@ -200,9 +200,7 @@
TypeSetByHwMode(ArrayRef<ValueTypeByHwMode> VTList);
SetType &getOrCreate(unsigned Mode) {
- if (hasMode(Mode))
- return get(Mode);
- return Map.insert({Mode,SetType()}).first->second;
+ return Map[Mode];
}
bool isValueTypeByHwMode(bool AllowEmpty) const;
@@ -1049,89 +1047,43 @@
TreePatternNodePtr getResultPattern() const { return ResultPattern; }
};
-/// This class represents a condition that has to be satisfied for a pattern
-/// to be tried. It is a generalization of a class "Pattern" from Target.td:
-/// in addition to the Target.td's predicates, this class can also represent
-/// conditions associated with HW modes. Both types will eventually become
-/// strings containing C++ code to be executed, the difference is in how
-/// these strings are generated.
-class Predicate {
-public:
- Predicate(Record *R, bool C = true) : Def(R), IfCond(C), IsHwMode(false) {
- assert(R->isSubClassOf("Predicate") &&
- "Predicate objects should only be created for records derived"
- "from Predicate class");
- }
- Predicate(StringRef FS, bool C = true) : Def(nullptr), Features(FS.str()),
- IfCond(C), IsHwMode(true) {}
-
- /// Return a string which contains the C++ condition code that will serve
- /// as a predicate during instruction selection.
- std::string getCondString() const {
- // The string will excute in a subclass of SelectionDAGISel.
- // Cast to std::string explicitly to avoid ambiguity with StringRef.
- std::string C = IsHwMode
- ? std::string("MF->getSubtarget().checkFeatures(\"" +
- Features + "\")")
- : std::string(Def->getValueAsString("CondString"));
- if (C.empty())
- return "";
- return IfCond ? C : "!("+C+')';
- }
-
- bool operator==(const Predicate &P) const {
- return IfCond == P.IfCond && IsHwMode == P.IsHwMode && Def == P.Def;
- }
- bool operator<(const Predicate &P) const {
- if (IsHwMode != P.IsHwMode)
- return IsHwMode < P.IsHwMode;
- assert(!Def == !P.Def && "Inconsistency between Def and IsHwMode");
- if (IfCond != P.IfCond)
- return IfCond < P.IfCond;
- if (Def)
- return LessRecord()(Def, P.Def);
- return Features < P.Features;
- }
- Record *Def; ///< Predicate definition from .td file, null for
- ///< HW modes.
- std::string Features; ///< Feature string for HW mode.
- bool IfCond; ///< The boolean value that the condition has to
- ///< evaluate to for this predicate to be true.
- bool IsHwMode; ///< Does this predicate correspond to a HW mode?
-};
-
/// PatternToMatch - Used by CodeGenDAGPatterns to keep tab of patterns
/// processed to produce isel.
class PatternToMatch {
-public:
- PatternToMatch(Record *srcrecord, std::vector<Predicate> preds,
- TreePatternNodePtr src, TreePatternNodePtr dst,
- std::vector<Record *> dstregs, int complexity,
- unsigned uid, unsigned setmode = 0)
- : SrcRecord(srcrecord), SrcPattern(src), DstPattern(dst),
- Predicates(std::move(preds)), Dstregs(std::move(dstregs)),
- AddedComplexity(complexity), ID(uid), ForceMode(setmode) {}
-
Record *SrcRecord; // Originating Record for the pattern.
+ ListInit *Predicates; // Top level predicate conditions to match.
TreePatternNodePtr SrcPattern; // Source pattern to match.
TreePatternNodePtr DstPattern; // Resulting pattern.
- std::vector<Predicate> Predicates; // Top level predicate conditions
- // to match.
std::vector<Record*> Dstregs; // Physical register defs being matched.
+ std::string HwModeFeatures;
int AddedComplexity; // Add to matching pattern complexity.
unsigned ID; // Unique ID for the record.
unsigned ForceMode; // Force this mode in type inference when set.
+public:
+ PatternToMatch(Record *srcrecord, ListInit *preds, TreePatternNodePtr src,
+ TreePatternNodePtr dst, std::vector<Record *> dstregs,
+ int complexity, unsigned uid, unsigned setmode = 0,
+ const Twine &hwmodefeatures = "")
+ : SrcRecord(srcrecord), Predicates(preds), SrcPattern(src),
+ DstPattern(dst), Dstregs(std::move(dstregs)),
+ HwModeFeatures(hwmodefeatures.str()), AddedComplexity(complexity),
+ ID(uid), ForceMode(setmode) {}
+
Record *getSrcRecord() const { return SrcRecord; }
+ ListInit *getPredicates() const { return Predicates; }
TreePatternNode *getSrcPattern() const { return SrcPattern.get(); }
TreePatternNodePtr getSrcPatternShared() const { return SrcPattern; }
TreePatternNode *getDstPattern() const { return DstPattern.get(); }
TreePatternNodePtr getDstPatternShared() const { return DstPattern; }
const std::vector<Record*> &getDstRegs() const { return Dstregs; }
+ StringRef getHwModeFeatures() const { return HwModeFeatures; }
int getAddedComplexity() const { return AddedComplexity; }
- const std::vector<Predicate> &getPredicates() const { return Predicates; }
+ unsigned getID() const { return ID; }
+ unsigned getForceMode() const { return ForceMode; }
std::string getPredicateCheck() const;
+ void getPredicateRecords(SmallVectorImpl<Record *> &PredicateRecs) const;
/// Compute the complexity metric for the input pattern. This roughly
/// corresponds to the number of nodes that are covered.
@@ -1289,8 +1241,6 @@
void GenerateVariants();
void VerifyInstructionFlags();
- std::vector<Predicate> makePredList(ListInit *L);
-
void ParseOnePattern(Record *TheDef,
TreePattern &Pattern, TreePattern &Result,
const std::vector<Record *> &InstImpResults);
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp
index 960fe08..3933ce6 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.cpp
@@ -177,17 +177,17 @@
}
std::pair<unsigned,unsigned>
-CGIOperandList::ParseOperandName(const std::string &Op, bool AllowWholeOp) {
+CGIOperandList::ParseOperandName(StringRef Op, bool AllowWholeOp) {
if (Op.empty() || Op[0] != '$')
PrintFatalError(TheDef->getLoc(),
TheDef->getName() + ": Illegal operand name: '" + Op + "'");
- std::string OpName = Op.substr(1);
- std::string SubOpName;
+ StringRef OpName = Op.substr(1);
+ StringRef SubOpName;
// Check to see if this is $foo.bar.
- std::string::size_type DotIdx = OpName.find_first_of('.');
- if (DotIdx != std::string::npos) {
+ StringRef::size_type DotIdx = OpName.find_first_of('.');
+ if (DotIdx != StringRef::npos) {
SubOpName = OpName.substr(DotIdx+1);
if (SubOpName.empty())
PrintFatalError(TheDef->getLoc(),
@@ -231,16 +231,16 @@
return std::make_pair(0U, 0U);
}
-static void ParseConstraint(const std::string &CStr, CGIOperandList &Ops,
+static void ParseConstraint(StringRef CStr, CGIOperandList &Ops,
Record *Rec) {
// EARLY_CLOBBER: @early $reg
- std::string::size_type wpos = CStr.find_first_of(" \t");
- std::string::size_type start = CStr.find_first_not_of(" \t");
- std::string Tok = CStr.substr(start, wpos - start);
+ StringRef::size_type wpos = CStr.find_first_of(" \t");
+ StringRef::size_type start = CStr.find_first_not_of(" \t");
+ StringRef Tok = CStr.substr(start, wpos - start);
if (Tok == "@earlyclobber") {
- std::string Name = CStr.substr(wpos+1);
+ StringRef Name = CStr.substr(wpos+1);
wpos = Name.find_first_not_of(" \t");
- if (wpos == std::string::npos)
+ if (wpos == StringRef::npos)
PrintFatalError(
Rec->getLoc(), "Illegal format for @earlyclobber constraint in '" +
Rec->getName() + "': '" + CStr + "'");
@@ -258,8 +258,8 @@
}
// Only other constraint is "TIED_TO" for now.
- std::string::size_type pos = CStr.find_first_of('=');
- if (pos == std::string::npos)
+ StringRef::size_type pos = CStr.find_first_of('=');
+ if (pos == StringRef::npos)
PrintFatalError(
Rec->getLoc(), "Unrecognized constraint '" + CStr +
"' in '" + Rec->getName() + "'");
@@ -267,20 +267,19 @@
// TIED_TO: $src1 = $dst
wpos = CStr.find_first_of(" \t", start);
- if (wpos == std::string::npos || wpos > pos)
+ if (wpos == StringRef::npos || wpos > pos)
PrintFatalError(
Rec->getLoc(), "Illegal format for tied-to constraint in '" +
Rec->getName() + "': '" + CStr + "'");
- std::string LHSOpName =
- std::string(StringRef(CStr).substr(start, wpos - start));
+ StringRef LHSOpName = CStr.substr(start, wpos - start);
std::pair<unsigned,unsigned> LHSOp = Ops.ParseOperandName(LHSOpName, false);
wpos = CStr.find_first_not_of(" \t", pos + 1);
- if (wpos == std::string::npos)
+ if (wpos == StringRef::npos)
PrintFatalError(
Rec->getLoc(), "Illegal format for tied-to constraint: '" + CStr + "'");
- std::string RHSOpName = std::string(StringRef(CStr).substr(wpos));
+ StringRef RHSOpName = CStr.substr(wpos);
std::pair<unsigned,unsigned> RHSOp = Ops.ParseOperandName(RHSOpName, false);
// Sort the operands into order, which should put the output one
@@ -325,29 +324,27 @@
Ops[SrcOp.first].Constraints[SrcOp.second] = NewConstraint;
}
-static void ParseConstraints(const std::string &CStr, CGIOperandList &Ops,
- Record *Rec) {
+static void ParseConstraints(StringRef CStr, CGIOperandList &Ops, Record *Rec) {
if (CStr.empty()) return;
- const std::string delims(",");
- std::string::size_type bidx, eidx;
+ StringRef delims(",");
+ StringRef::size_type bidx, eidx;
bidx = CStr.find_first_not_of(delims);
- while (bidx != std::string::npos) {
+ while (bidx != StringRef::npos) {
eidx = CStr.find_first_of(delims, bidx);
- if (eidx == std::string::npos)
- eidx = CStr.length();
+ if (eidx == StringRef::npos)
+ eidx = CStr.size();
ParseConstraint(CStr.substr(bidx, eidx - bidx), Ops, Rec);
bidx = CStr.find_first_not_of(delims, eidx);
}
}
-void CGIOperandList::ProcessDisableEncoding(std::string DisableEncoding) {
+void CGIOperandList::ProcessDisableEncoding(StringRef DisableEncoding) {
while (1) {
- std::pair<StringRef, StringRef> P = getToken(DisableEncoding, " ,\t");
- std::string OpName = std::string(P.first);
- DisableEncoding = std::string(P.second);
+ StringRef OpName;
+ std::tie(OpName, DisableEncoding) = getToken(DisableEncoding, " ,\t");
if (OpName.empty()) break;
// Figure out which operand this is.
@@ -427,12 +424,11 @@
hasChain_Inferred = false;
// Parse Constraints.
- ParseConstraints(std::string(R->getValueAsString("Constraints")), Operands,
- R);
+ ParseConstraints(R->getValueAsString("Constraints"), Operands, R);
// Parse the DisableEncoding field.
Operands.ProcessDisableEncoding(
- std::string(R->getValueAsString("DisableEncoding")));
+ R->getValueAsString("DisableEncoding"));
// First check for a ComplexDeprecationPredicate.
if (R->getValue("ComplexDeprecationPredicate")) {
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h
index af851a1..e35d219 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenInstruction.h
@@ -182,7 +182,7 @@
/// where $foo is a whole operand and $foo.bar refers to a suboperand.
/// This aborts if the name is invalid. If AllowWholeOp is true, references
/// to operands with suboperands are allowed, otherwise not.
- std::pair<unsigned,unsigned> ParseOperandName(const std::string &Op,
+ std::pair<unsigned,unsigned> ParseOperandName(StringRef Op,
bool AllowWholeOp = true);
/// getFlattenedOperandNumber - Flatten a operand/suboperand pair into a
@@ -211,7 +211,7 @@
return false;
}
- void ProcessDisableEncoding(std::string Value);
+ void ProcessDisableEncoding(StringRef Value);
};
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h b/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h
index c469f66..dbfad3b 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenIntrinsics.h
@@ -120,6 +120,9 @@
/// True if the intrinsic is marked as noduplicate.
bool isNoDuplicate;
+ /// True if the intrinsic is marked as nomerge.
+ bool isNoMerge;
+
/// True if the intrinsic is no-return.
bool isNoReturn;
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp
index 289a20a..6f718ac 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenMapTable.cpp
@@ -318,11 +318,10 @@
ListInit *ColFields = InstrMapDesc.getColFields();
Record *MatchInstr = nullptr;
- for (unsigned i = 0, e = RelatedInstrVec.size(); i < e; i++) {
+ for (llvm::Record *CurInstr : RelatedInstrVec) {
bool MatchFound = true;
- Record *CurInstr = RelatedInstrVec[i];
for (unsigned j = 0, endCF = ColFields->size();
- (j < endCF) && MatchFound; j++) {
+ (j < endCF) && MatchFound; j++) {
Init *ColFieldJ = ColFields->getElement(j);
Init *CurInstrInit = CurInstr->getValue(ColFieldJ)->getValue();
std::string CurInstrVal = CurInstrInit->getAsUnquotedString();
@@ -342,8 +341,9 @@
}
PrintFatalError("Multiple matches found for `" + KeyInstr->getName() +
- "', for the relation `" + InstrMapDesc.getName() + "', row fields [" +
- KeyValueStr + "], column `" + CurValueCol->getAsString() + "'");
+ "', for the relation `" + InstrMapDesc.getName() +
+ "', row fields [" + KeyValueStr + "], column `" +
+ CurValueCol->getAsString() + "'");
}
MatchInstr = CurInstr;
}
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp
index f9a7ba6..930b774 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.cpp
@@ -154,14 +154,11 @@
//===----------------------------------------------------------------------===//
CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum)
- : TheDef(R),
- EnumValue(Enum),
- CostPerUse(R->getValueAsInt("CostPerUse")),
- CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
- HasDisjunctSubRegs(false),
- SubRegsComplete(false),
- SuperRegsComplete(false),
- TopoSig(~0u) {
+ : TheDef(R), EnumValue(Enum),
+ CostPerUse(R->getValueAsListOfInts("CostPerUse")),
+ CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")),
+ HasDisjunctSubRegs(false), SubRegsComplete(false),
+ SuperRegsComplete(false), TopoSig(~0u) {
Artificial = R->getValueAsBit("isArtificial");
}
@@ -314,18 +311,17 @@
// Look at the possible compositions of Idx.
// They may not all be supported by SR.
- for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
- E = Comps.end(); I != E; ++I) {
- SubRegMap::const_iterator SRI = Map.find(I->first);
+ for (auto Comp : Comps) {
+ SubRegMap::const_iterator SRI = Map.find(Comp.first);
if (SRI == Map.end())
continue; // Idx + I->first doesn't exist in SR.
// Add I->second as a name for the subreg SRI->second, assuming it is
// orphaned, and the name isn't already used for something else.
- if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
+ if (SubRegs.count(Comp.second) || !Orphans.erase(SRI->second))
continue;
// We found a new name for the orphaned sub-register.
- SubRegs.insert(std::make_pair(I->second, SRI->second));
- Indices.push_back(I->second);
+ SubRegs.insert(std::make_pair(Comp.second, SRI->second));
+ Indices.push_back(Comp.second);
}
}
@@ -531,13 +527,13 @@
for (unsigned i = 0, e = NewSubRegs.size(); i != e; ++i) {
CodeGenSubRegIndex *NewIdx = NewSubRegs[i].first;
CodeGenRegister *NewSubReg = NewSubRegs[i].second;
- for (SubRegMap::const_iterator SI = NewSubReg->SubRegs.begin(),
- SE = NewSubReg->SubRegs.end(); SI != SE; ++SI) {
- CodeGenSubRegIndex *SubIdx = getSubRegIndex(SI->second);
+ for (auto SubReg : NewSubReg->SubRegs) {
+ CodeGenSubRegIndex *SubIdx = getSubRegIndex(SubReg.second);
if (!SubIdx)
PrintFatalError(TheDef->getLoc(), "No SubRegIndex for " +
- SI->second->getName() + " in " + getName());
- NewIdx->addComposite(SI->first, SubIdx);
+ SubReg.second->getName() +
+ " in " + getName());
+ NewIdx->addComposite(SubReg.first, SubIdx);
}
}
}
@@ -550,24 +546,23 @@
// Make sure all sub-registers have been visited first, so the super-reg
// lists will be topologically ordered.
- for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
- I != E; ++I)
- I->second->computeSuperRegs(RegBank);
+ for (auto SubReg : SubRegs)
+ SubReg.second->computeSuperRegs(RegBank);
// Now add this as a super-register on all sub-registers.
// Also compute the TopoSigId in post-order.
TopoSigId Id;
- for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
- I != E; ++I) {
+ for (auto SubReg : SubRegs) {
// Topological signature computed from SubIdx, TopoId(SubReg).
// Loops and idempotent indices have TopoSig = ~0u.
- Id.push_back(I->first->EnumValue);
- Id.push_back(I->second->TopoSig);
+ Id.push_back(SubReg.first->EnumValue);
+ Id.push_back(SubReg.second->TopoSig);
// Don't add duplicate entries.
- if (!I->second->SuperRegs.empty() && I->second->SuperRegs.back() == this)
+ if (!SubReg.second->SuperRegs.empty() &&
+ SubReg.second->SuperRegs.back() == this)
continue;
- I->second->SuperRegs.push_back(this);
+ SubReg.second->SuperRegs.push_back(this);
}
TopoSig = RegBank.getTopoSig(Id);
}
@@ -582,17 +577,15 @@
SR->addSubRegsPreOrder(OSet, RegBank);
}
// Add any secondary sub-registers that weren't part of the explicit tree.
- for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
- I != E; ++I)
- OSet.insert(I->second);
+ for (auto SubReg : SubRegs)
+ OSet.insert(SubReg.second);
}
// Get the sum of this register's unit weights.
unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const {
unsigned Weight = 0;
- for (RegUnitList::iterator I = RegUnits.begin(), E = RegUnits.end();
- I != E; ++I) {
- Weight += RegBank.getRegUnit(*I).Weight;
+ for (unsigned RegUnit : RegUnits) {
+ Weight += RegBank.getRegUnit(RegUnit).Weight;
}
return Weight;
}
@@ -646,16 +639,18 @@
std::string Name;
Record *Proto = Lists[0][n];
std::vector<Init*> Tuple;
- unsigned CostPerUse = 0;
for (unsigned i = 0; i != Dim; ++i) {
Record *Reg = Lists[i][n];
if (i) Name += '_';
Name += Reg->getName();
Tuple.push_back(DefInit::get(Reg));
- CostPerUse = std::max(CostPerUse,
- unsigned(Reg->getValueAsInt("CostPerUse")));
}
+ // Take the cost list of the first register in the tuple.
+ ListInit *CostList = Proto->getValueAsListInit("CostPerUse");
+ SmallVector<Init *, 2> CostPerUse;
+ CostPerUse.insert(CostPerUse.end(), CostList->begin(), CostList->end());
+
StringInit *AsmName = StringInit::get("");
if (!RegNames.empty()) {
if (RegNames.size() <= n)
@@ -697,7 +692,7 @@
// CostPerUse is aggregated from all Tuple members.
if (Field == "CostPerUse")
- RV.setValue(IntInit::get(CostPerUse));
+ RV.setValue(ListInit::get(CostPerUse, CostList->getElementType()));
// Composite registers are always covered by sub-registers.
if (Field == "CoveredBySubRegs")
@@ -797,7 +792,7 @@
RI.RegSize = RI.SpillSize = Size ? Size
: VTs[0].getSimple().getSizeInBits();
RI.SpillAlignment = R->getValueAsInt("Alignment");
- RSI.Map.insert({DefaultMode, RI});
+ RSI.insertRegSizeForMode(DefaultMode, RI);
}
CopyCost = R->getValueAsInt("CopyCost");
@@ -838,7 +833,10 @@
Namespace = Super.Namespace;
VTs = Super.VTs;
CopyCost = Super.CopyCost;
- Allocatable = Super.Allocatable;
+ // Check for allocatable superclasses.
+ Allocatable = any_of(SuperClasses, [&](const CodeGenRegisterClass *S) {
+ return S->Allocatable;
+ });
AltOrderSelect = Super.AltOrderSelect;
AllocationPriority = Super.AllocationPriority;
GeneratePressureSet |= Super.GeneratePressureSet;
@@ -1396,19 +1394,17 @@
TopoSigs.set(Reg1.getTopoSig());
const CodeGenRegister::SubRegMap &SRM1 = Reg1.getSubRegs();
- for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(),
- e1 = SRM1.end(); i1 != e1; ++i1) {
- CodeGenSubRegIndex *Idx1 = i1->first;
- CodeGenRegister *Reg2 = i1->second;
+ for (auto I1 : SRM1) {
+ CodeGenSubRegIndex *Idx1 = I1.first;
+ CodeGenRegister *Reg2 = I1.second;
// Ignore identity compositions.
if (&Reg1 == Reg2)
continue;
const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs();
// Try composing Idx1 with another SubRegIndex.
- for (CodeGenRegister::SubRegMap::const_iterator i2 = SRM2.begin(),
- e2 = SRM2.end(); i2 != e2; ++i2) {
- CodeGenSubRegIndex *Idx2 = i2->first;
- CodeGenRegister *Reg3 = i2->second;
+ for (auto I2 : SRM2) {
+ CodeGenSubRegIndex *Idx2 = I2.first;
+ CodeGenRegister *Reg3 = I2.second;
// Ignore identity compositions.
if (Reg2 == Reg3)
continue;
@@ -1425,7 +1421,7 @@
" and " + Idx2->getQualifiedName() +
" compose ambiguously as " + Prev->getQualifiedName() +
" or " + Idx3->getQualifiedName());
- }
+ }
}
}
}
@@ -1728,13 +1724,12 @@
bool Changed = false;
const CodeGenRegister::SubRegMap &SRM = Reg->getSubRegs();
- for (CodeGenRegister::SubRegMap::const_iterator SRI = SRM.begin(),
- SRE = SRM.end(); SRI != SRE; ++SRI) {
- if (SRI->second == Reg)
+ for (auto SRI : SRM) {
+ if (SRI.second == Reg)
continue; // self-cycles happen
- Changed |= normalizeWeight(SRI->second, UberSets, RegSets,
- NormalRegs, NormalUnits, RegBank);
+ Changed |= normalizeWeight(SRI.second, UberSets, RegSets, NormalRegs,
+ NormalUnits, RegBank);
}
// Postorder register normalization.
@@ -2064,15 +2059,14 @@
// Iterate through SubRegisters.
typedef CodeGenRegister::SubRegMap SubRegMap;
const SubRegMap &SubRegs = Register.getSubRegs();
- for (SubRegMap::const_iterator S = SubRegs.begin(),
- SE = SubRegs.end(); S != SE; ++S) {
- CodeGenRegister *SubReg = S->second;
+ for (auto S : SubRegs) {
+ CodeGenRegister *SubReg = S.second;
// Ignore non-leaf subregisters, their lane masks are fully covered by
// the leaf subregisters anyway.
if (!SubReg->getSubRegs().empty())
continue;
- CodeGenSubRegIndex *SubRegIndex = S->first;
- const CodeGenRegister *SubRegister = S->second;
+ CodeGenSubRegIndex *SubRegIndex = S.first;
+ const CodeGenRegister *SubRegister = S.second;
LaneBitmask LaneMask = SubRegIndex->LaneMask;
// Distribute LaneMask to Register Units touched.
for (unsigned SUI : SubRegister->getRegUnits()) {
@@ -2194,10 +2188,9 @@
if (R->Artificial)
continue;
const CodeGenRegister::SubRegMap &SRM = R->getSubRegs();
- for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
- E = SRM.end(); I != E; ++I) {
- if (!I->first->Artificial)
- SRSets[I->first].push_back(R);
+ for (auto I : SRM) {
+ if (!I.first->Artificial)
+ SRSets[I.first].push_back(R);
}
}
@@ -2422,9 +2415,8 @@
// This new super-register is covered by its sub-registers.
bool AllSubsInSet = true;
const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs();
- for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(),
- E = SRM.end(); I != E; ++I)
- if (!Set.count(I->second)) {
+ for (auto I : SRM)
+ if (!Set.count(I.second)) {
AllSubsInSet = false;
break;
}
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h
index 5228e65..6a06960 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenRegisters.h
@@ -151,7 +151,7 @@
struct CodeGenRegister {
Record *TheDef;
unsigned EnumValue;
- unsigned CostPerUse;
+ std::vector<int64_t> CostPerUse;
bool CoveredBySubRegs;
bool HasDisjunctSubRegs;
bool Artificial;
@@ -738,9 +738,8 @@
// Get the sum of unit weights.
unsigned getRegUnitSetWeight(const std::vector<unsigned> &Units) const {
unsigned Weight = 0;
- for (std::vector<unsigned>::const_iterator
- I = Units.begin(), E = Units.end(); I != E; ++I)
- Weight += getRegUnit(*I).Weight;
+ for (unsigned Unit : Units)
+ Weight += getRegUnit(Unit).Weight;
return Weight;
}
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp
index b20eb6e..ee52b2e 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -708,10 +708,10 @@
/// Compute a SchedWrite name from a sequence of writes.
std::string CodeGenSchedModels::genRWName(ArrayRef<unsigned> Seq, bool IsRead) {
std::string Name("(");
- for (auto I = Seq.begin(), E = Seq.end(); I != E; ++I) {
- if (I != Seq.begin())
- Name += '_';
- Name += getSchedRW(*I, IsRead).Name;
+ ListSeparator LS("_");
+ for (unsigned I : Seq) {
+ Name += LS;
+ Name += getSchedRW(I, IsRead).Name;
}
Name += ')';
return Name;
@@ -921,11 +921,10 @@
ProcIndices.push_back(0);
LLVM_DEBUG({
dbgs() << "SchedRW machine model for " << InstName;
- for (IdxIter WI = SC.Writes.begin(), WE = SC.Writes.end(); WI != WE;
- ++WI)
- dbgs() << " " << SchedWrites[*WI].Name;
- for (IdxIter RI = SC.Reads.begin(), RE = SC.Reads.end(); RI != RE; ++RI)
- dbgs() << " " << SchedReads[*RI].Name;
+ for (unsigned int Write : SC.Writes)
+ dbgs() << " " << SchedWrites[Write].Name;
+ for (unsigned int Read : SC.Reads)
+ dbgs() << " " << SchedReads[Read].Name;
dbgs() << '\n';
});
}
@@ -990,10 +989,10 @@
std::string CodeGenSchedModels::createSchedClassName(const RecVec &InstDefs) {
std::string Name;
- for (RecIter I = InstDefs.begin(), E = InstDefs.end(); I != E; ++I) {
- if (I != InstDefs.begin())
- Name += '_';
- Name += (*I)->getName();
+ ListSeparator LS("_");
+ for (const Record *InstDef : InstDefs) {
+ Name += LS;
+ Name += InstDef->getName();
}
return Name;
}
@@ -1557,12 +1556,11 @@
// sequence (add to the current operand's sequence).
SmallVectorImpl<unsigned> &Seq = RWSequences.back();
IdxVec ExpandedRWs;
- for (IdxIter RWI = SelectedRWs.begin(), RWE = SelectedRWs.end();
- RWI != RWE; ++RWI) {
+ for (unsigned int SelectedRW : SelectedRWs) {
if (IsRead)
- ExpandedRWs.push_back(*RWI);
+ ExpandedRWs.push_back(SelectedRW);
else
- SchedModels.expandRWSequence(*RWI, ExpandedRWs, IsRead);
+ SchedModels.expandRWSequence(SelectedRW, ExpandedRWs, IsRead);
}
llvm::append_range(Seq, ExpandedRWs);
}
@@ -1576,9 +1574,8 @@
const SmallVectorImpl<unsigned> &RWSeq, bool IsRead, unsigned StartIdx) {
bool Subst = false;
// Visit each original RW within the current sequence.
- for (SmallVectorImpl<unsigned>::const_iterator
- RWI = RWSeq.begin(), RWE = RWSeq.end(); RWI != RWE; ++RWI) {
- const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(*RWI, IsRead);
+ for (unsigned int RWI : RWSeq) {
+ const CodeGenSchedRW &SchedRW = SchedModels.getSchedRW(RWI, IsRead);
// Push this RW on all partial PredTransitions or distribute variants.
// New PredTransitions may be pushed within this loop which should not be
// revisited (TransEnd must be loop invariant).
@@ -1593,9 +1590,9 @@
pushVariant(IV, IsRead);
if (IntersectingVariants.empty()) {
if (IsRead)
- TransVec[TransIdx].ReadSequences.back().push_back(*RWI);
+ TransVec[TransIdx].ReadSequences.back().push_back(RWI);
else
- TransVec[TransIdx].WriteSequences.back().push_back(*RWI);
+ TransVec[TransIdx].WriteSequences.back().push_back(RWI);
continue;
} else {
Subst = true;
@@ -1620,26 +1617,23 @@
TransVec.emplace_back(Trans.PredTerm, Trans.ProcIndex);
// Visit each original write sequence.
- for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
- WSI = Trans.WriteSequences.begin(), WSE = Trans.WriteSequences.end();
- WSI != WSE; ++WSI) {
+ for (const auto &WriteSequence : Trans.WriteSequences) {
// Push a new (empty) write sequence onto all partial Transitions.
for (std::vector<PredTransition>::iterator I =
TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
I->WriteSequences.emplace_back();
}
- Subst |= substituteVariantOperand(*WSI, /*IsRead=*/false, StartIdx);
+ Subst |=
+ substituteVariantOperand(WriteSequence, /*IsRead=*/false, StartIdx);
}
// Visit each original read sequence.
- for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
- RSI = Trans.ReadSequences.begin(), RSE = Trans.ReadSequences.end();
- RSI != RSE; ++RSI) {
+ for (const auto &ReadSequence : Trans.ReadSequences) {
// Push a new (empty) read sequence onto all partial Transitions.
for (std::vector<PredTransition>::iterator I =
TransVec.begin() + StartIdx, E = TransVec.end(); I != E; ++I) {
I->ReadSequences.emplace_back();
}
- Subst |= substituteVariantOperand(*RSI, /*IsRead=*/true, StartIdx);
+ Subst |= substituteVariantOperand(ReadSequence, /*IsRead=*/true, StartIdx);
}
return Subst;
}
@@ -1676,33 +1670,32 @@
CodeGenSchedModels &SchedModels) {
// For each PredTransition, create a new CodeGenSchedTransition, which usually
// requires creating a new SchedClass.
- for (ArrayRef<PredTransition>::iterator
- I = LastTransitions.begin(), E = LastTransitions.end(); I != E; ++I) {
+ for (const auto &LastTransition : LastTransitions) {
// Variant expansion (substituteVariants) may create unconditional
// transitions. We don't need to build sched classes for them.
- if (I->PredTerm.empty())
+ if (LastTransition.PredTerm.empty())
continue;
IdxVec OperWritesVariant, OperReadsVariant;
- addSequences(SchedModels, I->WriteSequences, OperWritesVariant, false);
- addSequences(SchedModels, I->ReadSequences, OperReadsVariant, true);
+ addSequences(SchedModels, LastTransition.WriteSequences, OperWritesVariant,
+ false);
+ addSequences(SchedModels, LastTransition.ReadSequences, OperReadsVariant,
+ true);
CodeGenSchedTransition SCTrans;
// Transition should not contain processor indices already assigned to
// InstRWs in this scheduling class.
const CodeGenSchedClass &FromSC = SchedModels.getSchedClass(FromClassIdx);
- if (FromSC.InstRWProcIndices.count(I->ProcIndex))
+ if (FromSC.InstRWProcIndices.count(LastTransition.ProcIndex))
continue;
- SCTrans.ProcIndex = I->ProcIndex;
+ SCTrans.ProcIndex = LastTransition.ProcIndex;
SCTrans.ToClassIdx =
SchedModels.addSchedClass(/*ItinClassDef=*/nullptr, OperWritesVariant,
- OperReadsVariant, I->ProcIndex);
+ OperReadsVariant, LastTransition.ProcIndex);
// The final PredTerm is unique set of predicates guarding the transition.
RecVec Preds;
- transform(I->PredTerm, std::back_inserter(Preds),
- [](const PredCheck &P) {
- return P.Predicate;
- });
+ transform(LastTransition.PredTerm, std::back_inserter(Preds),
+ [](const PredCheck &P) { return P.Predicate; });
Preds.erase(std::unique(Preds.begin(), Preds.end()), Preds.end());
dumpTransition(SchedModels, FromSC, SCTrans, Preds);
SCTrans.PredTerm = std::move(Preds);
@@ -1791,11 +1784,10 @@
// Check if any processor resource group contains all resource records in
// SubUnits.
bool CodeGenSchedModels::hasSuperGroup(RecVec &SubUnits, CodeGenProcModel &PM) {
- for (unsigned i = 0, e = PM.ProcResourceDefs.size(); i < e; ++i) {
- if (!PM.ProcResourceDefs[i]->isSubClassOf("ProcResGroup"))
+ for (Record *ProcResourceDef : PM.ProcResourceDefs) {
+ if (!ProcResourceDef->isSubClassOf("ProcResGroup"))
continue;
- RecVec SuperUnits =
- PM.ProcResourceDefs[i]->getValueAsListOfDefs("Resources");
+ RecVec SuperUnits = ProcResourceDef->getValueAsListOfDefs("Resources");
RecIter RI = SubUnits.begin(), RE = SubUnits.end();
for ( ; RI != RE; ++RI) {
if (!is_contained(SuperUnits, *RI)) {
@@ -1951,27 +1943,26 @@
llvm::sort(PM.ReadAdvanceDefs, LessRecord());
llvm::sort(PM.ProcResourceDefs, LessRecord());
LLVM_DEBUG(
- PM.dump();
- dbgs() << "WriteResDefs: "; for (RecIter RI = PM.WriteResDefs.begin(),
- RE = PM.WriteResDefs.end();
- RI != RE; ++RI) {
- if ((*RI)->isSubClassOf("WriteRes"))
- dbgs() << (*RI)->getValueAsDef("WriteType")->getName() << " ";
+ PM.dump(); dbgs() << "WriteResDefs: "; for (auto WriteResDef
+ : PM.WriteResDefs) {
+ if (WriteResDef->isSubClassOf("WriteRes"))
+ dbgs() << WriteResDef->getValueAsDef("WriteType")->getName() << " ";
else
- dbgs() << (*RI)->getName() << " ";
+ dbgs() << WriteResDef->getName() << " ";
} dbgs() << "\nReadAdvanceDefs: ";
- for (RecIter RI = PM.ReadAdvanceDefs.begin(),
- RE = PM.ReadAdvanceDefs.end();
- RI != RE; ++RI) {
- if ((*RI)->isSubClassOf("ReadAdvance"))
- dbgs() << (*RI)->getValueAsDef("ReadType")->getName() << " ";
+ for (Record *ReadAdvanceDef
+ : PM.ReadAdvanceDefs) {
+ if (ReadAdvanceDef->isSubClassOf("ReadAdvance"))
+ dbgs() << ReadAdvanceDef->getValueAsDef("ReadType")->getName()
+ << " ";
else
- dbgs() << (*RI)->getName() << " ";
+ dbgs() << ReadAdvanceDef->getName() << " ";
} dbgs()
<< "\nProcResourceDefs: ";
- for (RecIter RI = PM.ProcResourceDefs.begin(),
- RE = PM.ProcResourceDefs.end();
- RI != RE; ++RI) { dbgs() << (*RI)->getName() << " "; } dbgs()
+ for (Record *ProcResourceDef
+ : PM.ProcResourceDefs) {
+ dbgs() << ProcResourceDef->getName() << " ";
+ } dbgs()
<< '\n');
verifyProcResourceGroups(PM);
}
@@ -2073,23 +2064,20 @@
addReadAdvance(SchedRW.TheDef, Idx);
}
}
- for (RecIter AI = SchedRW.Aliases.begin(), AE = SchedRW.Aliases.end();
- AI != AE; ++AI) {
+ for (auto *Alias : SchedRW.Aliases) {
IdxVec AliasProcIndices;
- if ((*AI)->getValueInit("SchedModel")->isComplete()) {
+ if (Alias->getValueInit("SchedModel")->isComplete()) {
AliasProcIndices.push_back(
- getProcModel((*AI)->getValueAsDef("SchedModel")).Index);
- }
- else
+ getProcModel(Alias->getValueAsDef("SchedModel")).Index);
+ } else
AliasProcIndices = ProcIndices;
- const CodeGenSchedRW &AliasRW = getSchedRW((*AI)->getValueAsDef("AliasRW"));
+ const CodeGenSchedRW &AliasRW = getSchedRW(Alias->getValueAsDef("AliasRW"));
assert(AliasRW.IsRead == IsRead && "cannot alias reads to writes");
IdxVec ExpandedRWs;
expandRWSequence(AliasRW.Index, ExpandedRWs, IsRead);
- for (IdxIter SI = ExpandedRWs.begin(), SE = ExpandedRWs.end();
- SI != SE; ++SI) {
- collectRWResources(*SI, IsRead, AliasProcIndices);
+ for (unsigned int ExpandedRW : ExpandedRWs) {
+ collectRWResources(ExpandedRW, IsRead, AliasProcIndices);
}
}
}
@@ -2179,9 +2167,8 @@
// Visit ProcResourceKinds referenced by the newly discovered WriteRes.
RecVec ProcResDefs = ProcWriteResDef->getValueAsListOfDefs("ProcResources");
- for (RecIter WritePRI = ProcResDefs.begin(), WritePRE = ProcResDefs.end();
- WritePRI != WritePRE; ++WritePRI) {
- addProcResource(*WritePRI, ProcModels[PIdx], ProcWriteResDef->getLoc());
+ for (auto *ProcResDef : ProcResDefs) {
+ addProcResource(ProcResDef, ProcModels[PIdx], ProcWriteResDef->getLoc());
}
}
@@ -2259,28 +2246,21 @@
void PredTransitions::dump() const {
dbgs() << "Expanded Variants:\n";
- for (std::vector<PredTransition>::const_iterator
- TI = TransVec.begin(), TE = TransVec.end(); TI != TE; ++TI) {
+ for (const auto &TI : TransVec) {
dbgs() << "{";
- for (SmallVectorImpl<PredCheck>::const_iterator
- PCI = TI->PredTerm.begin(), PCE = TI->PredTerm.end();
- PCI != PCE; ++PCI) {
- if (PCI != TI->PredTerm.begin())
- dbgs() << ", ";
- dbgs() << SchedModels.getSchedRW(PCI->RWIdx, PCI->IsRead).Name
- << ":" << PCI->Predicate->getName();
- }
+ ListSeparator LS;
+ for (const PredCheck &PC : TI.PredTerm)
+ dbgs() << LS << SchedModels.getSchedRW(PC.RWIdx, PC.IsRead).Name << ":"
+ << PC.Predicate->getName();
dbgs() << "},\n => {";
- for (SmallVectorImpl<SmallVector<unsigned,4>>::const_iterator
- WSI = TI->WriteSequences.begin(), WSE = TI->WriteSequences.end();
+ for (SmallVectorImpl<SmallVector<unsigned, 4>>::const_iterator
+ WSI = TI.WriteSequences.begin(),
+ WSE = TI.WriteSequences.end();
WSI != WSE; ++WSI) {
dbgs() << "(";
- for (SmallVectorImpl<unsigned>::const_iterator
- WI = WSI->begin(), WE = WSI->end(); WI != WE; ++WI) {
- if (WI != WSI->begin())
- dbgs() << ", ";
- dbgs() << SchedModels.getSchedWrite(*WI).Name;
- }
+ ListSeparator LS;
+ for (unsigned N : *WSI)
+ dbgs() << LS << SchedModels.getSchedWrite(N).Name;
dbgs() << "),";
}
dbgs() << "}\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp b/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp
index 8f6d212..137f990 100644
--- a/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -77,6 +77,7 @@
case MVT::ppcf128: return "MVT::ppcf128";
case MVT::x86mmx: return "MVT::x86mmx";
case MVT::x86amx: return "MVT::x86amx";
+ case MVT::i64x8: return "MVT::i64x8";
case MVT::Glue: return "MVT::Glue";
case MVT::isVoid: return "MVT::isVoid";
case MVT::v1i1: return "MVT::v1i1";
@@ -99,6 +100,8 @@
case MVT::v64i8: return "MVT::v64i8";
case MVT::v128i8: return "MVT::v128i8";
case MVT::v256i8: return "MVT::v256i8";
+ case MVT::v512i8: return "MVT::v512i8";
+ case MVT::v1024i8: return "MVT::v1024i8";
case MVT::v1i16: return "MVT::v1i16";
case MVT::v2i16: return "MVT::v2i16";
case MVT::v3i16: return "MVT::v3i16";
@@ -108,11 +111,15 @@
case MVT::v32i16: return "MVT::v32i16";
case MVT::v64i16: return "MVT::v64i16";
case MVT::v128i16: return "MVT::v128i16";
+ case MVT::v256i16: return "MVT::v256i16";
+ case MVT::v512i16: return "MVT::v512i16";
case MVT::v1i32: return "MVT::v1i32";
case MVT::v2i32: return "MVT::v2i32";
case MVT::v3i32: return "MVT::v3i32";
case MVT::v4i32: return "MVT::v4i32";
case MVT::v5i32: return "MVT::v5i32";
+ case MVT::v6i32: return "MVT::v6i32";
+ case MVT::v7i32: return "MVT::v7i32";
case MVT::v8i32: return "MVT::v8i32";
case MVT::v16i32: return "MVT::v16i32";
case MVT::v32i32: return "MVT::v32i32";
@@ -124,6 +131,7 @@
case MVT::v2048i32: return "MVT::v2048i32";
case MVT::v1i64: return "MVT::v1i64";
case MVT::v2i64: return "MVT::v2i64";
+ case MVT::v3i64: return "MVT::v3i64";
case MVT::v4i64: return "MVT::v4i64";
case MVT::v8i64: return "MVT::v8i64";
case MVT::v16i64: return "MVT::v16i64";
@@ -132,6 +140,7 @@
case MVT::v128i64: return "MVT::v128i64";
case MVT::v256i64: return "MVT::v256i64";
case MVT::v1i128: return "MVT::v1i128";
+ case MVT::v1f16: return "MVT::v1f16";
case MVT::v2f16: return "MVT::v2f16";
case MVT::v3f16: return "MVT::v3f16";
case MVT::v4f16: return "MVT::v4f16";
@@ -140,6 +149,8 @@
case MVT::v32f16: return "MVT::v32f16";
case MVT::v64f16: return "MVT::v64f16";
case MVT::v128f16: return "MVT::v128f16";
+ case MVT::v256f16: return "MVT::v256f16";
+ case MVT::v512f16: return "MVT::v512f16";
case MVT::v2bf16: return "MVT::v2bf16";
case MVT::v3bf16: return "MVT::v3bf16";
case MVT::v4bf16: return "MVT::v4bf16";
@@ -153,6 +164,8 @@
case MVT::v3f32: return "MVT::v3f32";
case MVT::v4f32: return "MVT::v4f32";
case MVT::v5f32: return "MVT::v5f32";
+ case MVT::v6f32: return "MVT::v6f32";
+ case MVT::v7f32: return "MVT::v7f32";
case MVT::v8f32: return "MVT::v8f32";
case MVT::v16f32: return "MVT::v16f32";
case MVT::v32f32: return "MVT::v32f32";
@@ -164,6 +177,7 @@
case MVT::v2048f32: return "MVT::v2048f32";
case MVT::v1f64: return "MVT::v1f64";
case MVT::v2f64: return "MVT::v2f64";
+ case MVT::v3f64: return "MVT::v3f64";
case MVT::v4f64: return "MVT::v4f64";
case MVT::v8f64: return "MVT::v8f64";
case MVT::v16f64: return "MVT::v16f64";
@@ -209,6 +223,7 @@
case MVT::nxv8f16: return "MVT::nxv8f16";
case MVT::nxv16f16: return "MVT::nxv16f16";
case MVT::nxv32f16: return "MVT::nxv32f16";
+ case MVT::nxv1bf16: return "MVT::nxv1bf16";
case MVT::nxv2bf16: return "MVT::nxv2bf16";
case MVT::nxv4bf16: return "MVT::nxv4bf16";
case MVT::nxv8bf16: return "MVT::nxv8bf16";
@@ -251,9 +266,9 @@
: Records(records), CGH(records) {
std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
if (Targets.size() == 0)
- PrintFatalError("ERROR: No 'Target' subclasses defined!");
+ PrintFatalError("No 'Target' subclasses defined!");
if (Targets.size() != 1)
- PrintFatalError("ERROR: Multiple subclasses of Target defined!");
+ PrintFatalError("Multiple subclasses of Target defined!");
TargetRec = Targets[0];
}
@@ -656,6 +671,7 @@
isWillReturn = false;
isCold = false;
isNoDuplicate = false;
+ isNoMerge = false;
isConvergent = false;
isSpeculatable = false;
hasSideEffects = false;
@@ -845,6 +861,8 @@
canThrow = true;
else if (R->getName() == "IntrNoDuplicate")
isNoDuplicate = true;
+ else if (R->getName() == "IntrNoMerge")
+ isNoMerge = true;
else if (R->getName() == "IntrConvergent")
isConvergent = true;
else if (R->getName() == "IntrNoReturn")
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DAGISelEmitter.cpp
index 32ed0bf..2f211e2 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelEmitter.cpp
@@ -115,7 +115,7 @@
// pattern may have been resolved into multiple match patterns due to
// alternative fragments. To ensure deterministic output, always use
// std::stable_sort with this predicate.
- return LHS->ID < RHS->ID;
+ return LHS->getID() < RHS->getID();
}
};
} // End anonymous namespace
@@ -153,9 +153,8 @@
// Add all the patterns to a temporary list so we can sort them.
Records.startTimer("Sort patterns");
std::vector<const PatternToMatch*> Patterns;
- for (CodeGenDAGPatterns::ptm_iterator I = CGP.ptm_begin(), E = CGP.ptm_end();
- I != E; ++I)
- Patterns.push_back(&*I);
+ for (const PatternToMatch &PTM : CGP.ptms())
+ Patterns.push_back(&PTM);
// We want to process the matches in order of minimal cost. Sort the patterns
// so the least cost one is at the start.
@@ -164,9 +163,9 @@
// Convert each variant of each pattern into a Matcher.
Records.startTimer("Convert to matchers");
std::vector<Matcher*> PatternMatchers;
- for (unsigned i = 0, e = Patterns.size(); i != e; ++i) {
+ for (const PatternToMatch *PTM : Patterns) {
for (unsigned Variant = 0; ; ++Variant) {
- if (Matcher *M = ConvertPatternToMatcher(*Patterns[i], Variant, CGP))
+ if (Matcher *M = ConvertPatternToMatcher(*PTM, Variant, CGP))
PatternMatchers.push_back(M);
else
break;
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.cpp b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.cpp
index bebd205..e436a93 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.cpp
@@ -421,3 +421,15 @@
// AllOnes is contradictory.
return isa<CheckImmAllOnesVMatcher>(M);
}
+
+bool CheckCondCodeMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const auto *CCCM = dyn_cast<CheckCondCodeMatcher>(M))
+ return CCCM->getCondCodeName() != getCondCodeName();
+ return false;
+}
+
+bool CheckChild2CondCodeMatcher::isContradictoryImpl(const Matcher *M) const {
+ if (const auto *CCCCM = dyn_cast<CheckChild2CondCodeMatcher>(M))
+ return CCCCM->getCondCodeName() != getCondCodeName();
+ return false;
+}
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.h b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.h
index ff9a0cb..77280ac 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.h
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcher.h
@@ -635,6 +635,7 @@
bool isEqualImpl(const Matcher *M) const override {
return cast<CheckCondCodeMatcher>(M)->CondCodeName == CondCodeName;
}
+ bool isContradictoryImpl(const Matcher *M) const override;
};
/// CheckChild2CondCodeMatcher - This checks to see if child 2 node is a
@@ -656,6 +657,7 @@
bool isEqualImpl(const Matcher *M) const override {
return cast<CheckChild2CondCodeMatcher>(M)->CondCodeName == CondCodeName;
}
+ bool isContradictoryImpl(const Matcher *M) const override;
};
/// CheckValueTypeMatcher - This checks to see if the current node is a
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
index 03528a4..a552998 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherEmitter.cpp
@@ -173,7 +173,7 @@
return str;
}
-static size_t GetVBRSize(unsigned Val) {
+static unsigned GetVBRSize(unsigned Val) {
if (Val <= 127) return 1;
unsigned NumBytes = 0;
@@ -186,7 +186,7 @@
/// EmitVBRValue - Emit the specified value as a VBR, returning the number of
/// bytes emitted.
-static uint64_t EmitVBRValue(uint64_t Val, raw_ostream &OS) {
+static unsigned EmitVBRValue(uint64_t Val, raw_ostream &OS) {
if (Val <= 127) {
OS << Val << ", ";
return 1;
@@ -206,6 +206,18 @@
return NumBytes+1;
}
+/// Emit the specified signed value as a VBR. To improve compression we encode
+/// positive numbers shifted left by 1 and negative numbers negated and shifted
+/// left by 1 with bit 0 set.
+static unsigned EmitSignedVBRValue(uint64_t Val, raw_ostream &OS) {
+ if ((int64_t)Val >= 0)
+ Val = Val << 1;
+ else
+ Val = (-Val << 1) | 1;
+
+ return EmitVBRValue(Val, OS);
+}
+
// This is expensive and slow.
static std::string getIncludePath(const Record *R) {
std::string str;
@@ -255,7 +267,7 @@
assert(SM->getNext() == nullptr && "Scope matcher should not have next");
unsigned Size = 1; // Count the kind.
for (unsigned i = 0, e = SM->getNumChildren(); i != e; ++i) {
- const size_t ChildSize = SizeMatcherList(SM->getChild(i), OS);
+ const unsigned ChildSize = SizeMatcherList(SM->getChild(i), OS);
assert(ChildSize != 0 && "Matcher cannot have child of size 0");
SM->getChild(i)->setSize(ChildSize);
Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
@@ -283,7 +295,7 @@
Child = cast<SwitchTypeMatcher>(N)->getCaseMatcher(i);
++Size; // Count the child's type.
}
- const size_t ChildSize = SizeMatcherList(Child, OS);
+ const unsigned ChildSize = SizeMatcherList(Child, OS);
assert(ChildSize != 0 && "Matcher cannot have child of size 0");
Child->setSize(ChildSize);
Size += GetVBRSize(ChildSize) + ChildSize; // Count VBR and child size.
@@ -381,9 +393,8 @@
OS.indent(Indent);
}
- size_t ChildSize = SM->getChild(i)->getSize();
- size_t VBRSize = GetVBRSize(ChildSize);
- EmitVBRValue(ChildSize, OS);
+ unsigned ChildSize = SM->getChild(i)->getSize();
+ unsigned VBRSize = EmitVBRValue(ChildSize, OS);
if (!OmitComments) {
OS << "/*->" << CurrentIdx + VBRSize + ChildSize << "*/";
if (i == 0)
@@ -534,7 +545,7 @@
"/*SwitchOpcode*/ " : "/*SwitchType*/ ");
}
- size_t ChildSize = Child->getSize();
+ unsigned ChildSize = Child->getSize();
CurrentIdx += EmitVBRValue(ChildSize, OS) + IdxSize;
if (const SwitchOpcodeMatcher *SOM = dyn_cast<SwitchOpcodeMatcher>(N))
OS << "TARGET_VAL(" << SOM->getCaseOpcode(i).getEnumName() << "),";
@@ -580,15 +591,16 @@
case Matcher::CheckInteger: {
OS << "OPC_CheckInteger, ";
- unsigned Bytes=1+EmitVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
+ unsigned Bytes =
+ 1 + EmitSignedVBRValue(cast<CheckIntegerMatcher>(N)->getValue(), OS);
OS << '\n';
return Bytes;
}
case Matcher::CheckChildInteger: {
OS << "OPC_CheckChild" << cast<CheckChildIntegerMatcher>(N)->getChildNo()
<< "Integer, ";
- unsigned Bytes=1+EmitVBRValue(cast<CheckChildIntegerMatcher>(N)->getValue(),
- OS);
+ unsigned Bytes = 1 + EmitSignedVBRValue(
+ cast<CheckChildIntegerMatcher>(N)->getValue(), OS);
OS << '\n';
return Bytes;
}
@@ -656,16 +668,16 @@
int64_t Val = cast<EmitIntegerMatcher>(N)->getValue();
OS << "OPC_EmitInteger, "
<< getEnumName(cast<EmitIntegerMatcher>(N)->getVT()) << ", ";
- unsigned Bytes = 2+EmitVBRValue(Val, OS);
+ unsigned Bytes = 2 + EmitSignedVBRValue(Val, OS);
OS << '\n';
return Bytes;
}
case Matcher::EmitStringInteger: {
const std::string &Val = cast<EmitStringIntegerMatcher>(N)->getValue();
// These should always fit into 7 bits.
- OS << "OPC_EmitInteger, "
- << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", "
- << Val << ",\n";
+ OS << "OPC_EmitStringInteger, "
+ << getEnumName(cast<EmitStringIntegerMatcher>(N)->getVT()) << ", " << Val
+ << ",\n";
return 3;
}
@@ -886,14 +898,13 @@
for (unsigned i = 0, e = Preds.size(); i != e; ++i) {
// Emit the predicate code corresponding to this pattern.
const TreePredicateFn PredFn = Preds[i];
-
assert(!PredFn.isAlwaysTrue() && "No code in this predicate");
- OS << " case " << i << ": {\n";
- for (auto *SimilarPred :
- NodePredicatesByCodeToRun[PredFn.getCodeToRunOnSDNode()])
- OS << " // " << TreePredicateFn(SimilarPred).getFnName() <<'\n';
+ std::string PredFnCodeStr = PredFn.getCodeToRunOnSDNode();
- OS << PredFn.getCodeToRunOnSDNode() << "\n }\n";
+ OS << " case " << i << ": {\n";
+ for (auto *SimilarPred : NodePredicatesByCodeToRun[PredFnCodeStr])
+ OS << " // " << TreePredicateFn(SimilarPred).getFnName() << '\n';
+ OS << PredFnCodeStr << "\n }\n";
}
OS << " }\n";
OS << "}\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp
index f7415b8..2625595 100644
--- a/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DAGISelMatcherGen.cpp
@@ -163,7 +163,7 @@
PatWithNoTypes->RemoveAllTypes();
// If there are types that are manifestly known, infer them.
- InferPossibleTypes(Pattern.ForceMode);
+ InferPossibleTypes(Pattern.getForceMode());
}
/// InferPossibleTypes - As we emit the pattern, we end up generating type
@@ -576,7 +576,7 @@
// Emit the matcher for the pattern structure and types.
EmitMatchCode(Pattern.getSrcPattern(), PatWithNoTypes.get(),
- Pattern.ForceMode);
+ Pattern.getForceMode());
// If the pattern has a predicate on it (e.g. only enabled when a subtarget
// feature is around, do the check).
diff --git a/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp
index 781cb06..27161d2 100644
--- a/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DFAEmitter.cpp
@@ -19,7 +19,6 @@
// to the NFA.
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dfa-emitter"
#include "DFAEmitter.h"
#include "CodeGenTarget.h"
@@ -39,6 +38,8 @@
#include <string>
#include <vector>
+#define DEBUG_TYPE "dfa-emitter"
+
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -376,11 +377,9 @@
const ActionTuple &AT = Actions[A];
if (AT.size() > 1)
OS << "std::make_tuple(";
- bool First = true;
+ ListSeparator LS;
for (const auto &SingleAction : AT) {
- if (!First)
- OS << ", ";
- First = false;
+ OS << LS;
SingleAction.print(OS);
}
if (AT.size() > 1)
diff --git a/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
index 40d9385..9cbdbc1 100644
--- a/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DFAPacketizerEmitter.cpp
@@ -14,8 +14,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dfa-emitter"
-
#include "CodeGenSchedule.h"
#include "CodeGenTarget.h"
#include "DFAEmitter.h"
@@ -34,6 +32,8 @@
#include <unordered_map>
#include <vector>
+#define DEBUG_TYPE "dfa-emitter"
+
using namespace llvm;
// We use a uint64_t to represent a resource bitmask.
@@ -157,8 +157,8 @@
uint64_t ComboResources = ComboBit;
LLVM_DEBUG(dbgs() << " combo: " << ComboFuncName << ":0x"
<< Twine::utohexstr(ComboResources) << "\n");
- for (unsigned k = 0, M = FuncList.size(); k < M; ++k) {
- std::string FuncName = std::string(FuncList[k]->getName());
+ for (auto *K : FuncList) {
+ std::string FuncName = std::string(K->getName());
uint64_t FuncResources = FUNameToBitsMap[FuncName];
LLVM_DEBUG(dbgs() << " " << FuncName << ":0x"
<< Twine::utohexstr(FuncResources) << "\n");
diff --git a/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp
index c9daa9b..b21bf36 100644
--- a/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/DirectiveEmitter.cpp
@@ -633,6 +633,43 @@
}
}
+// Generate check in the Enter functions for clauses classes.
+void GenerateFlangClauseCheckPrototypes(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ IfDefScope Scope("GEN_FLANG_CLAUSE_CHECK_ENTER", OS);
+
+ OS << "\n";
+ for (const auto &C : DirLang.getClauses()) {
+ Clause Clause{C};
+ OS << "void Enter(const parser::" << DirLang.getFlangClauseBaseClass()
+ << "::" << Clause.getFormattedParserClassName() << " &);\n";
+ }
+}
+
+// Generate the mapping for clauses between the parser class and the
+// corresponding clause Kind
+void GenerateFlangClauseParserKindMap(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+
+ IfDefScope Scope("GEN_FLANG_CLAUSE_PARSER_KIND_MAP", OS);
+
+ OS << "\n";
+ for (const auto &C : DirLang.getClauses()) {
+ Clause Clause{C};
+ OS << "if constexpr (std::is_same_v<A, parser::"
+ << DirLang.getFlangClauseBaseClass()
+ << "::" << Clause.getFormattedParserClassName();
+ OS << ">)\n";
+ OS << " return llvm::" << DirLang.getCppNamespace()
+ << "::Clause::" << DirLang.getClausePrefix() << Clause.getFormattedName()
+ << ";\n";
+ }
+
+ OS << "llvm_unreachable(\"Invalid " << DirLang.getName()
+ << " Parser clause\");\n";
+}
+
// Generate the implementation section for the enumeration in the directive
// language
void EmitDirectivesFlangImpl(const DirectiveLanguage &DirLang,
@@ -649,6 +686,10 @@
GenerateFlangClauseDump(DirLang, OS);
GenerateFlangClauseUnparse(DirLang, OS);
+
+ GenerateFlangClauseCheckPrototypes(DirLang, OS);
+
+ GenerateFlangClauseParserKindMap(DirLang, OS);
}
void GenerateClauseClassMacro(const DirectiveLanguage &DirLang,
@@ -717,37 +758,11 @@
OS << "#undef CLAUSE\n";
}
-// Generate the implementation section for the enumeration in the directive
-// language.
-void EmitDirectivesGen(RecordKeeper &Records, raw_ostream &OS) {
- const auto DirLang = DirectiveLanguage{Records};
- if (DirLang.HasValidityErrors())
- return;
-
- EmitDirectivesFlangImpl(DirLang, OS);
-
- GenerateClauseClassMacro(DirLang, OS);
-}
-
-// Generate the implementation for the enumeration in the directive
+// Generate the implemenation for the enumeration in the directive
// language. This code can be included in library.
-void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
- const auto DirLang = DirectiveLanguage{Records};
- if (DirLang.HasValidityErrors())
- return;
-
- if (!DirLang.getIncludeHeader().empty())
- OS << "#include \"" << DirLang.getIncludeHeader() << "\"\n\n";
-
- OS << "#include \"llvm/ADT/StringRef.h\"\n";
- OS << "#include \"llvm/ADT/StringSwitch.h\"\n";
- OS << "#include \"llvm/Support/ErrorHandling.h\"\n";
- OS << "\n";
- OS << "using namespace llvm;\n";
- llvm::SmallVector<StringRef, 2> Namespaces;
- llvm::SplitString(DirLang.getCppNamespace(), Namespaces, "::");
- for (auto Ns : Namespaces)
- OS << "using namespace " << Ns << ";\n";
+void EmitDirectivesBasicImpl(const DirectiveLanguage &DirLang,
+ raw_ostream &OS) {
+ IfDefScope Scope("GEN_DIRECTIVES_IMPL", OS);
// getDirectiveKind(StringRef Str)
GenerateGetKind(DirLang.getDirectives(), OS, "Directive", DirLang,
@@ -773,4 +788,18 @@
GenerateIsAllowedClause(DirLang, OS);
}
+// Generate the implemenation section for the enumeration in the directive
+// language.
+void EmitDirectivesImpl(RecordKeeper &Records, raw_ostream &OS) {
+ const auto DirLang = DirectiveLanguage{Records};
+ if (DirLang.HasValidityErrors())
+ return;
+
+ EmitDirectivesFlangImpl(DirLang, OS);
+
+ GenerateClauseClassMacro(DirLang, OS);
+
+ EmitDirectivesBasicImpl(DirLang, OS);
+}
+
} // namespace llvm
diff --git a/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp
index 4e532c3..77654cb 100644
--- a/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/ExegesisEmitter.cpp
@@ -98,9 +98,9 @@
: Records(RK), PfmCounterNameTable(collectPfmCounters(RK)) {
std::vector<Record *> Targets = Records.getAllDerivedDefinitions("Target");
if (Targets.size() == 0)
- PrintFatalError("ERROR: No 'Target' subclasses defined!");
+ PrintFatalError("No 'Target' subclasses defined!");
if (Targets.size() != 1)
- PrintFatalError("ERROR: Multiple subclasses of Target defined!");
+ PrintFatalError("Multiple subclasses of Target defined!");
Target = std::string(Targets[0]->getName());
}
diff --git a/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp
index 0729ab7..d642621 100644
--- a/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/FastISelEmitter.cpp
@@ -290,9 +290,11 @@
}
void PrintParameters(raw_ostream &OS) const {
+ ListSeparator LS;
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+ OS << LS;
if (Operands[i].isReg()) {
- OS << "unsigned Op" << i << ", bool Op" << i << "IsKill";
+ OS << "unsigned Op" << i;
} else if (Operands[i].isImm()) {
OS << "uint64_t imm" << i;
} else if (Operands[i].isFP()) {
@@ -300,31 +302,25 @@
} else {
llvm_unreachable("Unknown operand kind!");
}
- if (i + 1 != e)
- OS << ", ";
}
}
void PrintArguments(raw_ostream &OS,
const std::vector<std::string> &PR) const {
assert(PR.size() == Operands.size());
- bool PrintedArg = false;
+ ListSeparator LS;
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
if (PR[i] != "")
// Implicit physical register operand.
continue;
- if (PrintedArg)
- OS << ", ";
+ OS << LS;
if (Operands[i].isReg()) {
- OS << "Op" << i << ", Op" << i << "IsKill";
- PrintedArg = true;
+ OS << "Op" << i;
} else if (Operands[i].isImm()) {
OS << "imm" << i;
- PrintedArg = true;
} else if (Operands[i].isFP()) {
OS << "f" << i;
- PrintedArg = true;
} else {
llvm_unreachable("Unknown operand kind!");
}
@@ -332,9 +328,11 @@
}
void PrintArguments(raw_ostream &OS) const {
+ ListSeparator LS;
for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
+ OS << LS;
if (Operands[i].isReg()) {
- OS << "Op" << i << ", Op" << i << "IsKill";
+ OS << "Op" << i;
} else if (Operands[i].isImm()) {
OS << "imm" << i;
} else if (Operands[i].isFP()) {
@@ -342,8 +340,6 @@
} else {
llvm_unreachable("Unknown operand kind!");
}
- if (i + 1 != e)
- OS << ", ";
}
}
@@ -620,10 +616,10 @@
return;
OS << "\n// FastEmit Immediate Predicate functions.\n";
- for (ImmPredicateSet::iterator I = ImmediatePredicates.begin(),
- E = ImmediatePredicates.end(); I != E; ++I) {
- OS << "static bool " << I->getFnName() << "(int64_t Imm) {\n";
- OS << I->getImmediatePredicateCode() << "\n}\n";
+ for (auto ImmediatePredicate : ImmediatePredicates) {
+ OS << "static bool " << ImmediatePredicate.getFnName()
+ << "(int64_t Imm) {\n";
+ OS << ImmediatePredicate.getImmediatePredicateCode() << "\n}\n";
}
OS << "\n\n";
@@ -677,7 +673,7 @@
OS << ");\n";
} else {
OS << "extractsubreg(" << RetVTName
- << ", Op0, Op0IsKill, " << Memo.SubRegNo << ");\n";
+ << ", Op0, " << Memo.SubRegNo << ");\n";
}
if (!PredicateCheck.empty()) {
@@ -695,29 +691,25 @@
void FastISelMap::printFunctionDefinitions(raw_ostream &OS) {
// Now emit code for all the patterns that we collected.
- for (OperandsOpcodeTypeRetPredMap::const_iterator OI = SimplePatterns.begin(),
- OE = SimplePatterns.end(); OI != OE; ++OI) {
- const OperandsSignature &Operands = OI->first;
- const OpcodeTypeRetPredMap &OTM = OI->second;
+ for (const auto &SimplePattern : SimplePatterns) {
+ const OperandsSignature &Operands = SimplePattern.first;
+ const OpcodeTypeRetPredMap &OTM = SimplePattern.second;
- for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
- I != E; ++I) {
- const std::string &Opcode = I->first;
- const TypeRetPredMap &TM = I->second;
+ for (const auto &I : OTM) {
+ const std::string &Opcode = I.first;
+ const TypeRetPredMap &TM = I.second;
OS << "// FastEmit functions for " << Opcode << ".\n";
OS << "\n";
// Emit one function for each opcode,type pair.
- for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
- TI != TE; ++TI) {
- MVT::SimpleValueType VT = TI->first;
- const RetPredMap &RM = TI->second;
+ for (const auto &TI : TM) {
+ MVT::SimpleValueType VT = TI.first;
+ const RetPredMap &RM = TI.second;
if (RM.size() != 1) {
- for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end();
- RI != RE; ++RI) {
- MVT::SimpleValueType RetVT = RI->first;
- const PredMap &PM = RI->second;
+ for (const auto &RI : RM) {
+ MVT::SimpleValueType RetVT = RI.first;
+ const PredMap &PM = RI.second;
OS << "unsigned fastEmit_" << getLegalCName(Opcode) << "_"
<< getLegalCName(std::string(getName(VT))) << "_"
@@ -739,9 +731,8 @@
OS << ", ";
Operands.PrintParameters(OS);
OS << ") {\nswitch (RetVT.SimpleTy) {\n";
- for (RetPredMap::const_iterator RI = RM.begin(), RE = RM.end();
- RI != RE; ++RI) {
- MVT::SimpleValueType RetVT = RI->first;
+ for (const auto &RI : RM) {
+ MVT::SimpleValueType RetVT = RI.first;
OS << " case " << getName(RetVT) << ": return fastEmit_"
<< getLegalCName(Opcode) << "_"
<< getLegalCName(std::string(getName(VT))) << "_"
@@ -783,9 +774,8 @@
Operands.PrintParameters(OS);
OS << ") {\n";
OS << " switch (VT.SimpleTy) {\n";
- for (TypeRetPredMap::const_iterator TI = TM.begin(), TE = TM.end();
- TI != TE; ++TI) {
- MVT::SimpleValueType VT = TI->first;
+ for (const auto &TI : TM) {
+ MVT::SimpleValueType VT = TI.first;
std::string TypeName = std::string(getName(VT));
OS << " case " << TypeName << ": return fastEmit_"
<< getLegalCName(Opcode) << "_" << getLegalCName(TypeName) << "_";
@@ -850,9 +840,8 @@
}
OS << " switch (Opcode) {\n";
- for (OpcodeTypeRetPredMap::const_iterator I = OTM.begin(), E = OTM.end();
- I != E; ++I) {
- const std::string &Opcode = I->first;
+ for (const auto &I : OTM) {
+ const std::string &Opcode = I.first;
OS << " case " << Opcode << ": return fastEmit_"
<< getLegalCName(Opcode) << "_";
diff --git a/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
index 01b39df..c5dd1e6 100644
--- a/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/FixedLenDecoderEmitter.cpp
@@ -973,7 +973,13 @@
<< "Address, const void *Decoder, bool &DecodeComplete) {\n";
Indentation += 2;
OS.indent(Indentation) << "DecodeComplete = true;\n";
- OS.indent(Indentation) << "InsnType tmp;\n";
+ // TODO: When InsnType is large, using uint64_t limits all fields to 64 bits
+ // It would be better for emitBinaryParser to use a 64-bit tmp whenever
+ // possible but fall back to an InsnType-sized tmp for truly large fields.
+ OS.indent(Indentation) << "using TmpType = "
+ "std::conditional_t<std::is_integral<InsnType>::"
+ "value, InsnType, uint64_t>;\n";
+ OS.indent(Indentation) << "TmpType tmp;\n";
OS.indent(Indentation) << "switch (Idx) {\n";
OS.indent(Indentation) << "default: llvm_unreachable(\"Invalid index!\");\n";
unsigned Index = 0;
@@ -1107,18 +1113,24 @@
bool &OpHasCompleteDecoder) const {
const std::string &Decoder = OpInfo.Decoder;
- if (OpInfo.numFields() != 1 || OpInfo.InitValue != 0) {
+ bool UseInsertBits = OpInfo.numFields() != 1 || OpInfo.InitValue != 0;
+
+ if (UseInsertBits) {
o.indent(Indentation) << "tmp = 0x";
o.write_hex(OpInfo.InitValue);
o << ";\n";
}
for (const EncodingField &EF : OpInfo) {
- o.indent(Indentation) << "tmp ";
- if (OpInfo.numFields() != 1 || OpInfo.InitValue != 0) o << '|';
- o << "= fieldFromInstruction"
- << "(insn, " << EF.Base << ", " << EF.Width << ')';
- if (OpInfo.numFields() != 1 || EF.Offset != 0)
+ o.indent(Indentation);
+ if (UseInsertBits)
+ o << "insertBits(tmp, ";
+ else
+ o << "tmp = ";
+ o << "fieldFromInstruction(insn, " << EF.Base << ", " << EF.Width << ')';
+ if (UseInsertBits)
+ o << ", " << EF.Offset << ", " << EF.Width << ')';
+ else if (EF.Offset != 0)
o << " << " << EF.Offset;
o << ";\n";
}
@@ -1210,14 +1222,9 @@
if (IsOr)
o << "(";
- bool First = true;
+ ListSeparator LS(IsOr ? " || " : " && ");
for (auto *Arg : D->getArgs()) {
- if (!First) {
- if (IsOr)
- o << " || ";
- else
- o << " && ";
- }
+ o << LS;
if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
if (NotArg->getOperator()->getAsString() != "not" ||
NotArg->getNumArgs() != 1)
@@ -1230,8 +1237,6 @@
PrintFatalError(Pred->getLoc(), "Invalid AssemblerCondDag!");
o << "Bits[" << Emitter->PredicateNamespace << "::" << Arg->getAsString()
<< "]";
-
- First = false;
}
if (IsOr)
@@ -1250,7 +1255,7 @@
if (!Pred->getValue("AssemblerMatcherPredicate"))
continue;
- if (dyn_cast<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
+ if (isa<DagInit>(Pred->getValue("AssemblerCondDag")->getValue()))
return true;
}
return false;
@@ -1501,13 +1506,13 @@
if (AllowMixed && !Greedy) {
assert(numInstructions == 3);
- for (unsigned i = 0; i < Opcodes.size(); ++i) {
+ for (auto Opcode : Opcodes) {
std::vector<unsigned> StartBits;
std::vector<unsigned> EndBits;
std::vector<uint64_t> FieldVals;
insn_t Insn;
- insnWithID(Insn, Opcodes[i].EncodingID);
+ insnWithID(Insn, Opcode.EncodingID);
// Look for islands of undecoded bits of any instruction.
if (getIslands(StartBits, EndBits, FieldVals, Insn) > 0) {
@@ -1769,13 +1774,13 @@
dumpStack(errs(), "\t\t");
- for (unsigned i = 0; i < Opcodes.size(); ++i) {
+ for (auto Opcode : Opcodes) {
errs() << '\t';
- emitNameWithID(errs(), Opcodes[i].EncodingID);
+ emitNameWithID(errs(), Opcode.EncodingID);
errs() << " ";
dumpBits(
errs(),
- getBitsField(*AllInstructions[Opcodes[i].EncodingID].EncodingDef, "Inst"));
+ getBitsField(*AllInstructions[Opcode.EncodingID].EncodingDef, "Inst"));
errs() << '\n';
}
}
@@ -2149,27 +2154,22 @@
OS << "// Helper functions for extracting fields from encoded instructions.\n"
<< "// InsnType must either be integral or an APInt-like object that "
"must:\n"
- << "// * Have a static const max_size_in_bits equal to the number of bits "
- "in the\n"
- << "// encoding.\n"
<< "// * be default-constructible and copy-constructible\n"
<< "// * be constructible from a uint64_t\n"
<< "// * be constructible from an APInt (this can be private)\n"
- << "// * Support getBitsSet(loBit, hiBit)\n"
- << "// * be convertible to uint64_t\n"
- << "// * Support the ~, &, ==, !=, and |= operators with other objects of "
+ << "// * Support insertBits(bits, startBit, numBits)\n"
+ << "// * Support extractBitsAsZExtValue(numBits, startBit)\n"
+ << "// * be convertible to bool\n"
+ << "// * Support the ~, &, ==, and != operators with other objects of "
"the same type\n"
- << "// * Support shift (<<, >>) with signed and unsigned integers on the "
- "RHS\n"
<< "// * Support put (<<) to raw_ostream&\n"
<< "template <typename InsnType>\n"
<< "#if defined(_MSC_VER) && !defined(__clang__)\n"
<< "__declspec(noinline)\n"
<< "#endif\n"
- << "static InsnType fieldFromInstruction(InsnType insn, unsigned "
- "startBit,\n"
- << " unsigned numBits, "
- "std::true_type) {\n"
+ << "static std::enable_if_t<std::is_integral<InsnType>::value, InsnType>\n"
+ << "fieldFromInstruction(const InsnType &insn, unsigned startBit,\n"
+ << " unsigned numBits) {\n"
<< " assert(startBit + numBits <= 64 && \"Cannot support >64-bit "
"extractions!\");\n"
<< " assert(startBit + numBits <= (sizeof(InsnType) * 8) &&\n"
@@ -2183,22 +2183,32 @@
<< "}\n"
<< "\n"
<< "template <typename InsnType>\n"
- << "static InsnType fieldFromInstruction(InsnType insn, unsigned "
- "startBit,\n"
- << " unsigned numBits, "
- "std::false_type) {\n"
- << " assert(startBit + numBits <= InsnType::max_size_in_bits && "
- "\"Instruction field out of bounds!\");\n"
- << " InsnType fieldMask = InsnType::getBitsSet(0, numBits);\n"
- << " return (insn >> startBit) & fieldMask;\n"
+ << "static std::enable_if_t<!std::is_integral<InsnType>::value, "
+ "uint64_t>\n"
+ << "fieldFromInstruction(const InsnType &insn, unsigned startBit,\n"
+ << " unsigned numBits) {\n"
+ << " return insn.extractBitsAsZExtValue(numBits, startBit);\n"
+ << "}\n\n";
+}
+
+// emitInsertBits - Emit the templated helper function insertBits().
+static void emitInsertBits(formatted_raw_ostream &OS) {
+ OS << "// Helper function for inserting bits extracted from an encoded "
+ "instruction into\n"
+ << "// a field.\n"
+ << "template <typename InsnType>\n"
+ << "static std::enable_if_t<std::is_integral<InsnType>::value>\n"
+ << "insertBits(InsnType &field, InsnType bits, unsigned startBit, "
+ "unsigned numBits) {\n"
+ << " assert(startBit + numBits <= sizeof field * 8);\n"
+ << " field |= (InsnType)bits << startBit;\n"
<< "}\n"
<< "\n"
<< "template <typename InsnType>\n"
- << "static InsnType fieldFromInstruction(InsnType insn, unsigned "
- "startBit,\n"
- << " unsigned numBits) {\n"
- << " return fieldFromInstruction(insn, startBit, numBits, "
- "std::is_integral<InsnType>());\n"
+ << "static std::enable_if_t<!std::is_integral<InsnType>::value>\n"
+ << "insertBits(InsnType &field, uint64_t bits, unsigned startBit, "
+ "unsigned numBits) {\n"
+ << " field.insertBits(bits, startBit, numBits);\n"
<< "}\n\n";
}
@@ -2401,6 +2411,7 @@
OS << "namespace llvm {\n\n";
emitFieldFromInstruction(OS);
+ emitInsertBits(OS);
Target.reverseBitsForLittleEndianEncoding();
@@ -2418,7 +2429,7 @@
if (auto *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
const CodeGenHwModes &HWM = Target.getHwModes();
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
- for (auto &KV : EBM.Map)
+ for (auto &KV : EBM)
HwModeNames.insert(HWM.getMode(KV.first).Name);
}
}
@@ -2436,7 +2447,7 @@
if (DefInit *DI = dyn_cast_or_null<DefInit>(RV->getValue())) {
const CodeGenHwModes &HWM = Target.getHwModes();
EncodingInfoByHwMode EBM(DI->getDef(), HWM);
- for (auto &KV : EBM.Map) {
+ for (auto &KV : EBM) {
NumberedEncodings.emplace_back(KV.second, NumberedInstruction,
HWM.getMode(KV.first).Name);
HwModeNames.insert(HWM.getMode(KV.first).Name);
diff --git a/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp
index ab00cff..c03cd37 100644
--- a/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/GICombinerEmitter.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/Timer.h"
#include "llvm/TableGen/Error.h"
@@ -241,13 +242,12 @@
bool Progressed = false;
SmallSet<GIMatchDagEdge *, 20> EdgesToRemove;
while (!EdgesRemaining.empty()) {
- for (auto EI = EdgesRemaining.begin(), EE = EdgesRemaining.end();
- EI != EE; ++EI) {
- if (Visited.count((*EI)->getFromMI())) {
- if (Roots.count((*EI)->getToMI()))
+ for (auto *EI : EdgesRemaining) {
+ if (Visited.count(EI->getFromMI())) {
+ if (Roots.count(EI->getToMI()))
PrintError(TheDef.getLoc(), "One or more roots are unnecessary");
- Visited.insert((*EI)->getToMI());
- EdgesToRemove.insert(*EI);
+ Visited.insert(EI->getToMI());
+ EdgesToRemove.insert(EI);
Progressed = true;
}
}
diff --git a/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt b/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
index 25fff72..c23ef67 100644
--- a/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
+++ b/src/llvm-project/llvm/utils/TableGen/GlobalISel/CMakeLists.txt
@@ -3,7 +3,7 @@
TableGen
)
-llvm_add_library(LLVMTableGenGlobalISel STATIC DISABLE_LLVM_LINK_LLVM_DYLIB
+add_llvm_library(LLVMTableGenGlobalISel STATIC DISABLE_LLVM_LINK_LLVM_DYLIB
CodeExpander.cpp
GIMatchDag.cpp
GIMatchDagEdge.cpp
diff --git a/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 0a6985a..6930736 100644
--- a/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -90,7 +90,7 @@
}
/// Get the opcode used to check this predicate.
-std::string getMatchOpcodeForPredicate(const TreePredicateFn &Predicate) {
+std::string getMatchOpcodeForImmPredicate(const TreePredicateFn &Predicate) {
return "GIM_Check" + Predicate.getImmTypeIdentifier().str() + "ImmPredicate";
}
@@ -118,7 +118,9 @@
return;
}
if (Ty.isVector()) {
- OS << "GILLT_v" << Ty.getNumElements() << "s" << Ty.getScalarSizeInBits();
+ OS << (Ty.isScalable() ? "GILLT_nxv" : "GILLT_v")
+ << Ty.getElementCount().getKnownMinValue() << "s"
+ << Ty.getScalarSizeInBits();
return;
}
if (Ty.isPointer()) {
@@ -136,7 +138,10 @@
return;
}
if (Ty.isVector()) {
- OS << "LLT::vector(" << Ty.getNumElements() << ", "
+ OS << "LLT::vector("
+ << (Ty.isScalable() ? "ElementCount::getScalable("
+ : "ElementCount::getFixed(")
+ << Ty.getElementCount().getKnownMinValue() << "), "
<< Ty.getScalarSizeInBits() << ")";
return;
}
@@ -169,10 +174,21 @@
if (Ty.isPointer() && Ty.getAddressSpace() != Other.Ty.getAddressSpace())
return Ty.getAddressSpace() < Other.Ty.getAddressSpace();
- if (Ty.isVector() && Ty.getNumElements() != Other.Ty.getNumElements())
- return Ty.getNumElements() < Other.Ty.getNumElements();
+ if (Ty.isVector() && Ty.getElementCount() != Other.Ty.getElementCount())
+ return std::make_tuple(Ty.isScalable(),
+ Ty.getElementCount().getKnownMinValue()) <
+ std::make_tuple(Other.Ty.isScalable(),
+ Other.Ty.getElementCount().getKnownMinValue());
- return Ty.getSizeInBits() < Other.Ty.getSizeInBits();
+ assert((!Ty.isVector() || Ty.isScalable() == Other.Ty.isScalable()) &&
+ "Unexpected mismatch of scalable property");
+ return Ty.isVector()
+ ? std::make_tuple(Ty.isScalable(),
+ Ty.getSizeInBits().getKnownMinSize()) <
+ std::make_tuple(Other.Ty.isScalable(),
+ Other.Ty.getSizeInBits().getKnownMinSize())
+ : Ty.getSizeInBits().getFixedSize() <
+ Other.Ty.getSizeInBits().getFixedSize();
}
bool operator==(const LLTCodeGen &B) const { return Ty == B.Ty; }
@@ -187,12 +203,9 @@
static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) {
MVT VT(SVT);
- if (VT.isScalableVector())
- return None;
-
- if (VT.isFixedLengthVector() && VT.getVectorNumElements() != 1)
+ if (VT.isVector() && !VT.getVectorElementCount().isScalar())
return LLTCodeGen(
- LLT::vector(VT.getVectorNumElements(), VT.getScalarSizeInBits()));
+ LLT::vector(VT.getVectorElementCount(), VT.getScalarSizeInBits()));
if (VT.isInteger() || VT.isFloatingPoint())
return LLTCodeGen(LLT::scalar(VT.getSizeInBits()));
@@ -1562,6 +1575,40 @@
}
};
+/// Generates code to check that this operand is an immediate whose value meets
+/// an immediate predicate.
+class OperandImmPredicateMatcher : public OperandPredicateMatcher {
+protected:
+ TreePredicateFn Predicate;
+
+public:
+ OperandImmPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
+ const TreePredicateFn &Predicate)
+ : OperandPredicateMatcher(IPM_ImmPredicate, InsnVarID, OpIdx),
+ Predicate(Predicate) {}
+
+ bool isIdentical(const PredicateMatcher &B) const override {
+ return OperandPredicateMatcher::isIdentical(B) &&
+ Predicate.getOrigPatFragRecord() ==
+ cast<OperandImmPredicateMatcher>(&B)
+ ->Predicate.getOrigPatFragRecord();
+ }
+
+ static bool classof(const PredicateMatcher *P) {
+ return P->getKind() == IPM_ImmPredicate;
+ }
+
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override {
+ Table << MatchTable::Opcode("GIM_CheckImmOperandPredicate")
+ << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
+ << MatchTable::Comment("MO") << MatchTable::IntValue(OpIdx)
+ << MatchTable::Comment("Predicate")
+ << MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
+ << MatchTable::LineBreak;
+ }
+};
+
/// Generates code to check that a set of predicates match for a particular
/// operand.
class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
@@ -1924,7 +1971,7 @@
void emitPredicateOpcodes(MatchTable &Table,
RuleMatcher &Rule) const override {
- Table << MatchTable::Opcode(getMatchOpcodeForPredicate(Predicate))
+ Table << MatchTable::Opcode(getMatchOpcodeForImmPredicate(Predicate))
<< MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID)
<< MatchTable::Comment("Predicate")
<< MatchTable::NamedValue(getEnumNameForPredicate(Predicate))
@@ -3536,7 +3583,7 @@
const CodeGenInstruction *getEquivNode(Record &Equiv,
const TreePatternNode *N) const;
- Error importRulePredicates(RuleMatcher &M, ArrayRef<Predicate> Predicates);
+ Error importRulePredicates(RuleMatcher &M, ArrayRef<Record *> Predicates);
Expected<InstructionMatcher &>
createAndImportSelDAGMatcher(RuleMatcher &Rule,
InstructionMatcher &InsnMatcher,
@@ -3623,6 +3670,10 @@
Optional<const CodeGenRegisterClass *>
inferRegClassFromPattern(TreePatternNode *N);
+ /// Return the size of the MemoryVT in this predicate, if possible.
+ Optional<unsigned>
+ getMemSizeBitsFromPredicate(const TreePredicateFn &Predicate);
+
// Add builtin predicates.
Expected<InstructionMatcher &>
addBuiltinPredicates(const Record *SrcGIEquivOrNull,
@@ -3723,19 +3774,30 @@
//===- Emitter ------------------------------------------------------------===//
-Error
-GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
- ArrayRef<Predicate> Predicates) {
- for (const Predicate &P : Predicates) {
- if (!P.Def || P.getCondString().empty())
+Error GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
+ ArrayRef<Record *> Predicates) {
+ for (Record *Pred : Predicates) {
+ if (Pred->getValueAsString("CondString").empty())
continue;
- declareSubtargetFeature(P.Def);
- M.addRequiredFeature(P.Def);
+ declareSubtargetFeature(Pred);
+ M.addRequiredFeature(Pred);
}
return Error::success();
}
+Optional<unsigned> GlobalISelEmitter::getMemSizeBitsFromPredicate(const TreePredicateFn &Predicate) {
+ Optional<LLTCodeGen> MemTyOrNone =
+ MVTToLLT(getValueType(Predicate.getMemoryVT()));
+
+ if (!MemTyOrNone)
+ return None;
+
+ // Align so unusual types like i1 don't get rounded down.
+ return llvm::alignTo(
+ static_cast<unsigned>(MemTyOrNone->get().getSizeInBits()), 8);
+}
+
Expected<InstructionMatcher &> GlobalISelEmitter::addBuiltinPredicates(
const Record *SrcGIEquivOrNull, const TreePredicateFn &Predicate,
InstructionMatcher &InsnMatcher, bool &HasAddedMatcher) {
@@ -3775,9 +3837,18 @@
if (Predicate.isStore()) {
if (Predicate.isTruncStore()) {
- // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
- InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
- 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
+ if (Predicate.getMemoryVT() != nullptr) {
+ // FIXME: If MemoryVT is set, we end up with 2 checks for the MMO size.
+ auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);
+ if (!MemSizeInBits)
+ return failedImport("MemVT could not be converted to LLT");
+
+ InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0, *MemSizeInBits /
+ 8);
+ } else {
+ InsnMatcher.addPredicate<MemoryVsLLTSizePredicateMatcher>(
+ 0, MemoryVsLLTSizePredicateMatcher::LessThan, 0);
+ }
return InsnMatcher;
}
if (Predicate.isNonTruncStore()) {
@@ -3804,19 +3875,12 @@
if (Predicate.isLoad() || Predicate.isStore() || Predicate.isAtomic()) {
if (Predicate.getMemoryVT() != nullptr) {
- Optional<LLTCodeGen> MemTyOrNone =
- MVTToLLT(getValueType(Predicate.getMemoryVT()));
-
- if (!MemTyOrNone)
+ auto MemSizeInBits = getMemSizeBitsFromPredicate(Predicate);
+ if (!MemSizeInBits)
return failedImport("MemVT could not be converted to LLT");
- // MMO's work in bytes so we must take care of unusual types like i1
- // don't round down.
- unsigned MemSizeInBits =
- llvm::alignTo(MemTyOrNone->get().getSizeInBits(), 8);
-
InsnMatcher.addPredicate<MemorySizePredicateMatcher>(0,
- MemSizeInBits / 8);
+ *MemSizeInBits / 8);
return InsnMatcher;
}
}
@@ -4153,6 +4217,17 @@
}
if (SrcChild->getOperator()->getName() == "timm") {
OM.addPredicate<ImmOperandMatcher>();
+
+ // Add predicates, if any
+ for (const TreePredicateCall &Call : SrcChild->getPredicateCalls()) {
+ const TreePredicateFn &Predicate = Call.Fn;
+
+ // Only handle immediate patterns for now
+ if (Predicate.isImmediatePattern()) {
+ OM.addPredicate<OperandImmPredicateMatcher>(Predicate);
+ }
+ }
+
return Error::success();
}
}
@@ -4464,7 +4539,6 @@
return failedImport(
"Dst pattern child def is an unsupported tablegen class");
}
-
return failedImport("Dst pattern child is an unsupported kind");
}
@@ -5043,7 +5117,9 @@
" => " +
llvm::to_string(*P.getDstPattern()));
- if (auto Error = importRulePredicates(M, P.getPredicates()))
+ SmallVector<Record *, 4> Predicates;
+ P.getPredicateRecords(Predicates);
+ if (auto Error = importRulePredicates(M, Predicates))
return std::move(Error);
// Next, analyze the pattern operators.
@@ -5351,7 +5427,7 @@
StringRef AdditionalDeclarations,
std::function<bool(const Record *R)> Filter) {
std::vector<const Record *> MatchedRecords;
- const auto &Defs = RK.getAllDerivedDefinitions("PatFrag");
+ const auto &Defs = RK.getAllDerivedDefinitions("PatFrags");
std::copy_if(Defs.begin(), Defs.end(), std::back_inserter(MatchedRecords),
[&](Record *Record) {
return !Record->getValueAsString(CodeFieldName).empty() &&
@@ -5595,9 +5671,17 @@
RK.getAllDerivedDefinitions("GIComplexOperandMatcher");
llvm::sort(ComplexPredicates, orderByName);
- std::vector<Record *> CustomRendererFns =
- RK.getAllDerivedDefinitions("GICustomOperandRenderer");
- llvm::sort(CustomRendererFns, orderByName);
+ std::vector<StringRef> CustomRendererFns;
+ transform(RK.getAllDerivedDefinitions("GICustomOperandRenderer"),
+ std::back_inserter(CustomRendererFns), [](const auto &Record) {
+ return Record->getValueAsString("RendererFn");
+ });
+ // Sort and remove duplicates to get a list of unique renderer functions, in
+ // case some were mentioned more than once.
+ llvm::sort(CustomRendererFns);
+ CustomRendererFns.erase(
+ std::unique(CustomRendererFns.begin(), CustomRendererFns.end()),
+ CustomRendererFns.end());
unsigned MaxTemporaries = 0;
for (const auto &Rule : Rules)
@@ -5675,13 +5759,6 @@
"(const " << Target.getName() << "Subtarget *)&MF.getSubtarget(), &MF);\n"
"}\n";
- if (Target.getName() == "X86" || Target.getName() == "AArch64") {
- // TODO: Implement PGSO.
- OS << "static bool shouldOptForSize(const MachineFunction *MF) {\n";
- OS << " return MF->getFunction().hasOptSize();\n";
- OS << "}\n\n";
- }
-
SubtargetFeatureInfo::emitComputeAvailableFeatures(
Target.getName(), "InstructionSelector",
"computeAvailableFunctionFeatures", FunctionFeatures, OS,
@@ -5791,17 +5868,15 @@
OS << "// Custom renderers.\n"
<< "enum {\n"
<< " GICR_Invalid,\n";
- for (const auto &Record : CustomRendererFns)
- OS << " GICR_" << Record->getValueAsString("RendererFn") << ",\n";
+ for (const auto &Fn : CustomRendererFns)
+ OS << " GICR_" << Fn << ",\n";
OS << "};\n";
OS << Target.getName() << "InstructionSelector::CustomRendererFn\n"
<< Target.getName() << "InstructionSelector::CustomRenderers[] = {\n"
<< " nullptr, // GICR_Invalid\n";
- for (const auto &Record : CustomRendererFns)
- OS << " &" << Target.getName()
- << "InstructionSelector::" << Record->getValueAsString("RendererFn")
- << ", // " << Record->getName() << "\n";
+ for (const auto &Fn : CustomRendererFns)
+ OS << " &" << Target.getName() << "InstructionSelector::" << Fn << ",\n";
OS << "};\n\n";
llvm::stable_sort(Rules, [&](const RuleMatcher &A, const RuleMatcher &B) {
diff --git a/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.cpp b/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.cpp
index 7cd1b0f..3d236b8 100644
--- a/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.cpp
@@ -91,13 +91,10 @@
llvm::sort(Pairs, deref<std::less<PairType>>());
OS << '{';
- for (unsigned i = 0, e = Pairs.size(); i != e; ++i) {
- const PairType *P = Pairs[i];
- OS << '(' << getModeName(P->first)
- << ':' << getMVTName(P->second).str() << ')';
- if (i != e-1)
- OS << ',';
- }
+ ListSeparator LS(",");
+ for (const PairType *P : Pairs)
+ OS << LS << '(' << getModeName(P->first) << ':'
+ << getMVTName(P->second).str() << ')';
OS << '}';
}
@@ -183,12 +180,9 @@
llvm::sort(Pairs, deref<std::less<PairType>>());
OS << '{';
- for (unsigned i = 0, e = Pairs.size(); i != e; ++i) {
- const PairType *P = Pairs[i];
- OS << '(' << getModeName(P->first) << ':' << P->second << ')';
- if (i != e-1)
- OS << ',';
- }
+ ListSeparator LS(",");
+ for (const PairType *P : Pairs)
+ OS << LS << '(' << getModeName(P->first) << ':' << P->second << ')';
OS << '}';
}
diff --git a/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.h b/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.h
index d92e590..c97add6 100644
--- a/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.h
+++ b/src/llvm-project/llvm/utils/TableGen/InfoByHwMode.h
@@ -15,10 +15,10 @@
#define LLVM_UTILS_TABLEGEN_INFOBYHWMODE_H
#include "CodeGenHwModes.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/MachineValueType.h"
#include <map>
-#include <set>
#include <string>
#include <vector>
@@ -37,10 +37,10 @@
};
template <typename InfoT>
-std::vector<unsigned> union_modes(const InfoByHwMode<InfoT> &A,
- const InfoByHwMode<InfoT> &B) {
- std::vector<unsigned> V;
- std::set<unsigned> U;
+void union_modes(const InfoByHwMode<InfoT> &A,
+ const InfoByHwMode<InfoT> &B,
+ SmallVectorImpl<unsigned> &Modes) {
+ SmallSet<unsigned, 4> U;
for (const auto &P : A)
U.insert(P.first);
for (const auto &P : B)
@@ -49,12 +49,11 @@
bool HasDefault = false;
for (unsigned M : U)
if (M != DefaultMode)
- V.push_back(M);
+ Modes.push_back(M);
else
HasDefault = true;
if (HasDefault)
- V.push_back(DefaultMode);
- return V;
+ Modes.push_back(DefaultMode);
}
template <typename InfoT>
@@ -114,6 +113,7 @@
Map.insert(std::make_pair(DefaultMode, I));
}
+protected:
MapType Map;
};
@@ -178,6 +178,10 @@
bool hasStricterSpillThan(const RegSizeInfoByHwMode &I) const;
void writeToStream(raw_ostream &OS) const;
+
+ void insertRegSizeForMode(unsigned Mode, RegSizeInfo Info) {
+ Map.insert(std::make_pair(Mode, Info));
+ }
};
raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T);
diff --git a/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp
index 66744bf..bc39122 100644
--- a/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/InstrDocsEmitter.cpp
@@ -141,13 +141,9 @@
FLAG(isAuthenticated)
if (!FlagStrings.empty()) {
OS << "Flags: ";
- bool IsFirst = true;
- for (auto FlagString : FlagStrings) {
- if (!IsFirst)
- OS << ", ";
- OS << "``" << FlagString << "``";
- IsFirst = false;
- }
+ ListSeparator LS;
+ for (auto FlagString : FlagStrings)
+ OS << LS << "``" << FlagString << "``";
OS << "\n\n";
}
@@ -192,26 +188,18 @@
// Implicit definitions.
if (!II->ImplicitDefs.empty()) {
OS << "Implicit defs: ";
- bool IsFirst = true;
- for (Record *Def : II->ImplicitDefs) {
- if (!IsFirst)
- OS << ", ";
- OS << "``" << Def->getName() << "``";
- IsFirst = false;
- }
+ ListSeparator LS;
+ for (Record *Def : II->ImplicitDefs)
+ OS << LS << "``" << Def->getName() << "``";
OS << "\n\n";
}
// Implicit uses.
if (!II->ImplicitUses.empty()) {
OS << "Implicit uses: ";
- bool IsFirst = true;
- for (Record *Use : II->ImplicitUses) {
- if (!IsFirst)
- OS << ", ";
- OS << "``" << Use->getName() << "``";
- IsFirst = false;
- }
+ ListSeparator LS;
+ for (Record *Use : II->ImplicitUses)
+ OS << LS << "``" << Use->getName() << "``";
OS << "\n\n";
}
@@ -220,13 +208,9 @@
II->TheDef->getValueAsListOfDefs("Predicates");
if (!Predicates.empty()) {
OS << "Predicates: ";
- bool IsFirst = true;
- for (Record *P : Predicates) {
- if (!IsFirst)
- OS << ", ";
- OS << "``" << P->getName() << "``";
- IsFirst = false;
- }
+ ListSeparator LS;
+ for (Record *P : Predicates)
+ OS << LS << "``" << P->getName() << "``";
OS << "\n\n";
}
}
diff --git a/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp
index 9ff385f..aee887a 100644
--- a/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/InstrInfoEmitter.cpp
@@ -19,6 +19,7 @@
#include "SequenceToOffsetTable.h"
#include "TableGenBackends.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
@@ -27,6 +28,7 @@
#include "llvm/TableGen/TableGenBackend.h"
#include <cassert>
#include <cstdint>
+#include <iterator>
#include <map>
#include <string>
#include <utility>
@@ -87,6 +89,13 @@
void emitOperandNameMappings(raw_ostream &OS, const CodeGenTarget &Target,
ArrayRef<const CodeGenInstruction*> NumberedInstructions);
+ void emitLogicalOperandSizeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions);
+ void emitLogicalOperandTypeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions);
+
// Operand information.
void EmitOperandInfo(raw_ostream &OS, OperandInfoMapTy &OperandInfoIDs);
std::vector<std::string> GetOperandInfo(const CodeGenInstruction &Inst);
@@ -442,6 +451,182 @@
OS << "#endif // GET_INSTRINFO_OPERAND_TYPE\n\n";
}
+void InstrInfoEmitter::emitLogicalOperandSizeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
+ std::map<std::vector<unsigned>, unsigned> LogicalOpSizeMap;
+
+ std::map<unsigned, std::vector<std::string>> InstMap;
+
+ size_t LogicalOpListSize = 0U;
+ std::vector<unsigned> LogicalOpList;
+ for (const auto *Inst : NumberedInstructions) {
+ if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
+ continue;
+
+ LogicalOpList.clear();
+ llvm::transform(Inst->Operands, std::back_inserter(LogicalOpList),
+ [](const CGIOperandList::OperandInfo &Op) -> unsigned {
+ auto *MIOI = Op.MIOperandInfo;
+ if (!MIOI || MIOI->getNumArgs() == 0)
+ return 1;
+ return MIOI->getNumArgs();
+ });
+ LogicalOpListSize = std::max(LogicalOpList.size(), LogicalOpListSize);
+
+ auto I =
+ LogicalOpSizeMap.insert({LogicalOpList, LogicalOpSizeMap.size()}).first;
+ InstMap[I->second].push_back(
+ (Namespace + "::" + Inst->TheDef->getName()).str());
+ }
+
+ OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
+ OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n";
+ OS << "namespace llvm {\n";
+ OS << "namespace " << Namespace << " {\n";
+ OS << "LLVM_READONLY static unsigned\n";
+ OS << "getLogicalOperandSize(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
+ if (!InstMap.empty()) {
+ std::vector<const std::vector<unsigned> *> LogicalOpSizeList(
+ LogicalOpSizeMap.size());
+ for (auto &P : LogicalOpSizeMap) {
+ LogicalOpSizeList[P.second] = &P.first;
+ }
+ OS << " static const unsigned SizeMap[][" << LogicalOpListSize
+ << "] = {\n";
+ for (auto &R : LogicalOpSizeList) {
+ const auto &Row = *R;
+ OS << " {";
+ int i;
+ for (i = 0; i < static_cast<int>(Row.size()); ++i) {
+ OS << Row[i] << ", ";
+ }
+ for (; i < static_cast<int>(LogicalOpListSize); ++i) {
+ OS << "0, ";
+ }
+ OS << "}, ";
+ OS << "\n";
+ }
+ OS << " };\n";
+
+ OS << " switch (Opcode) {\n";
+ OS << " default: return LogicalOpIdx;\n";
+ for (auto &P : InstMap) {
+ auto OpMapIdx = P.first;
+ const auto &Insts = P.second;
+ for (const auto &Inst : Insts) {
+ OS << " case " << Inst << ":\n";
+ }
+ OS << " return SizeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
+ }
+ OS << " }\n";
+ } else {
+ OS << " return LogicalOpIdx;\n";
+ }
+ OS << "}\n";
+
+ OS << "LLVM_READONLY static inline unsigned\n";
+ OS << "getLogicalOperandIdx(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
+ OS << " auto S = 0U;\n";
+ OS << " for (auto i = 0U; i < LogicalOpIdx; ++i)\n";
+ OS << " S += getLogicalOperandSize(Opcode, i);\n";
+ OS << " return S;\n";
+ OS << "}\n";
+
+ OS << "} // end namespace " << Namespace << "\n";
+ OS << "} // end namespace llvm\n";
+ OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_SIZE_MAP\n\n";
+}
+
+void InstrInfoEmitter::emitLogicalOperandTypeMappings(
+ raw_ostream &OS, StringRef Namespace,
+ ArrayRef<const CodeGenInstruction *> NumberedInstructions) {
+ std::map<std::vector<std::string>, unsigned> LogicalOpTypeMap;
+
+ std::map<unsigned, std::vector<std::string>> InstMap;
+
+ size_t OpTypeListSize = 0U;
+ std::vector<std::string> LogicalOpTypeList;
+ for (const auto *Inst : NumberedInstructions) {
+ if (!Inst->TheDef->getValueAsBit("UseLogicalOperandMappings"))
+ continue;
+
+ LogicalOpTypeList.clear();
+ for (const auto &Op : Inst->Operands) {
+ auto *OpR = Op.Rec;
+ if ((OpR->isSubClassOf("Operand") ||
+ OpR->isSubClassOf("RegisterOperand") ||
+ OpR->isSubClassOf("RegisterClass")) &&
+ !OpR->isAnonymous()) {
+ LogicalOpTypeList.push_back(
+ (Namespace + "::OpTypes::" + Op.Rec->getName()).str());
+ } else {
+ LogicalOpTypeList.push_back("-1");
+ }
+ }
+ OpTypeListSize = std::max(LogicalOpTypeList.size(), OpTypeListSize);
+
+ auto I =
+ LogicalOpTypeMap.insert({LogicalOpTypeList, LogicalOpTypeMap.size()})
+ .first;
+ InstMap[I->second].push_back(
+ (Namespace + "::" + Inst->TheDef->getName()).str());
+ }
+
+ OS << "#ifdef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
+ OS << "#undef GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n";
+ OS << "namespace llvm {\n";
+ OS << "namespace " << Namespace << " {\n";
+ OS << "LLVM_READONLY static int\n";
+ OS << "getLogicalOperandType(uint16_t Opcode, uint16_t LogicalOpIdx) {\n";
+ if (!InstMap.empty()) {
+ std::vector<const std::vector<std::string> *> LogicalOpTypeList(
+ LogicalOpTypeMap.size());
+ for (auto &P : LogicalOpTypeMap) {
+ LogicalOpTypeList[P.second] = &P.first;
+ }
+ OS << " static const int TypeMap[][" << OpTypeListSize << "] = {\n";
+ for (int r = 0, rs = LogicalOpTypeList.size(); r < rs; ++r) {
+ const auto &Row = *LogicalOpTypeList[r];
+ OS << " {";
+ int i, s = Row.size();
+ for (i = 0; i < s; ++i) {
+ if (i > 0)
+ OS << ", ";
+ OS << Row[i];
+ }
+ for (; i < static_cast<int>(OpTypeListSize); ++i) {
+ if (i > 0)
+ OS << ", ";
+ OS << "-1";
+ }
+ OS << "}";
+ if (r != rs - 1)
+ OS << ",";
+ OS << "\n";
+ }
+ OS << " };\n";
+
+ OS << " switch (Opcode) {\n";
+ OS << " default: return -1;\n";
+ for (auto &P : InstMap) {
+ auto OpMapIdx = P.first;
+ const auto &Insts = P.second;
+ for (const auto &Inst : Insts) {
+ OS << " case " << Inst << ":\n";
+ }
+ OS << " return TypeMap[" << OpMapIdx << "][LogicalOpIdx];\n";
+ }
+ OS << " }\n";
+ } else {
+ OS << " return -1;\n";
+ }
+ OS << "}\n";
+ OS << "} // end namespace " << Namespace << "\n";
+ OS << "} // end namespace llvm\n";
+ OS << "#endif // GET_INSTRINFO_LOGICAL_OPERAND_TYPE_MAP\n\n";
+}
+
void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS,
StringRef TargetName) {
RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate");
@@ -726,6 +911,12 @@
Records.startTimer("Emit operand type mappings");
emitOperandTypeMappings(OS, Target, NumberedInstructions);
+ Records.startTimer("Emit logical operand size mappings");
+ emitLogicalOperandSizeMappings(OS, TargetName, NumberedInstructions);
+
+ Records.startTimer("Emit logical operand type mappings");
+ emitLogicalOperandTypeMappings(OS, TargetName, NumberedInstructions);
+
Records.startTimer("Emit helper methods");
emitMCIIHelperMethods(OS, TargetName);
}
diff --git a/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp
index 978d24c..3d1d258 100644
--- a/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/IntrinsicEmitter.cpp
@@ -378,7 +378,7 @@
MVT VVT = VT;
if (VVT.isScalableVector())
Sig.push_back(IIT_SCALABLE_VEC);
- switch (VVT.getVectorNumElements()) {
+ switch (VVT.getVectorMinNumElements()) {
default: PrintFatalError("unhandled vector type width in intrinsic!");
case 1: Sig.push_back(IIT_V1); break;
case 2: Sig.push_back(IIT_V2); break;
@@ -584,6 +584,9 @@
if (L->isNoDuplicate != R->isNoDuplicate)
return R->isNoDuplicate;
+ if (L->isNoMerge != R->isNoMerge)
+ return R->isNoMerge;
+
if (L->isNoReturn != R->isNoReturn)
return R->isNoReturn;
@@ -659,240 +662,165 @@
OS << " if (id != 0) {\n";
OS << " switch(IntrinsicsToAttributesMap[id - 1]) {\n";
OS << " default: llvm_unreachable(\"Invalid attribute number\");\n";
- for (UniqAttrMapTy::const_iterator I = UniqAttributes.begin(),
- E = UniqAttributes.end(); I != E; ++I) {
- OS << " case " << I->second << ": {\n";
+ for (auto UniqAttribute : UniqAttributes) {
+ OS << " case " << UniqAttribute.second << ": {\n";
- const CodeGenIntrinsic &intrinsic = *(I->first);
+ const CodeGenIntrinsic &Intrinsic = *(UniqAttribute.first);
// Keep track of the number of attributes we're writing out.
unsigned numAttrs = 0;
// The argument attributes are alreadys sorted by argument index.
- unsigned ai = 0, ae = intrinsic.ArgumentAttributes.size();
- if (ae) {
- while (ai != ae) {
- unsigned attrIdx = intrinsic.ArgumentAttributes[ai].Index;
+ unsigned Ai = 0, Ae = Intrinsic.ArgumentAttributes.size();
+ if (Ae) {
+ while (Ai != Ae) {
+ unsigned AttrIdx = Intrinsic.ArgumentAttributes[Ai].Index;
- OS << " const Attribute::AttrKind AttrParam" << attrIdx << "[]= {";
- bool addComma = false;
+ OS << " const Attribute::AttrKind AttrParam" << AttrIdx << "[]= {";
+ ListSeparator LS(",");
bool AllValuesAreZero = true;
SmallVector<uint64_t, 8> Values;
do {
- switch (intrinsic.ArgumentAttributes[ai].Kind) {
+ switch (Intrinsic.ArgumentAttributes[Ai].Kind) {
case CodeGenIntrinsic::NoCapture:
- if (addComma)
- OS << ",";
- OS << "Attribute::NoCapture";
- addComma = true;
+ OS << LS << "Attribute::NoCapture";
break;
case CodeGenIntrinsic::NoAlias:
- if (addComma)
- OS << ",";
- OS << "Attribute::NoAlias";
- addComma = true;
+ OS << LS << "Attribute::NoAlias";
break;
case CodeGenIntrinsic::NoUndef:
- if (addComma)
- OS << ",";
- OS << "Attribute::NoUndef";
- addComma = true;
+ OS << LS << "Attribute::NoUndef";
break;
case CodeGenIntrinsic::Returned:
- if (addComma)
- OS << ",";
- OS << "Attribute::Returned";
- addComma = true;
+ OS << LS << "Attribute::Returned";
break;
case CodeGenIntrinsic::ReadOnly:
- if (addComma)
- OS << ",";
- OS << "Attribute::ReadOnly";
- addComma = true;
+ OS << LS << "Attribute::ReadOnly";
break;
case CodeGenIntrinsic::WriteOnly:
- if (addComma)
- OS << ",";
- OS << "Attribute::WriteOnly";
- addComma = true;
+ OS << LS << "Attribute::WriteOnly";
break;
case CodeGenIntrinsic::ReadNone:
- if (addComma)
- OS << ",";
- OS << "Attribute::ReadNone";
- addComma = true;
+ OS << LS << "Attribute::ReadNone";
break;
case CodeGenIntrinsic::ImmArg:
- if (addComma)
- OS << ',';
- OS << "Attribute::ImmArg";
- addComma = true;
+ OS << LS << "Attribute::ImmArg";
break;
case CodeGenIntrinsic::Alignment:
- if (addComma)
- OS << ',';
- OS << "Attribute::Alignment";
- addComma = true;
+ OS << LS << "Attribute::Alignment";
break;
}
- uint64_t V = intrinsic.ArgumentAttributes[ai].Value;
+ uint64_t V = Intrinsic.ArgumentAttributes[Ai].Value;
Values.push_back(V);
AllValuesAreZero &= (V == 0);
- ++ai;
- } while (ai != ae && intrinsic.ArgumentAttributes[ai].Index == attrIdx);
+ ++Ai;
+ } while (Ai != Ae && Intrinsic.ArgumentAttributes[Ai].Index == AttrIdx);
OS << "};\n";
// Generate attribute value array if not all attribute values are zero.
if (!AllValuesAreZero) {
- OS << " const uint64_t AttrValParam" << attrIdx << "[]= {";
- addComma = false;
- for (const auto V : Values) {
- if (addComma)
- OS << ',';
- OS << V;
- addComma = true;
- }
+ OS << " const uint64_t AttrValParam" << AttrIdx << "[]= {";
+ ListSeparator LSV(",");
+ for (const auto V : Values)
+ OS << LSV << V;
OS << "};\n";
}
OS << " AS[" << numAttrs++ << "] = AttributeList::get(C, "
- << attrIdx << ", AttrParam" << attrIdx;
+ << AttrIdx << ", AttrParam" << AttrIdx;
if (!AllValuesAreZero)
- OS << ", AttrValParam" << attrIdx;
+ OS << ", AttrValParam" << AttrIdx;
OS << ");\n";
}
}
- if (!intrinsic.canThrow ||
- (intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem &&
- !intrinsic.hasSideEffects) ||
- intrinsic.isNoReturn || intrinsic.isNoSync || intrinsic.isNoFree ||
- intrinsic.isWillReturn || intrinsic.isCold || intrinsic.isNoDuplicate ||
- intrinsic.isConvergent || intrinsic.isSpeculatable) {
+ if (!Intrinsic.canThrow ||
+ (Intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem &&
+ !Intrinsic.hasSideEffects) ||
+ Intrinsic.isNoReturn || Intrinsic.isNoSync || Intrinsic.isNoFree ||
+ Intrinsic.isWillReturn || Intrinsic.isCold || Intrinsic.isNoDuplicate ||
+ Intrinsic.isNoMerge || Intrinsic.isConvergent ||
+ Intrinsic.isSpeculatable) {
OS << " const Attribute::AttrKind Atts[] = {";
- bool addComma = false;
- if (!intrinsic.canThrow) {
- OS << "Attribute::NoUnwind";
- addComma = true;
- }
- if (intrinsic.isNoReturn) {
- if (addComma)
- OS << ",";
- OS << "Attribute::NoReturn";
- addComma = true;
- }
- if (intrinsic.isNoSync) {
- if (addComma)
- OS << ",";
- OS << "Attribute::NoSync";
- addComma = true;
- }
- if (intrinsic.isNoFree) {
- if (addComma)
- OS << ",";
- OS << "Attribute::NoFree";
- addComma = true;
- }
- if (intrinsic.isWillReturn) {
- if (addComma)
- OS << ",";
- OS << "Attribute::WillReturn";
- addComma = true;
- }
- if (intrinsic.isCold) {
- if (addComma)
- OS << ",";
- OS << "Attribute::Cold";
- addComma = true;
- }
- if (intrinsic.isNoDuplicate) {
- if (addComma)
- OS << ",";
- OS << "Attribute::NoDuplicate";
- addComma = true;
- }
- if (intrinsic.isConvergent) {
- if (addComma)
- OS << ",";
- OS << "Attribute::Convergent";
- addComma = true;
- }
- if (intrinsic.isSpeculatable) {
- if (addComma)
- OS << ",";
- OS << "Attribute::Speculatable";
- addComma = true;
- }
+ ListSeparator LS(",");
+ if (!Intrinsic.canThrow)
+ OS << LS << "Attribute::NoUnwind";
+ if (Intrinsic.isNoReturn)
+ OS << LS << "Attribute::NoReturn";
+ if (Intrinsic.isNoSync)
+ OS << LS << "Attribute::NoSync";
+ if (Intrinsic.isNoFree)
+ OS << LS << "Attribute::NoFree";
+ if (Intrinsic.isWillReturn)
+ OS << LS << "Attribute::WillReturn";
+ if (Intrinsic.isCold)
+ OS << LS << "Attribute::Cold";
+ if (Intrinsic.isNoDuplicate)
+ OS << LS << "Attribute::NoDuplicate";
+ if (Intrinsic.isNoMerge)
+ OS << LS << "Attribute::NoMerge";
+ if (Intrinsic.isConvergent)
+ OS << LS << "Attribute::Convergent";
+ if (Intrinsic.isSpeculatable)
+ OS << LS << "Attribute::Speculatable";
- switch (intrinsic.ModRef) {
+ switch (Intrinsic.ModRef) {
case CodeGenIntrinsic::NoMem:
- if (intrinsic.hasSideEffects)
+ if (Intrinsic.hasSideEffects)
break;
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::ReadNone";
break;
case CodeGenIntrinsic::ReadArgMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::ReadOnly,";
OS << "Attribute::ArgMemOnly";
break;
case CodeGenIntrinsic::ReadMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::ReadOnly";
break;
case CodeGenIntrinsic::ReadInaccessibleMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::ReadOnly,";
OS << "Attribute::InaccessibleMemOnly";
break;
case CodeGenIntrinsic::ReadInaccessibleMemOrArgMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::ReadOnly,";
OS << "Attribute::InaccessibleMemOrArgMemOnly";
break;
case CodeGenIntrinsic::WriteArgMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::WriteOnly,";
OS << "Attribute::ArgMemOnly";
break;
case CodeGenIntrinsic::WriteMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::WriteOnly";
break;
case CodeGenIntrinsic::WriteInaccessibleMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::WriteOnly,";
OS << "Attribute::InaccessibleMemOnly";
break;
case CodeGenIntrinsic::WriteInaccessibleMemOrArgMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::WriteOnly,";
OS << "Attribute::InaccessibleMemOrArgMemOnly";
break;
case CodeGenIntrinsic::ReadWriteArgMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::ArgMemOnly";
break;
case CodeGenIntrinsic::ReadWriteInaccessibleMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::InaccessibleMemOnly";
break;
case CodeGenIntrinsic::ReadWriteInaccessibleMemOrArgMem:
- if (addComma)
- OS << ",";
+ OS << LS;
OS << "Attribute::InaccessibleMemOrArgMemOnly";
break;
case CodeGenIntrinsic::ReadWriteMem:
@@ -977,25 +905,25 @@
OS << " StringRef TargetPrefix(TargetPrefixStr);\n\n";
// Note: this could emit significantly better code if we cared.
- for (BIMTy::iterator I = BuiltinMap.begin(), E = BuiltinMap.end();I != E;++I){
+ for (auto &I : BuiltinMap) {
OS << " ";
- if (!I->first.empty())
- OS << "if (TargetPrefix == \"" << I->first << "\") ";
+ if (!I.first.empty())
+ OS << "if (TargetPrefix == \"" << I.first << "\") ";
else
OS << "/* Target Independent Builtins */ ";
OS << "{\n";
// Emit the comparisons for this target prefix.
- OS << " static const BuiltinEntry " << I->first << "Names[] = {\n";
- for (const auto &P : I->second) {
+ OS << " static const BuiltinEntry " << I.first << "Names[] = {\n";
+ for (const auto &P : I.second) {
OS << " {Intrinsic::" << P.second << ", "
<< Table.GetOrAddStringOffset(P.first) << "}, // " << P.first << "\n";
}
OS << " };\n";
- OS << " auto I = std::lower_bound(std::begin(" << I->first << "Names),\n";
- OS << " std::end(" << I->first << "Names),\n";
+ OS << " auto I = std::lower_bound(std::begin(" << I.first << "Names),\n";
+ OS << " std::end(" << I.first << "Names),\n";
OS << " BuiltinNameStr);\n";
- OS << " if (I != std::end(" << I->first << "Names) &&\n";
+ OS << " if (I != std::end(" << I.first << "Names) &&\n";
OS << " I->getName() == BuiltinNameStr)\n";
OS << " return I->IntrinID;\n";
OS << " }\n";
diff --git a/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp
index 8e6c058..0809432 100644
--- a/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -251,7 +251,7 @@
// Prefix values.
OS << ", {";
- for (StringRef PrefixKey : Prefix.first)
+ for (const auto &PrefixKey : Prefix.first)
OS << "\"" << PrefixKey << "\" COMMA ";
OS << "nullptr})\n";
}
diff --git a/src/llvm-project/llvm/utils/TableGen/PseudoLoweringEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
index e05409d..6acb630 100644
--- a/src/llvm-project/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/PseudoLoweringEmitter.cpp
@@ -108,6 +108,11 @@
OperandMap[BaseIdx + i].Kind = OpData::Imm;
OperandMap[BaseIdx + i].Data.Imm = II->getValue();
++OpsAdded;
+ } else if (auto *BI = dyn_cast<BitsInit>(Dag->getArg(i))) {
+ auto *II = cast<IntInit>(BI->convertInitializerTo(IntRecTy::get()));
+ OperandMap[BaseIdx + i].Kind = OpData::Imm;
+ OperandMap[BaseIdx + i].Data.Imm = II->getValue();
+ ++OpsAdded;
} else if (DagInit *SubDag = dyn_cast<DagInit>(Dag->getArg(i))) {
// Just add the operands recursively. This is almost certainly
// a constant value for a complex operand (> 1 MI operand).
diff --git a/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
index 183c8f9..e931801 100644
--- a/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/RISCVCompressInstEmitter.cpp
@@ -273,8 +273,8 @@
// The Instruction might have tied operands so the Dag might have
// a fewer operand count.
unsigned RealCount = Inst.Operands.size();
- for (unsigned i = 0; i < Inst.Operands.size(); i++)
- if (Inst.Operands[i].getTiedRegister() != -1)
+ for (const auto &Operand : Inst.Operands)
+ if (Operand.getTiedRegister() != -1)
--RealCount;
if (Dag->getNumArgs() != RealCount)
diff --git a/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index dce7594..037fad2 100644
--- a/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -305,9 +305,8 @@
for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {
ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
PSets[i].reserve(PSetIDs.size());
- for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
- PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) {
- PSets[i].push_back(RegBank.getRegPressureSet(*PSetI).Order);
+ for (unsigned PSetID : PSetIDs) {
+ PSets[i].push_back(RegBank.getRegPressureSet(PSetID).Order);
}
llvm::sort(PSets[i]);
PSetsSeqs.add(PSets[i]);
@@ -399,11 +398,9 @@
return;
// Now we know maximal length of number list. Append -1's, where needed
- for (DwarfRegNumsVecTy::iterator I = DwarfRegNums.begin(),
- E = DwarfRegNums.end();
- I != E; ++I)
- for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
- I->second.push_back(-1);
+ for (auto &DwarfRegNum : DwarfRegNums)
+ for (unsigned I = DwarfRegNum.second.size(), E = maxLength; I != E; ++I)
+ DwarfRegNum.second.push_back(-1);
StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
@@ -411,10 +408,10 @@
// Emit reverse information about the dwarf register numbers.
for (unsigned j = 0; j < 2; ++j) {
- for (unsigned i = 0, e = maxLength; i != e; ++i) {
+ for (unsigned I = 0, E = maxLength; I != E; ++I) {
OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
- OS << i << "Dwarf2L[]";
+ OS << I << "Dwarf2L[]";
if (!isCtor) {
OS << " = {\n";
@@ -422,17 +419,15 @@
// Store the mapping sorted by the LLVM reg num so lookup can be done
// with a binary search.
std::map<uint64_t, Record*> Dwarf2LMap;
- for (DwarfRegNumsVecTy::iterator
- I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
- int DwarfRegNo = I->second[i];
+ for (auto &DwarfRegNum : DwarfRegNums) {
+ int DwarfRegNo = DwarfRegNum.second[I];
if (DwarfRegNo < 0)
continue;
- Dwarf2LMap[DwarfRegNo] = I->first;
+ Dwarf2LMap[DwarfRegNo] = DwarfRegNum.first;
}
- for (std::map<uint64_t, Record*>::iterator
- I = Dwarf2LMap.begin(), E = Dwarf2LMap.end(); I != E; ++I)
- OS << " { " << I->first << "U, " << getQualifiedName(I->second)
+ for (auto &I : Dwarf2LMap)
+ OS << " { " << I.first << "U, " << getQualifiedName(I.second)
<< " },\n";
OS << "};\n";
@@ -443,11 +438,10 @@
// We have to store the size in a const global, it's used in multiple
// places.
OS << "extern const unsigned " << Namespace
- << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "Dwarf2LSize";
+ << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2LSize";
if (!isCtor)
OS << " = array_lengthof(" << Namespace
- << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
- << "Dwarf2L);\n\n";
+ << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2L);\n\n";
else
OS << ";\n\n";
}
@@ -486,13 +480,12 @@
OS << " = {\n";
// Store the mapping sorted by the Dwarf reg num so lookup can be done
// with a binary search.
- for (DwarfRegNumsVecTy::iterator
- I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
- int RegNo = I->second[i];
+ for (auto &DwarfRegNum : DwarfRegNums) {
+ int RegNo = DwarfRegNum.second[i];
if (RegNo == -1) // -1 is the default value, don't emit a mapping.
continue;
- OS << " { " << getQualifiedName(I->first) << ", " << RegNo
+ OS << " { " << getQualifiedName(DwarfRegNum.first) << ", " << RegNo
<< "U },\n";
}
OS << "};\n";
@@ -1029,9 +1022,10 @@
ArrayRef<const CodeGenRegister*> Roots = RegBank.getRegUnit(i).getRoots();
assert(!Roots.empty() && "All regunits must have a root register.");
assert(Roots.size() <= 2 && "More than two roots not supported yet.");
- OS << " { " << getQualifiedName(Roots.front()->TheDef);
- for (unsigned r = 1; r != Roots.size(); ++r)
- OS << ", " << getQualifiedName(Roots[r]->TheDef);
+ OS << " { ";
+ ListSeparator LS;
+ for (const CodeGenRegister *R : Roots)
+ OS << LS << getQualifiedName(R->TheDef);
OS << " },\n";
}
OS << "};\n\n";
@@ -1083,12 +1077,15 @@
for (const auto &RC : RegisterClasses) {
assert(isInt<8>(RC.CopyCost) && "Copy cost too large.");
+ uint32_t RegSize = 0;
+ if (RC.RSI.isSimple())
+ RegSize = RC.RSI.getSimple().RegSize;
OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
- << RegClassStrings.get(RC.getName()) << ", "
- << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
- << RC.getQualifiedName() + "RegClassID" << ", "
- << RC.CopyCost << ", "
- << ( RC.Allocatable ? "true" : "false" ) << " },\n";
+ << RegClassStrings.get(RC.getName()) << ", " << RC.getOrder().size()
+ << ", sizeof(" << RC.getName() << "Bits), "
+ << RC.getQualifiedName() + "RegClassID"
+ << ", " << RegSize << ", " << RC.CopyCost << ", "
+ << (RC.Allocatable ? "true" : "false") << " },\n";
}
OS << "};\n\n";
@@ -1441,19 +1438,52 @@
// Emit extra information about registers.
const std::string &TargetName = std::string(Target.getName());
- OS << "\nstatic const TargetRegisterInfoDesc "
- << TargetName << "RegInfoDesc[] = { // Extra Descriptors\n";
- OS << " { 0, false },\n";
-
const auto &Regs = RegBank.getRegisters();
- for (const auto &Reg : Regs) {
- OS << " { ";
- OS << Reg.CostPerUse << ", "
- << ( AllocatableRegs.count(Reg.TheDef) != 0 ? "true" : "false" )
- << " },\n";
- }
- OS << "};\n"; // End of register descriptors...
+ unsigned NumRegCosts = 1;
+ for (const auto &Reg : Regs)
+ NumRegCosts = std::max((size_t)NumRegCosts, Reg.CostPerUse.size());
+ std::vector<unsigned> AllRegCostPerUse;
+ llvm::BitVector InAllocClass(Regs.size() + 1, false);
+ AllRegCostPerUse.insert(AllRegCostPerUse.end(), NumRegCosts, 0);
+
+ // Populate the vector RegCosts with the CostPerUse list of the registers
+ // in the order they are read. Have at most NumRegCosts entries for
+ // each register. Fill with zero for values which are not explicitly given.
+ for (const auto &Reg : Regs) {
+ auto Costs = Reg.CostPerUse;
+ AllRegCostPerUse.insert(AllRegCostPerUse.end(), Costs.begin(), Costs.end());
+ if (NumRegCosts > Costs.size())
+ AllRegCostPerUse.insert(AllRegCostPerUse.end(),
+ NumRegCosts - Costs.size(), 0);
+
+ if (AllocatableRegs.count(Reg.TheDef))
+ InAllocClass.set(Reg.EnumValue);
+ }
+
+ // Emit the cost values as a 1D-array after grouping them by their indices,
+ // i.e. the costs for all registers corresponds to index 0, 1, 2, etc.
+ // Size of the emitted array should be NumRegCosts * (Regs.size() + 1).
+ OS << "\nstatic const uint8_t "
+ << "CostPerUseTable[] = { \n";
+ for (unsigned int I = 0; I < NumRegCosts; ++I) {
+ for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)
+ OS << AllRegCostPerUse[J] << ", ";
+ }
+ OS << "};\n\n";
+
+ OS << "\nstatic const bool "
+ << "InAllocatableClassTable[] = { \n";
+ for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {
+ OS << (InAllocClass[I] ? "true" : "false") << ", ";
+ }
+ OS << "};\n\n";
+
+ OS << "\nstatic const TargetRegisterInfoDesc " << TargetName
+ << "RegInfoDesc = { // Extra Descriptors\n";
+ OS << "CostPerUseTable, " << NumRegCosts << ", "
+ << "InAllocatableClassTable";
+ OS << "};\n\n"; // End of register descriptors...
std::string ClassName = Target.getName().str() + "GenRegisterInfo";
@@ -1513,10 +1543,11 @@
EmitRegMappingTables(OS, Regs, true);
- OS << ClassName << "::\n" << ClassName
+ OS << ClassName << "::\n"
+ << ClassName
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,\n"
" unsigned PC, unsigned HwMode)\n"
- << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
+ << " : TargetRegisterInfo(&" << TargetName << "RegInfoDesc"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() << ",\n"
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable,\n"
<< " ";
@@ -1679,7 +1710,10 @@
for (const CodeGenRegister &R : RegBank.getRegisters()) {
OS << "Register " << R.getName() << ":\n";
- OS << "\tCostPerUse: " << R.CostPerUse << '\n';
+ OS << "\tCostPerUse: ";
+ for (const auto &Cost : R.CostPerUse)
+ OS << Cost << " ";
+ OS << '\n';
OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
for (std::pair<CodeGenSubRegIndex*,CodeGenRegister*> P : R.getSubRegs()) {
diff --git a/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp
index 912d43b..7803848 100644
--- a/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/SearchableTableEmitter.cpp
@@ -348,17 +348,13 @@
IndexRowsStorage.push_back(Entry.first);
OS << " { ";
- bool NeedComma = false;
+ ListSeparator LS;
for (const auto &Field : Index.Fields) {
- if (NeedComma)
- OS << ", ";
- NeedComma = true;
-
std::string Repr = primaryRepresentation(
Index.Loc, Field, Entry.first->getValueInit(Field.Name));
if (isa<StringRecTy>(Field.RecType))
Repr = StringRef(Repr).upper();
- OS << Repr;
+ OS << LS << Repr;
}
OS << ", " << Entry.second << " },\n";
}
@@ -414,13 +410,9 @@
}
OS << " };\n";
OS << " KeyType Key = {";
- bool NeedComma = false;
+ ListSeparator LS;
for (const auto &Field : Index.Fields) {
- if (NeedComma)
- OS << ", ";
- NeedComma = true;
-
- OS << Field.Name;
+ OS << LS << Field.Name;
if (isa<StringRecTy>(Field.RecType)) {
OS << ".upper()";
if (IsPrimary)
@@ -482,15 +474,10 @@
raw_ostream &OS) {
OS << "const " << Table.CppTypeName << " *" << Index.Name << "(";
- bool NeedComma = false;
- for (const auto &Field : Index.Fields) {
- if (NeedComma)
- OS << ", ";
- NeedComma = true;
-
- OS << searchableFieldType(Table, Index, Field, TypeInArgument) << " "
+ ListSeparator LS;
+ for (const auto &Field : Index.Fields)
+ OS << LS << searchableFieldType(Table, Index, Field, TypeInArgument) << " "
<< Field.Name;
- }
OS << ")";
}
@@ -518,15 +505,11 @@
Record *Entry = Table.Entries[i];
OS << " { ";
- bool NeedComma = false;
- for (const auto &Field : Table.Fields) {
- if (NeedComma)
- OS << ", ";
- NeedComma = true;
-
- OS << primaryRepresentation(Table.Locs[0], Field,
+ ListSeparator LS;
+ for (const auto &Field : Table.Fields)
+ OS << LS
+ << primaryRepresentation(Table.Locs[0], Field,
Entry->getValueInit(Field.Name));
- }
OS << " }, // " << i << "\n";
}
diff --git a/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp
index 7d2b4b9..c88fe94 100644
--- a/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -179,8 +179,8 @@
static void printFeatureMask(raw_ostream &OS, RecVec &FeatureList,
const DenseMap<Record *, unsigned> &FeatureMap) {
std::array<uint64_t, MAX_SUBTARGET_WORDS> Mask = {};
- for (unsigned j = 0, M = FeatureList.size(); j < M; ++j) {
- unsigned Bit = FeatureMap.lookup(FeatureList[j]);
+ for (const Record *Feature : FeatureList) {
+ unsigned Bit = FeatureMap.lookup(Feature);
Mask[Bit / 64] |= 1ULL << (Bit % 64);
}
@@ -215,10 +215,8 @@
// For each feature
unsigned NumFeatures = 0;
- for (unsigned i = 0, N = FeatureList.size(); i < N; ++i) {
+ for (const Record *Feature : FeatureList) {
// Next feature
- Record *Feature = FeatureList[i];
-
StringRef Name = Feature->getName();
StringRef CommandLineName = Feature->getValueAsString("Name");
StringRef Desc = Feature->getValueAsString("Desc");
@@ -344,13 +342,12 @@
ItinData->getValueAsListOfInts("OperandCycles");
// For each operand cycle
- unsigned N = NOperandCycles = OperandCycleList.size();
- for (unsigned i = 0; i < N;) {
+ NOperandCycles = OperandCycleList.size();
+ ListSeparator LS;
+ for (int OCycle : OperandCycleList) {
// Next operand cycle
- const int OCycle = OperandCycleList[i];
-
+ ItinString += LS;
ItinString += " " + itostr(OCycle);
- if (++i < N) ItinString += ", ";
}
}
@@ -361,13 +358,14 @@
RecVec BypassList = ItinData->getValueAsListOfDefs("Bypasses");
unsigned N = BypassList.size();
unsigned i = 0;
- for (; i < N;) {
+ ListSeparator LS;
+ for (; i < N; ++i) {
+ ItinString += LS;
ItinString += Name + "Bypass::" + BypassList[i]->getName().str();
- if (++i < NOperandCycles) ItinString += ", ";
}
- for (; i < NOperandCycles;) {
+ for (; i < NOperandCycles; ++i) {
+ ItinString += LS;
ItinString += " 0";
- if (++i < NOperandCycles) ItinString += ", ";
}
}
@@ -995,6 +993,7 @@
SCDesc.NumMicroOps = 0;
SCDesc.BeginGroup = false;
SCDesc.EndGroup = false;
+ SCDesc.RetireOOO = false;
SCDesc.WriteProcResIdx = 0;
SCDesc.WriteLatencyIdx = 0;
SCDesc.ReadAdvanceIdx = 0;
@@ -1097,6 +1096,7 @@
SCDesc.EndGroup |= WriteRes->getValueAsBit("EndGroup");
SCDesc.BeginGroup |= WriteRes->getValueAsBit("SingleIssue");
SCDesc.EndGroup |= WriteRes->getValueAsBit("SingleIssue");
+ SCDesc.RetireOOO |= WriteRes->getValueAsBit("RetireOOO");
// Create an entry for each ProcResource listed in WriteRes.
RecVec PRVec = WriteRes->getValueAsListOfDefs("ProcResources");
@@ -1295,7 +1295,7 @@
std::vector<MCSchedClassDesc> &SCTab =
SchedTables.ProcSchedClasses[1 + (PI - SchedModels.procModelBegin())];
- OS << "\n// {Name, NumMicroOps, BeginGroup, EndGroup,"
+ OS << "\n// {Name, NumMicroOps, BeginGroup, EndGroup, RetireOOO,"
<< " WriteProcResIdx,#, WriteLatencyIdx,#, ReadAdvanceIdx,#}\n";
OS << "static const llvm::MCSchedClassDesc "
<< PI->ModelName << "SchedClasses[] = {\n";
@@ -1306,7 +1306,7 @@
&& "invalid class not first");
OS << " {DBGFIELD(\"InvalidSchedClass\") "
<< MCSchedClassDesc::InvalidNumMicroOps
- << ", false, false, 0, 0, 0, 0, 0, 0},\n";
+ << ", false, false, false, 0, 0, 0, 0, 0, 0},\n";
for (unsigned SCIdx = 1, SCEnd = SCTab.size(); SCIdx != SCEnd; ++SCIdx) {
MCSchedClassDesc &MCDesc = SCTab[SCIdx];
@@ -1317,6 +1317,7 @@
OS << MCDesc.NumMicroOps
<< ", " << ( MCDesc.BeginGroup ? "true" : "false" )
<< ", " << ( MCDesc.EndGroup ? "true" : "false" )
+ << ", " << ( MCDesc.RetireOOO ? "true" : "false" )
<< ", " << format("%2d", MCDesc.WriteProcResIdx)
<< ", " << MCDesc.NumWriteProcResEntries
<< ", " << format("%2d", MCDesc.WriteLatencyIdx)
diff --git a/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp b/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
index 105ed82..33a2277 100644
--- a/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/SubtargetFeatureInfo.cpp
@@ -130,14 +130,9 @@
if (IsOr)
OS << "(";
- bool First = true;
+ ListSeparator LS(IsOr ? " || " : " && ");
for (auto *Arg : D->getArgs()) {
- if (!First) {
- if (IsOr)
- OS << " || ";
- else
- OS << " && ";
- }
+ OS << LS;
if (auto *NotArg = dyn_cast<DagInit>(Arg)) {
if (NotArg->getOperator()->getAsString() != "not" ||
NotArg->getNumArgs() != 1)
@@ -149,8 +144,6 @@
!cast<DefInit>(Arg)->getDef()->isSubClassOf("SubtargetFeature"))
PrintFatalError(SFI.TheDef->getLoc(), "Invalid AssemblerCondDag!");
OS << "FB[" << TargetName << "::" << Arg->getAsString() << "]";
-
- First = false;
}
if (IsOr)
diff --git a/src/llvm-project/llvm/utils/TableGen/TableGen.cpp b/src/llvm-project/llvm/utils/TableGen/TableGen.cpp
index 6d851da..24c11c8 100644
--- a/src/llvm-project/llvm/utils/TableGen/TableGen.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/TableGen.cpp
@@ -25,6 +25,7 @@
NullBackend,
DumpJSON,
GenEmitter,
+ GenCodeBeads,
GenRegisterInfo,
GenInstrInfo,
GenInstrDocs,
@@ -56,7 +57,6 @@
GenAutomata,
GenDirectivesEnumDecl,
GenDirectivesEnumImpl,
- GenDirectivesEnumGen,
};
namespace llvm {
@@ -81,6 +81,8 @@
clEnumValN(DumpJSON, "dump-json",
"Dump all records as machine-readable JSON"),
clEnumValN(GenEmitter, "gen-emitter", "Generate machine code emitter"),
+ clEnumValN(GenCodeBeads, "gen-code-beads",
+ "Generate machine code beads"),
clEnumValN(GenRegisterInfo, "gen-register-info",
"Generate registers and register classes info"),
clEnumValN(GenInstrInfo, "gen-instr-info",
@@ -136,9 +138,7 @@
clEnumValN(GenDirectivesEnumDecl, "gen-directive-decl",
"Generate directive related declaration code (header file)"),
clEnumValN(GenDirectivesEnumImpl, "gen-directive-impl",
- "Generate directive related implementation code"),
- clEnumValN(GenDirectivesEnumGen, "gen-directive-gen",
- "Generate directive related implementation code part")));
+ "Generate directive related implementation code")));
cl::OptionCategory PrintEnumsCat("Options for -print-enums");
cl::opt<std::string> Class("class", cl::desc("Print Enum list for this class"),
@@ -161,6 +161,9 @@
case GenEmitter:
EmitCodeEmitter(Records, OS);
break;
+ case GenCodeBeads:
+ EmitCodeBeads(Records, OS);
+ break;
case GenRegisterInfo:
EmitRegisterInfo(Records, OS);
break;
@@ -269,9 +272,6 @@
case GenDirectivesEnumImpl:
EmitDirectivesImpl(Records, OS);
break;
- case GenDirectivesEnumGen:
- EmitDirectivesGen(Records, OS);
- break;
}
return false;
diff --git a/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h b/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h
index 92204f3..71db8dc 100644
--- a/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h
+++ b/src/llvm-project/llvm/utils/TableGen/TableGenBackends.h
@@ -67,6 +67,7 @@
void EmitAsmWriter(RecordKeeper &RK, raw_ostream &OS);
void EmitCallingConv(RecordKeeper &RK, raw_ostream &OS);
void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS);
+void EmitCodeBeads(RecordKeeper &RK, raw_ostream &OS);
void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS);
void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS);
void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS);
@@ -92,7 +93,6 @@
void EmitAutomata(RecordKeeper &RK, raw_ostream &OS);
void EmitDirectivesDecl(RecordKeeper &RK, raw_ostream &OS);
void EmitDirectivesImpl(RecordKeeper &RK, raw_ostream &OS);
-void EmitDirectivesGen(RecordKeeper &RK, raw_ostream &OS);
} // End llvm namespace
diff --git a/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp b/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
index 331664f..89069ec 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/X86DisassemblerTables.cpp
@@ -102,7 +102,8 @@
case IC_64BIT_ADSIZE:
return (noPrefix && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE, noPrefix));
case IC_64BIT_OPSIZE_ADSIZE:
- return false;
+ return (noPrefix &&
+ inheritsFrom(child, IC_64BIT_VEX_OPSIZE_ADSIZE, noPrefix));
case IC_XD:
return inheritsFrom(child, IC_64BIT_XD);
case IC_XS:
@@ -123,10 +124,11 @@
case IC_64BIT_OPSIZE:
return inheritsFrom(child, IC_64BIT_REXW_OPSIZE) ||
(!AdSize64 && inheritsFrom(child, IC_64BIT_OPSIZE_ADSIZE)) ||
- (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE));
+ (!AdSize64 && inheritsFrom(child, IC_64BIT_REXW_ADSIZE)) ||
+ (!AdSize64 && inheritsFrom(child, IC_64BIT_VEX_OPSIZE_ADSIZE));
case IC_64BIT_XD:
- return(inheritsFrom(child, IC_64BIT_REXW_XD) ||
- (!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE)));
+ return (inheritsFrom(child, IC_64BIT_REXW_XD) ||
+ (!AdSize64 && inheritsFrom(child, IC_64BIT_XD_ADSIZE)));
case IC_64BIT_XS:
return(inheritsFrom(child, IC_64BIT_REXW_XS) ||
(!AdSize64 && inheritsFrom(child, IC_64BIT_XS_ADSIZE)));
@@ -156,7 +158,12 @@
case IC_VEX_OPSIZE:
return (VEX_LIG && VEX_WIG && inheritsFrom(child, IC_VEX_L_W_OPSIZE)) ||
(VEX_WIG && inheritsFrom(child, IC_VEX_W_OPSIZE)) ||
- (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE));
+ (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)) ||
+ inheritsFrom(child, IC_64BIT_VEX_OPSIZE);
+ case IC_64BIT_VEX_OPSIZE:
+ return inheritsFrom(child, IC_64BIT_VEX_OPSIZE_ADSIZE);
+ case IC_64BIT_VEX_OPSIZE_ADSIZE:
+ return false;
case IC_VEX_W:
return VEX_LIG && inheritsFrom(child, IC_VEX_L_W);
case IC_VEX_W_XS:
@@ -698,8 +705,8 @@
ModRMDecision.push_back(decision.instructionIDs[index]);
break;
case MODRM_FULL:
- for (unsigned index = 0; index < 256; ++index)
- ModRMDecision.push_back(decision.instructionIDs[index]);
+ for (unsigned short InstructionID : decision.instructionIDs)
+ ModRMDecision.push_back(InstructionID);
break;
}
@@ -710,10 +717,9 @@
ModRMTableNum += ModRMDecision.size();
o1 << "/*Table" << EntryNumber << "*/\n";
i1++;
- for (std::vector<unsigned>::const_iterator I = ModRMDecision.begin(),
- E = ModRMDecision.end(); I != E; ++I) {
- o1.indent(i1 * 2) << format("0x%hx", *I) << ", /*"
- << InstructionSpecifiers[*I].name << "*/\n";
+ for (unsigned I : ModRMDecision) {
+ o1.indent(i1 * 2) << format("0x%hx", I) << ", /*"
+ << InstructionSpecifiers[I].name << "*/\n";
}
i1--;
}
@@ -743,6 +749,7 @@
// We assume that the index can fit into uint16_t.
assert(sEntryNumber < 65536U &&
"Index into ModRMDecision is too large for uint16_t!");
+ (void)sEntryNumber;
++sTableNumber;
}
@@ -823,12 +830,9 @@
for (unsigned Index = 0; Index < NumInstructions; ++Index) {
OperandListTy OperandList;
- for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
- ++OperandIndex) {
- OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[Index]
- .operands[OperandIndex].encoding;
- OperandType Type = (OperandType)InstructionSpecifiers[Index]
- .operands[OperandIndex].type;
+ for (auto Operand : InstructionSpecifiers[Index].operands) {
+ OperandEncoding Encoding = (OperandEncoding)Operand.encoding;
+ OperandType Type = (OperandType)Operand.type;
OperandList.push_back(std::make_pair(Encoding, Type));
}
unsigned &N = OperandSets[OperandList];
@@ -856,12 +860,9 @@
i++;
OperandListTy OperandList;
- for (unsigned OperandIndex = 0; OperandIndex < X86_MAX_OPERANDS;
- ++OperandIndex) {
- OperandEncoding Encoding = (OperandEncoding)InstructionSpecifiers[index]
- .operands[OperandIndex].encoding;
- OperandType Type = (OperandType)InstructionSpecifiers[index]
- .operands[OperandIndex].type;
+ for (auto Operand : InstructionSpecifiers[index].operands) {
+ OperandEncoding Encoding = (OperandEncoding)Operand.encoding;
+ OperandType Type = (OperandType)Operand.type;
OperandList.push_back(std::make_pair(Encoding, Type));
}
o.indent(i * 2) << (OperandSets[OperandList] - 1) << ",\n";
@@ -887,6 +888,9 @@
if ((index & ATTR_EVEX) || (index & ATTR_VEX) || (index & ATTR_VEXL)) {
if (index & ATTR_EVEX)
o << "IC_EVEX";
+ else if ((index & (ATTR_64BIT | ATTR_VEXL | ATTR_REXW | ATTR_OPSIZE)) ==
+ (ATTR_64BIT | ATTR_OPSIZE))
+ o << "IC_64BIT_VEX";
else
o << "IC_VEX";
@@ -898,9 +902,13 @@
if (index & ATTR_REXW)
o << "_W";
- if (index & ATTR_OPSIZE)
+ if (index & ATTR_OPSIZE) {
o << "_OPSIZE";
- else if (index & ATTR_XD)
+ if ((index & (ATTR_64BIT | ATTR_EVEX | ATTR_VEX | ATTR_VEXL |
+ ATTR_REXW | ATTR_ADSIZE)) ==
+ (ATTR_64BIT | ATTR_VEX | ATTR_ADSIZE))
+ o << "_ADSIZE";
+ } else if (index & ATTR_XD)
o << "_XD";
else if (index & ATTR_XS)
o << "_XS";
@@ -914,8 +922,7 @@
if (index & ATTR_EVEXB)
o << "_B";
}
- }
- else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
+ } else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XS))
o << "IC_64BIT_REXW_XS";
else if ((index & ATTR_64BIT) && (index & ATTR_REXW) && (index & ATTR_XD))
o << "IC_64BIT_REXW_XD";
diff --git a/src/llvm-project/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp b/src/llvm-project/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
index 6dc7e31..009dc03 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/X86EVEX2VEXTablesEmitter.cpp
@@ -30,10 +30,13 @@
std::map<uint64_t, std::vector<const CodeGenInstruction *>> VEXInsts;
typedef std::pair<const CodeGenInstruction *, const CodeGenInstruction *> Entry;
+ typedef std::pair<StringRef, StringRef> Predicate;
// Represent both compress tables
std::vector<Entry> EVEX2VEX128;
std::vector<Entry> EVEX2VEX256;
+ // Represent predicates of VEX instructions.
+ std::vector<Predicate> EVEX2VEXPredicates;
public:
X86EVEX2VEXTablesEmitter(RecordKeeper &R) : Records(R), Target(R) {}
@@ -45,6 +48,9 @@
// Prints the given table as a C++ array of type
// X86EvexToVexCompressTableEntry
void printTable(const std::vector<Entry> &Table, raw_ostream &OS);
+ // Prints function which checks target feature specific predicate.
+ void printCheckPredicate(const std::vector<Predicate> &Predicates,
+ raw_ostream &OS);
};
void X86EVEX2VEXTablesEmitter::printTable(const std::vector<Entry> &Table,
@@ -67,6 +73,19 @@
OS << "};\n\n";
}
+void X86EVEX2VEXTablesEmitter::printCheckPredicate(
+ const std::vector<Predicate> &Predicates, raw_ostream &OS) {
+ OS << "static bool CheckVEXInstPredicate"
+ << "(MachineInstr &MI, const X86Subtarget *Subtarget) {\n"
+ << " unsigned Opc = MI.getOpcode();\n"
+ << " switch (Opc) {\n"
+ << " default: return true;\n";
+ for (auto Pair : Predicates)
+ OS << " case X86::" << Pair.first << ": return " << Pair.second << ";\n";
+ OS << " }\n"
+ << "}\n\n";
+}
+
// Return true if the 2 BitsInits are equal
// Calculates the integer value residing BitsInit object
static inline uint64_t getValueFromBitsInit(const BitsInit *B) {
@@ -169,6 +188,18 @@
};
void X86EVEX2VEXTablesEmitter::run(raw_ostream &OS) {
+ auto getPredicates = [&](const CodeGenInstruction *Inst) {
+ std::vector<Record *> PredicatesRecords =
+ Inst->TheDef->getValueAsListOfDefs("Predicates");
+ // Currently we only do AVX related checks and assume each instruction
+ // has one and only one AVX related predicates.
+ for (unsigned i = 0, e = PredicatesRecords.size(); i != e; ++i)
+ if (PredicatesRecords[i]->getName().startswith("HasAVX"))
+ return PredicatesRecords[i]->getValueAsString("CondString");
+ llvm_unreachable(
+ "Instruction with checkPredicate set must have one predicate!");
+ };
+
emitSourceFileHeader("X86 EVEX2VEX tables", OS);
ArrayRef<const CodeGenInstruction *> NumberedInstructions =
@@ -222,11 +253,18 @@
EVEX2VEX256.push_back(std::make_pair(EVEXInst, VEXInst)); // {0,1}
else
EVEX2VEX128.push_back(std::make_pair(EVEXInst, VEXInst)); // {0,0}
+
+ // Adding predicate check to EVEX2VEXPredicates table when needed.
+ if (VEXInst->TheDef->getValueAsBit("checkVEXPredicate"))
+ EVEX2VEXPredicates.push_back(
+ std::make_pair(EVEXInst->TheDef->getName(), getPredicates(VEXInst)));
}
// Print both tables
printTable(EVEX2VEX128, OS);
printTable(EVEX2VEX256, OS);
+ // Print CheckVEXInstPredicate function.
+ printCheckPredicate(EVEX2VEXPredicates, OS);
}
}
diff --git a/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp b/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
index e4b7c05..c2ca379 100644
--- a/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
+++ b/src/llvm-project/llvm/utils/TableGen/X86RecognizableInstr.cpp
@@ -125,13 +125,7 @@
return;
}
- // Special case since there is no attribute class for 64-bit and VEX
- if (Name == "VMASKMOVDQU64") {
- ShouldBeEmitted = false;
- return;
- }
-
- ShouldBeEmitted = true;
+ ShouldBeEmitted = true;
}
void RecognizableInstr::processInstr(DisassemblerTables &tables,
@@ -267,6 +261,11 @@
insnContext = IC_VEX_L_OPSIZE;
else if (OpPrefix == X86Local::PD && HasVEX_W)
insnContext = IC_VEX_W_OPSIZE;
+ else if (OpPrefix == X86Local::PD && Is64Bit &&
+ AdSize == X86Local::AdSize32)
+ insnContext = IC_64BIT_VEX_OPSIZE_ADSIZE;
+ else if (OpPrefix == X86Local::PD && Is64Bit)
+ insnContext = IC_64BIT_VEX_OPSIZE;
else if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_OPSIZE;
else if (HasVEX_LPrefix && OpPrefix == X86Local::XS)
diff --git a/src/llvm-project/llvm/utils/UpdateTestChecks/asm.py b/src/llvm-project/llvm/utils/UpdateTestChecks/asm.py
index 6390ace..2a18899 100644
--- a/src/llvm-project/llvm/utils/UpdateTestChecks/asm.py
+++ b/src/llvm-project/llvm/utils/UpdateTestChecks/asm.py
@@ -51,6 +51,12 @@
r'.Lfunc_end[0-9]+:\n',
flags=(re.M | re.S))
+ASM_FUNCTION_M68K_RE = re.compile(
+ r'^_?(?P<func>[^:]+):[ \t]*;[ \t]*@"?(?P=func)"?\n'
+ r'(?P<body>.*?)\s*' # (body of the function)
+ r'.Lfunc_end[0-9]+:\n',
+ flags=(re.M | re.S))
+
ASM_FUNCTION_MIPS_RE = re.compile(
r'^_?(?P<func>[^:]+):[ \t]*#+[ \t]*@"?(?P=func)"?\n[^:]*?' # f: (name of func)
r'(?:^[ \t]+\.(frame|f?mask|set).*?\n)+' # Mips+LLVM standard asm prologue
@@ -135,11 +141,21 @@
r'[ \t]*\.cfi_endproc\n',
flags=(re.M | re.S))
+ASM_FUNCTION_THUMBS_DARWIN_RE = re.compile(
+ r'^_(?P<func>[^:]+):\n'
+ r'(?P<body>.*?)\n'
+ r'[ \t]*\.data_region\n',
+ flags=(re.M | re.S))
+
+ASM_FUNCTION_THUMB_DARWIN_RE = re.compile(
+ r'^_(?P<func>[^:]+):\n'
+ r'(?P<body>.*?)\n'
+ r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
+ flags=(re.M | re.S))
+
ASM_FUNCTION_ARM_IOS_RE = re.compile(
- r'^_(?P<func>[^:]+):[ \t]*\n'
- r'^Lfunc_begin(?P<id>[0-9][1-9]*):\n'
+ r'^_(?P<func>[^:]+):\n'
r'(?P<body>.*?)'
- r'^Lfunc_end(?P=id):\n'
r'^[ \t]*@[ \t]--[ \t]End[ \t]function',
flags=(re.M | re.S))
@@ -165,7 +181,7 @@
flags=re.M))
SCRUB_X86_SP_RE = re.compile(r'\d+\(%(esp|rsp)\)')
SCRUB_X86_RIP_RE = re.compile(r'[.\w]+\(%rip\)')
-SCRUB_X86_LCP_RE = re.compile(r'\.LCPI[0-9]+_[0-9]+')
+SCRUB_X86_LCP_RE = re.compile(r'\.?LCPI[0-9]+_[0-9]+')
SCRUB_X86_RET_RE = re.compile(r'ret[l|q]')
def scrub_asm_x86(asm, args):
@@ -191,7 +207,7 @@
# Generically match a RIP-relative memory operand.
asm = SCRUB_X86_RIP_RE.sub(r'{{.*}}(%rip)', asm)
# Generically match a LCP symbol.
- asm = SCRUB_X86_LCP_RE.sub(r'{{\.LCPI.*}}', asm)
+ asm = SCRUB_X86_LCP_RE.sub(r'{{\.?LCPI[0-9]+_[0-9]+}}', asm)
if getattr(args, 'extra_scrub', False):
# Avoid generating different checks for 32- and 64-bit because of 'retl' vs 'retq'.
asm = SCRUB_X86_RET_RE.sub(r'ret{{[l|q]}}', asm)
@@ -247,6 +263,16 @@
asm = common.SCRUB_TAILING_COMMENT_TOKEN_RE.sub(r'', asm)
return asm
+def scrub_asm_m68k(asm, args):
+ # Scrub runs of whitespace out of the assembly, but leave the leading
+ # whitespace in place.
+ asm = common.SCRUB_WHITESPACE_RE.sub(r' ', asm)
+ # Expand the tabs used for indentation.
+ asm = string.expandtabs(asm, 2)
+ # Strip trailing whitespace.
+ asm = common.SCRUB_TRAILING_WHITESPACE_RE.sub(r'', asm)
+ return asm
+
def scrub_asm_mips(asm, args):
# Scrub runs of whitespace out of the assembly, but leave the leading
# whitespace in place.
@@ -346,8 +372,10 @@
'i686': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'x86': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
'i386': (scrub_asm_x86, ASM_FUNCTION_X86_RE),
+ 'arm64_32-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
'aarch64': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_RE),
'aarch64-apple-darwin': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
+ 'aarch64-apple-ios': (scrub_asm_arm_eabi, ASM_FUNCTION_AARCH64_DARWIN_RE),
'hexagon': (scrub_asm_hexagon, ASM_FUNCTION_HEXAGON_RE),
'r600': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
'amdgcn': (scrub_asm_amdgpu, ASM_FUNCTION_AMDGPU_RE),
@@ -360,7 +388,10 @@
'thumb': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_RE),
'thumb-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
'thumbv5-macho': (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_MACHO_RE),
+ 'thumbv7s-apple-darwin' : (scrub_asm_arm_eabi, ASM_FUNCTION_THUMBS_DARWIN_RE),
+ 'thumbv7-apple-darwin' : (scrub_asm_arm_eabi, ASM_FUNCTION_THUMB_DARWIN_RE),
'thumbv7-apple-ios' : (scrub_asm_arm_eabi, ASM_FUNCTION_ARM_IOS_RE),
+ 'm68k': (scrub_asm_m68k, ASM_FUNCTION_M68K_RE),
'mips': (scrub_asm_mips, ASM_FUNCTION_MIPS_RE),
'msp430': (scrub_asm_msp430, ASM_FUNCTION_MSP430_RE),
'avr': (scrub_asm_avr, ASM_FUNCTION_AVR_RE),
diff --git a/src/llvm-project/llvm/utils/UpdateTestChecks/common.py b/src/llvm-project/llvm/utils/UpdateTestChecks/common.py
index 4befaec..aa9b845 100644
--- a/src/llvm-project/llvm/utils/UpdateTestChecks/common.py
+++ b/src/llvm-project/llvm/utils/UpdateTestChecks/common.py
@@ -2,6 +2,7 @@
import copy
import glob
+import os
import re
import subprocess
import sys
@@ -16,6 +17,7 @@
_verbose = False
+_prefix_filecheck_ir_name = ''
def parse_commandline_args(parser):
parser.add_argument('--include-generated-funcs', action='store_true',
@@ -30,9 +32,19 @@
help='Activate CHECK line generation from this point forward')
parser.add_argument('--disable', action='store_false', dest='enabled',
help='Deactivate CHECK line generation from this point forward')
+ parser.add_argument('--replace-value-regex', nargs='+', default=[],
+ help='List of regular expressions to replace matching value names')
+ parser.add_argument('--prefix-filecheck-ir-name', default='',
+ help='Add a prefix to FileCheck IR value names to avoid conflicts with scripted names')
+ parser.add_argument('--global-value-regex', nargs='+', default=[],
+ help='List of regular expressions that a global value declaration must match to generate a check (has no effect if checking globals is not enabled)')
+ parser.add_argument('--global-hex-value-regex', nargs='+', default=[],
+ help='List of regular expressions such that, for matching global value declarations, literal integer values should be encoded in hex in the associated FileCheck directives')
args = parser.parse_args()
- global _verbose
+ global _verbose, _global_value_regex, _global_hex_value_regex
_verbose = args.verbose
+ _global_value_regex = args.global_value_regex
+ _global_hex_value_regex = args.global_hex_value_regex
return args
@@ -51,6 +63,9 @@
self.argparse_callback = argparse_callback
self.path = test
self.args = args
+ if args.prefix_filecheck_ir_name:
+ global _prefix_filecheck_ir_name
+ _prefix_filecheck_ir_name = args.prefix_filecheck_ir_name
self.argv = argv
self.input_lines = input_lines
self.run_lines = find_run_lines(test, self.input_lines)
@@ -112,9 +127,12 @@
comment_prefix, argparse_callback)
-def should_add_line_to_output(input_line, prefix_set):
+def should_add_line_to_output(input_line, prefix_set, skip_global_checks = False, comment_marker = ';'):
# Skip any blank comment lines in the IR.
- if input_line.strip() == ';':
+ if not skip_global_checks and input_line.strip() == comment_marker:
+ return False
+ # Skip a special double comment line we use as a separator.
+ if input_line.strip() == comment_marker + SEPARATOR:
return False
# Skip any blank lines in the IR.
#if input_line.strip() == '':
@@ -122,16 +140,31 @@
# And skip any CHECK lines. We're building our own.
m = CHECK_RE.match(input_line)
if m and m.group(1) in prefix_set:
+ if skip_global_checks:
+ global_ir_value_re = re.compile('\[\[', flags=(re.M))
+ return not global_ir_value_re.search(input_line)
return False
return True
# Invoke the tool that is being tested.
-def invoke_tool(exe, cmd_args, ir):
+def invoke_tool(exe, cmd_args, ir, preprocess_cmd=None, verbose=False):
with open(ir) as ir_file:
# TODO Remove the str form which is used by update_test_checks.py and
# update_llc_test_checks.py
# The safer list form is used by update_cc_test_checks.py
+ if preprocess_cmd:
+ # Allow pre-processing the IR file (e.g. using sed):
+ assert isinstance(preprocess_cmd, str) # TODO: use a list instead of using shell
+ preprocess_cmd = preprocess_cmd.replace('%s', ir).strip()
+ if verbose:
+ print('Pre-processing input file: ', ir, " with command '",
+ preprocess_cmd, "'", sep="", file=sys.stderr)
+ # Python 2.7 doesn't have subprocess.DEVNULL:
+ with open(os.devnull, 'w') as devnull:
+ pp = subprocess.Popen(preprocess_cmd, shell=True, stdin=devnull,
+ stdout=subprocess.PIPE)
+ ir_file = pp.stdout
if isinstance(cmd_args, list):
stdout = subprocess.check_output([exe] + cmd_args, stdin=ir_file)
else:
@@ -177,6 +210,7 @@
r'# =>This Inner Loop Header:.*|# in Loop:.*', flags=re.M)
SCRUB_TAILING_COMMENT_TOKEN_RE = re.compile(r'(?<=\S)+[ \t]*#$', flags=re.M)
+SEPARATOR = '.'
def error(msg, test_file=None):
if test_file:
@@ -237,10 +271,14 @@
def is_same_except_arg_names(self, extrascrub, args_and_sig, attrs):
arg_names = set()
def drop_arg_names(match):
- arg_names.add(match.group(3))
- return match.group(1) + match.group(match.lastindex)
+ arg_names.add(match.group(variable_group_in_ir_value_match))
+ if match.group(attribute_group_in_ir_value_match):
+ attr = match.group(attribute_group_in_ir_value_match)
+ else:
+ attr = ''
+ return match.group(1) + attr + match.group(match.lastindex)
def repl_arg_names(match):
- if match.group(3) is not None and match.group(3) in arg_names:
+ if match.group(variable_group_in_ir_value_match) is not None and match.group(variable_group_in_ir_value_match) in arg_names:
return match.group(1) + match.group(match.lastindex)
return match.group(1) + match.group(2) + match.group(match.lastindex)
if self.attrs != attrs:
@@ -259,27 +297,36 @@
return self.scrub
class FunctionTestBuilder:
- def __init__(self, run_list, flags, scrubber_args):
+ def __init__(self, run_list, flags, scrubber_args, path):
self._verbose = flags.verbose
self._record_args = flags.function_signature
self._check_attributes = flags.check_attributes
self._scrubber_args = scrubber_args
+ self._path = path
+ # Strip double-quotes if input was read by UTC_ARGS
+ self._replace_value_regex = list(map(lambda x: x.strip('"'), flags.replace_value_regex))
self._func_dict = {}
self._func_order = {}
+ self._global_var_dict = {}
for tuple in run_list:
for prefix in tuple[0]:
self._func_dict.update({prefix:dict()})
self._func_order.update({prefix: []})
+ self._global_var_dict.update({prefix:dict()})
def finish_and_get_func_dict(self):
for prefix in self._get_failed_prefixes():
- warn('Prefix %s had conflicting output from different RUN lines for all functions' % (prefix,))
+ warn('Prefix %s had conflicting output from different RUN lines for all functions in test %s' % (prefix,self._path,))
return self._func_dict
def func_order(self):
return self._func_order
-
+
+ def global_var_dict(self):
+ return self._global_var_dict
+
def process_run_line(self, function_re, scrubber, raw_tool_output, prefixes):
+ build_global_values_dictionary(self._global_var_dict, raw_tool_output, prefixes)
for m in function_re.finditer(raw_tool_output):
if not m:
continue
@@ -310,6 +357,31 @@
for l in scrubbed_body.splitlines():
print(' ' + l, file=sys.stderr)
for prefix in prefixes:
+ # Replace function names matching the regex.
+ for regex in self._replace_value_regex:
+ # Pattern that matches capture groups in the regex in leftmost order.
+ group_regex = re.compile('\(.*?\)')
+ # Replace function name with regex.
+ match = re.match(regex, func)
+ if match:
+ func_repl = regex
+ # Replace any capture groups with their matched strings.
+ for g in match.groups():
+ func_repl = group_regex.sub(re.escape(g), func_repl, count=1)
+ func = re.sub(func_repl, '{{' + func_repl + '}}', func)
+
+ # Replace all calls to regex matching functions.
+ matches = re.finditer(regex, scrubbed_body)
+ for match in matches:
+ func_repl = regex
+ # Replace any capture groups with their matched strings.
+ for g in match.groups():
+ func_repl = group_regex.sub(re.escape(g), func_repl, count=1)
+ # Substitute function call names that match the regex with the same
+ # capture groups set.
+ scrubbed_body = re.sub(func_repl, '{{' + func_repl + '}}',
+ scrubbed_body)
+
if func in self._func_dict[prefix]:
if (self._func_dict[prefix][func] is None or
str(self._func_dict[prefix][func]) != scrubbed_body or
@@ -341,7 +413,7 @@
# all instances of the prefix. Effectively, this prefix is unused and should
# be removed.
for prefix in self._func_dict:
- if (self._func_dict[prefix] and
+ if (self._func_dict[prefix] and
(not [fct for fct in self._func_dict[prefix]
if self._func_dict[prefix][fct] is not None])):
yield prefix
@@ -354,34 +426,60 @@
# TODO: We should also derive check lines for global, debug, loop declarations, etc..
class NamelessValue:
- def __init__(self, check_prefix, ir_prefix, ir_regexp):
+ def __init__(self, check_prefix, check_key, ir_prefix, global_ir_prefix, global_ir_prefix_regexp,
+ ir_regexp, global_ir_rhs_regexp, is_before_functions):
self.check_prefix = check_prefix
+ self.check_key = check_key
self.ir_prefix = ir_prefix
+ self.global_ir_prefix = global_ir_prefix
+ self.global_ir_prefix_regexp = global_ir_prefix_regexp
self.ir_regexp = ir_regexp
+ self.global_ir_rhs_regexp = global_ir_rhs_regexp
+ self.is_before_functions = is_before_functions
# Description of the different "unnamed" values we match in the IR, e.g.,
# (local) ssa values, (debug) metadata, etc.
nameless_values = [
- NamelessValue(r'TMP', r'%', r'[\w.-]+?'),
- NamelessValue(r'GLOB', r'@', r'[0-9]+?'),
- NamelessValue(r'ATTR', r'#', r'[0-9]+?'),
- NamelessValue(r'DBG', r'!dbg !', r'[0-9]+?'),
- NamelessValue(r'TBAA', r'!tbaa !', r'[0-9]+?'),
- NamelessValue(r'RNG', r'!range !', r'[0-9]+?'),
- NamelessValue(r'LOOP', r'!llvm.loop !', r'[0-9]+?'),
- NamelessValue(r'META', r'metadata !', r'[0-9]+?'),
+ NamelessValue(r'TMP' , '%' , r'%' , None , None , r'[\w$.-]+?' , None , False) ,
+ NamelessValue(r'ATTR' , '#' , r'#' , None , None , r'[0-9]+' , None , False) ,
+ NamelessValue(r'ATTR' , '#' , None , r'attributes #' , r'[0-9]+' , None , r'{[^}]*}' , False) ,
+ NamelessValue(r'GLOB' , '@' , r'@' , None , None , r'[0-9]+' , None , False) ,
+ NamelessValue(r'GLOB' , '@' , None , r'@' , r'[a-zA-Z0-9_$"\\.-]+' , None , r'.+' , True) ,
+ NamelessValue(r'DBG' , '!' , r'!dbg ' , None , None , r'![0-9]+' , None , False) ,
+ NamelessValue(r'PROF' , '!' , r'!prof ' , None , None , r'![0-9]+' , None , False) ,
+ NamelessValue(r'TBAA' , '!' , r'!tbaa ' , None , None , r'![0-9]+' , None , False) ,
+ NamelessValue(r'RNG' , '!' , r'!range ' , None , None , r'![0-9]+' , None , False) ,
+ NamelessValue(r'LOOP' , '!' , r'!llvm.loop ' , None , None , r'![0-9]+' , None , False) ,
+ NamelessValue(r'META' , '!' , r'metadata ' , None , None , r'![0-9]+' , None , False) ,
+ NamelessValue(r'META' , '!' , None , r'' , r'![0-9]+' , None , r'(?:distinct |)!.*' , False) ,
]
+def createOrRegexp(old, new):
+ if not old:
+ return new
+ if not new:
+ return old
+ return old + '|' + new
+
+def createPrefixMatch(prefix_str, prefix_re):
+ if prefix_str is None or prefix_re is None:
+ return ''
+ return '(?:' + prefix_str + '(' + prefix_re + '))'
+
# Build the regexp that matches an "IR value". This can be a local variable,
# argument, global, or metadata, anything that is "named". It is important that
# the PREFIX and SUFFIX below only contain a single group, if that changes
# other locations will need adjustment as well.
-IR_VALUE_REGEXP_PREFIX = r'(\s+)'
+IR_VALUE_REGEXP_PREFIX = r'(\s*)'
IR_VALUE_REGEXP_STRING = r''
for nameless_value in nameless_values:
- if IR_VALUE_REGEXP_STRING:
- IR_VALUE_REGEXP_STRING += '|'
- IR_VALUE_REGEXP_STRING += nameless_value.ir_prefix + r'(' + nameless_value.ir_regexp + r')'
+ lcl_match = createPrefixMatch(nameless_value.ir_prefix, nameless_value.ir_regexp)
+ glb_match = createPrefixMatch(nameless_value.global_ir_prefix, nameless_value.global_ir_prefix_regexp)
+ assert((lcl_match or glb_match) and not (lcl_match and glb_match))
+ if lcl_match:
+ IR_VALUE_REGEXP_STRING = createOrRegexp(IR_VALUE_REGEXP_STRING, lcl_match)
+ elif glb_match:
+ IR_VALUE_REGEXP_STRING = createOrRegexp(IR_VALUE_REGEXP_STRING, '^' + glb_match)
IR_VALUE_REGEXP_SUFFIX = r'([,\s\(\)]|\Z)'
IR_VALUE_RE = re.compile(IR_VALUE_REGEXP_PREFIX + r'(' + IR_VALUE_REGEXP_STRING + r')' + IR_VALUE_REGEXP_SUFFIX)
@@ -389,6 +487,10 @@
# IR_VALUE_REGEXP_STRING is one group (=2), and then the nameless values start.
first_nameless_group_in_ir_value_match = 3
+# constants for the group id of special matches
+variable_group_in_ir_value_match = 3
+attribute_group_in_ir_value_match = 4
+
# Check a match for IR_VALUE_RE and inspect it to determine if it was a local
# value, %..., global @..., debug number !dbg !..., etc. See the PREFIXES above.
def get_idx_from_ir_value_match(match):
@@ -396,7 +498,7 @@
if match.group(i) is not None:
return i - first_nameless_group_in_ir_value_match
error("Unable to identify the kind of IR value from the match!")
- return 0;
+ return 0
# See get_idx_from_ir_value_match
def get_name_from_ir_value_match(match):
@@ -407,30 +509,71 @@
def get_nameless_check_prefix_from_ir_value_match(match):
return nameless_values[get_idx_from_ir_value_match(match)].check_prefix
-# Return the IR prefix we use for this kind or IR value, e.g., % for locals,
+# Return the IR prefix and check prefix we use for this kind or IR value, e.g., (%, TMP) for locals,
# see also get_idx_from_ir_value_match
def get_ir_prefix_from_ir_value_match(match):
- return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix
+ idx = get_idx_from_ir_value_match(match)
+ if nameless_values[idx].ir_prefix and match.group(0).strip().startswith(nameless_values[idx].ir_prefix):
+ return nameless_values[idx].ir_prefix, nameless_values[idx].check_prefix
+ return nameless_values[idx].global_ir_prefix, nameless_values[idx].check_prefix
-# Return true if this kind or IR value is "local", basically if it matches '%{{.*}}'.
-def is_local_ir_value_match(match):
+def get_check_key_from_ir_value_match(match):
+ idx = get_idx_from_ir_value_match(match)
+ return nameless_values[idx].check_key
+
+# Return the IR regexp we use for this kind or IR value, e.g., [\w.-]+? for locals,
+# see also get_idx_from_ir_value_match
+def get_ir_prefix_from_ir_value_re_match(match):
+ # for backwards compatibility we check locals with '.*'
+ if is_local_def_ir_value_match(match):
+ return '.*'
+ idx = get_idx_from_ir_value_match(match)
+ if nameless_values[idx].ir_prefix and match.group(0).strip().startswith(nameless_values[idx].ir_prefix):
+ return nameless_values[idx].ir_regexp
+ return nameless_values[idx].global_ir_prefix_regexp
+
+# Return true if this kind of IR value is "local", basically if it matches '%{{.*}}'.
+def is_local_def_ir_value_match(match):
return nameless_values[get_idx_from_ir_value_match(match)].ir_prefix == '%'
+# Return true if this kind of IR value is "global", basically if it matches '#{{.*}}'.
+def is_global_scope_ir_value_match(match):
+ return nameless_values[get_idx_from_ir_value_match(match)].global_ir_prefix is not None
+
+# Return true if var clashes with the scripted FileCheck check_prefix.
+def may_clash_with_default_check_prefix_name(check_prefix, var):
+ return check_prefix and re.match(r'^' + check_prefix + r'[0-9]+?$', var, re.IGNORECASE)
+
# Create a FileCheck variable name based on an IR name.
-def get_value_name(var, match):
+def get_value_name(var, check_prefix):
+ var = var.replace('!', '')
+ # This is a nameless value, prepend check_prefix.
if var.isdigit():
- var = get_nameless_check_prefix_from_ir_value_match(match) + var
+ var = check_prefix + var
+ else:
+ # This is a named value that clashes with the check_prefix, prepend with _prefix_filecheck_ir_name,
+ # if it has been defined.
+ if may_clash_with_default_check_prefix_name(check_prefix, var) and _prefix_filecheck_ir_name:
+ var = _prefix_filecheck_ir_name + var
var = var.replace('.', '_')
var = var.replace('-', '_')
return var.upper()
# Create a FileCheck variable from regex.
def get_value_definition(var, match):
- return '[[' + get_value_name(var, match) + ':' + get_ir_prefix_from_ir_value_match(match) + '.*]]'
+ # for backwards compatibility we check locals with '.*'
+ if is_local_def_ir_value_match(match):
+ return '[[' + get_value_name(var, get_nameless_check_prefix_from_ir_value_match(match)) + ':' + \
+ get_ir_prefix_from_ir_value_match(match)[0] + get_ir_prefix_from_ir_value_re_match(match) + ']]'
+ prefix = get_ir_prefix_from_ir_value_match(match)[0]
+ return prefix + '[[' + get_value_name(var, get_nameless_check_prefix_from_ir_value_match(match)) + ':' + get_ir_prefix_from_ir_value_re_match(match) + ']]'
# Use a FileCheck variable.
-def get_value_use(var, match):
- return '[[' + get_value_name(var, match) + ']]'
+def get_value_use(var, match, check_prefix):
+ if is_local_def_ir_value_match(match):
+ return '[[' + get_value_name(var, check_prefix) + ']]'
+ prefix = get_ir_prefix_from_ir_value_match(match)[0]
+ return prefix + '[[' + get_value_name(var, check_prefix) + ']]'
# Replace IR value defs and uses with FileCheck variables.
def generalize_check_lines(lines, is_analyze, vars_seen, global_vars_seen):
@@ -438,18 +581,23 @@
# a line. We transform variables we haven't seen
# into defs, and variables we have seen into uses.
def transform_line_vars(match):
- pre = get_ir_prefix_from_ir_value_match(match)
+ pre, check = get_ir_prefix_from_ir_value_match(match)
var = get_name_from_ir_value_match(match)
for nameless_value in nameless_values:
- if re.match(r'^' + nameless_value.check_prefix + r'[0-9]+?$', var, re.IGNORECASE):
- warn("Change IR value name '%s' to prevent possible conflict with scripted FileCheck name." % (var,))
- if (pre, var) in vars_seen or (pre, var) in global_vars_seen:
- rv = get_value_use(var, match)
+ if may_clash_with_default_check_prefix_name(nameless_value.check_prefix, var):
+ warn("Change IR value name '%s' or use -prefix-ir-filecheck-name to prevent possible conflict"
+ " with scripted FileCheck name." % (var,))
+ key = (var, get_check_key_from_ir_value_match(match))
+ is_local_def = is_local_def_ir_value_match(match)
+ if is_local_def and key in vars_seen:
+ rv = get_value_use(var, match, get_nameless_check_prefix_from_ir_value_match(match))
+ elif not is_local_def and key in global_vars_seen:
+ rv = get_value_use(var, match, global_vars_seen[key])
else:
- if is_local_ir_value_match(match):
- vars_seen.add((pre, var))
+ if is_local_def:
+ vars_seen.add(key)
else:
- global_vars_seen.add((pre, var))
+ global_vars_seen[key] = get_nameless_check_prefix_from_ir_value_match(match)
rv = get_value_definition(var, match)
# re.sub replaces the entire regex match
# with whatever you return, so we have
@@ -462,6 +610,12 @@
for i, line in enumerate(lines):
# An IR variable named '%.' matches the FileCheck regex string.
line = line.replace('%.', '%dot')
+ for regex in _global_hex_value_regex:
+ if re.match('^@' + regex + ' = ', line):
+ line = re.sub(r'\bi([0-9]+) ([0-9]+)',
+ lambda m : 'i' + m.group(1) + ' [[#' + hex(int(m.group(2))) + ']]',
+ line)
+ break
# Ignore any comments, since the check lines will too.
scrubbed_line = SCRUB_IR_COMMENT_RE.sub(r'', line)
lines[i] = scrubbed_line
@@ -490,8 +644,13 @@
# prefix_exclusions is constructed, we can now emit the output
for p in prefix_list:
+ global_vars_seen = {}
checkprefixes = p[0]
for checkprefix in checkprefixes:
+ if checkprefix in global_vars_seen_dict:
+ global_vars_seen.update(global_vars_seen_dict[checkprefix])
+ else:
+ global_vars_seen_dict[checkprefix] = {}
if checkprefix in printed_prefixes:
break
@@ -510,8 +669,9 @@
output_lines.append(comment_marker)
if checkprefix not in global_vars_seen_dict:
- global_vars_seen_dict[checkprefix] = set()
- global_vars_seen = global_vars_seen_dict[checkprefix]
+ global_vars_seen_dict[checkprefix] = {}
+
+ global_vars_seen_before = [key for key in global_vars_seen.keys()]
vars_seen = set()
printed_prefixes.append(checkprefix)
@@ -574,6 +734,11 @@
# Add space between different check prefixes and also before the first
# line of code in the test function.
output_lines.append(comment_marker)
+
+ # Remembe new global variables we have not seen before
+ for key in global_vars_seen:
+ if key not in global_vars_seen_before:
+ global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
break
def add_ir_checks(output_lines, comment_marker, prefix_list, func_dict,
@@ -590,6 +755,91 @@
add_checks(output_lines, comment_marker, prefix_list, func_dict, func_name,
check_label_format, False, True, global_vars_seen_dict)
+def build_global_values_dictionary(glob_val_dict, raw_tool_output, prefixes):
+ for nameless_value in nameless_values:
+ if nameless_value.global_ir_prefix is None:
+ continue
+
+ lhs_re_str = nameless_value.global_ir_prefix + nameless_value.global_ir_prefix_regexp
+ rhs_re_str = nameless_value.global_ir_rhs_regexp
+
+ global_ir_value_re_str = r'^' + lhs_re_str + r'\s=\s' + rhs_re_str + r'$'
+ global_ir_value_re = re.compile(global_ir_value_re_str, flags=(re.M))
+ lines = []
+ for m in global_ir_value_re.finditer(raw_tool_output):
+ lines.append(m.group(0))
+
+ for prefix in prefixes:
+ if glob_val_dict[prefix] is None:
+ continue
+ if nameless_value.check_prefix in glob_val_dict[prefix]:
+ if lines == glob_val_dict[prefix][nameless_value.check_prefix]:
+ continue
+ if prefix == prefixes[-1]:
+ warn('Found conflicting asm under the same prefix: %r!' % (prefix,))
+ else:
+ glob_val_dict[prefix][nameless_value.check_prefix] = None
+ continue
+ glob_val_dict[prefix][nameless_value.check_prefix] = lines
+
+def add_global_checks(glob_val_dict, comment_marker, prefix_list, output_lines, global_vars_seen_dict, is_analyze, is_before_functions):
+ printed_prefixes = set()
+ for nameless_value in nameless_values:
+ if nameless_value.global_ir_prefix is None:
+ continue
+ if nameless_value.is_before_functions != is_before_functions:
+ continue
+ for p in prefix_list:
+ global_vars_seen = {}
+ checkprefixes = p[0]
+ if checkprefixes is None:
+ continue
+ for checkprefix in checkprefixes:
+ if checkprefix in global_vars_seen_dict:
+ global_vars_seen.update(global_vars_seen_dict[checkprefix])
+ else:
+ global_vars_seen_dict[checkprefix] = {}
+ if (checkprefix, nameless_value.check_prefix) in printed_prefixes:
+ break
+ if not glob_val_dict[checkprefix]:
+ continue
+ if nameless_value.check_prefix not in glob_val_dict[checkprefix]:
+ continue
+ if not glob_val_dict[checkprefix][nameless_value.check_prefix]:
+ continue
+
+ check_lines = []
+ global_vars_seen_before = [key for key in global_vars_seen.keys()]
+ for line in glob_val_dict[checkprefix][nameless_value.check_prefix]:
+ if _global_value_regex:
+ matched = False
+ for regex in _global_value_regex:
+ if re.match('^@' + regex + ' = ', line):
+ matched = True
+ break
+ if not matched:
+ continue
+ tmp = generalize_check_lines([line], is_analyze, set(), global_vars_seen)
+ check_line = '%s %s: %s' % (comment_marker, checkprefix, tmp[0])
+ check_lines.append(check_line)
+ if not check_lines:
+ continue
+
+ output_lines.append(comment_marker + SEPARATOR)
+ for check_line in check_lines:
+ output_lines.append(check_line)
+
+ printed_prefixes.add((checkprefix, nameless_value.check_prefix))
+
+ # Remembe new global variables we have not seen before
+ for key in global_vars_seen:
+ if key not in global_vars_seen_before:
+ global_vars_seen_dict[checkprefix][key] = global_vars_seen[key]
+ break
+
+ if printed_prefixes:
+ output_lines.append(comment_marker + SEPARATOR)
+
def check_prefix(prefix):
if not PREFIX_RE.match(prefix):
@@ -633,6 +883,8 @@
continue # Don't add default values
autogenerated_note_args += action.option_strings[0] + ' '
if action.const is None: # action takes a parameter
+ if action.nargs == '+':
+ value = ' '.join(map(lambda v: '"' + v.strip('"') + '"', value))
autogenerated_note_args += '%s ' % value
if autogenerated_note_args:
autogenerated_note_args = ' %s %s' % (UTC_ARGS_KEY, autogenerated_note_args[:-1])
@@ -642,8 +894,9 @@
def check_for_command(line, parser, args, argv, argparse_callback):
cmd_m = UTC_ARGS_CMD.match(line)
if cmd_m:
- cmd = cmd_m.group('cmd').strip().split(' ')
- argv = argv + cmd
+ for option in cmd_m.group('cmd').strip().split(' '):
+ if option:
+ argv.append(option)
args = parser.parse_args(filter(lambda arg: arg not in args.tests, argv))
if argparse_callback is not None:
argparse_callback(args)
@@ -678,6 +931,8 @@
args = input_line_info.args
if line.strip() == comment_string:
continue
+ if line.strip() == comment_string + SEPARATOR:
+ continue
if line.lstrip().startswith(comment_string):
m = CHECK_RE.match(line)
if m and m.group(1) in prefix_set:
diff --git a/src/llvm-project/llvm/utils/abtest.py b/src/llvm-project/llvm/utils/abtest.py
index 69a86f6..4ca3ca4 100755
--- a/src/llvm-project/llvm/utils/abtest.py
+++ b/src/llvm-project/llvm/utils/abtest.py
@@ -7,6 +7,10 @@
# list of files which should be linked together and result tested. "link_test"
# should returns with exitcode 0 if the linking and testing succeeded.
#
+# If a response file is provided, only the object files that are listed in the
+# file are inspected. In addition, the "link_test" is called with a temporary
+# response file representing one iteration of bisection.
+#
# abtest.py operates by taking all files from the "before" directory and
# in each step replacing one of them with a file from the "bad" directory.
#
@@ -41,9 +45,10 @@
import os
import subprocess
import sys
+import tempfile
-
-LINKTEST = "./link_test"
+# Specify LINKTEST via `--test`. Default value is './link_test'.
+LINKTEST = ""
ESCAPE = "\033[%sm"
BOLD = ESCAPE % "1"
RED = ESCAPE % "31"
@@ -234,22 +239,42 @@
return True
-def prepare_files(gooddir, baddir):
- files_a = find(gooddir, "*")
- files_b = find(baddir, "*")
+def prepare_files(gooddir, baddir, rspfile):
+ files_a = []
+ files_b = []
- basenames_a = set(map(os.path.basename, files_a))
- basenames_b = set(map(os.path.basename, files_b))
+ if rspfile is not None:
+ def get_basename(name):
+ # remove prefix
+ if name.startswith(gooddir):
+ return name[len(gooddir):]
+ if name.startswith(baddir):
+ return name[len(baddir):]
+ assert False, ""
+
+ with open(rspfile, "r") as rf:
+ for line in rf.read().splitlines():
+ for obj in line.split():
+ assert not os.path.isabs(obj), "TODO: support abs path"
+ files_a.append(gooddir + "/" + obj)
+ files_b.append(baddir + "/" + obj)
+ else:
+ get_basename = lambda name: os.path.basename(name)
+ files_a = find(gooddir, "*")
+ files_b = find(baddir, "*")
+
+ basenames_a = set(map(get_basename, files_a))
+ basenames_b = set(map(get_basename, files_b))
for name in files_b:
- basename = os.path.basename(name)
+ basename = get_basename(name)
if basename not in basenames_a:
warn("There is no corresponding file to '%s' in %s" %
(name, gooddir))
choices = []
skipped = []
for name in files_a:
- basename = os.path.basename(name)
+ basename = get_basename(name)
if basename not in basenames_b:
warn("There is no corresponding file to '%s' in %s" %
(name, baddir))
@@ -271,13 +296,25 @@
# Note that we iterate over files_a so we don't change the order
# (cannot use `picks` as it is a dictionary without order)
for x in files_a:
- basename = os.path.basename(x)
+ basename = get_basename(x)
picked = picks.get(basename)
if picked is None:
assert basename in skipped
files.append(x)
else:
files.append(picked)
+
+ # If response file is used, create a temporary response file for the
+ # picked files.
+ if rspfile is not None:
+ with tempfile.NamedTemporaryFile('w', suffix='.rsp',
+ delete=False) as tf:
+ tf.write(" ".join(files))
+ tf.flush()
+ ret = testrun([tf.name])
+ os.remove(tf.name)
+ return ret
+
return testrun(files)
return perform_test, choices
@@ -332,6 +369,8 @@
parser = argparse.ArgumentParser()
parser.add_argument('--a', dest='dir_a', default='before')
parser.add_argument('--b', dest='dir_b', default='after')
+ parser.add_argument('--rsp', default=None)
+ parser.add_argument('--test', default='./link_test')
parser.add_argument('--insane', help='Skip sanity check',
action='store_true')
parser.add_argument('--seq',
@@ -342,6 +381,9 @@
gooddir = config.dir_a
baddir = config.dir_b
+ rspfile = config.rsp
+ global LINKTEST
+ LINKTEST = config.test
# Preparation phase: Creates a dictionary mapping names to a list of two
# choices each. The bisection algorithm will pick one choice for each name
@@ -352,7 +394,7 @@
perform_test, choices = prepare_functions(config.file, gooddir,
goodfile, badfile)
else:
- perform_test, choices = prepare_files(gooddir, baddir)
+ perform_test, choices = prepare_files(gooddir, baddir, rspfile)
info("%d bisection choices" % len(choices))
diff --git a/src/llvm-project/llvm/utils/benchmark/README.LLVM b/src/llvm-project/llvm/utils/benchmark/README.LLVM
index 5e0067b..d77da3b 100644
--- a/src/llvm-project/llvm/utils/benchmark/README.LLVM
+++ b/src/llvm-project/llvm/utils/benchmark/README.LLVM
@@ -34,6 +34,6 @@
asm issues and 32-bit RISC-V build failures. The second cherrypicked commit
fixes formatting issues introduced by the preceding change.
* https://github.com/google/benchmark/commit/ffe1342eb2faa7d2e7c35b4db2ccf99fab81ec20
- is applied to add the CycleTimer implementation for M680x0
+ is applied to add the CycleTimer implementation for M68k
* https://github.com/google/benchmark/commit/d9abf017632be4a00b92cf4289539b353fcea5d2
is applied to rename 'mftbl' to 'mftb'.
diff --git a/src/llvm-project/llvm/utils/benchmark/include/benchmark/benchmark.h b/src/llvm-project/llvm/utils/benchmark/include/benchmark/benchmark.h
index 3b535f1..528aa7f 100644
--- a/src/llvm-project/llvm/utils/benchmark/include/benchmark/benchmark.h
+++ b/src/llvm-project/llvm/utils/benchmark/include/benchmark/benchmark.h
@@ -952,7 +952,7 @@
FunctionBenchmark(const char* name, Function* func)
: Benchmark(name), func_(func) {}
- virtual void Run(State& st);
+ void Run(State& st) override;
private:
Function* func_;
@@ -962,7 +962,7 @@
template <class Lambda>
class LambdaBenchmark : public Benchmark {
public:
- virtual void Run(State& st) { lambda_(st); }
+ void Run(State& st) override { lambda_(st); }
private:
template <class OLambda>
@@ -1013,7 +1013,7 @@
public:
Fixture() : internal::Benchmark("") {}
- virtual void Run(State& st) {
+ void Run(State& st) override {
this->SetUp(st);
this->BenchmarkCase(st);
this->TearDown(st);
@@ -1399,8 +1399,8 @@
: output_options_(opts_), name_field_width_(0),
prev_counters_(), printed_header_(false) {}
- virtual bool ReportContext(const Context& context);
- virtual void ReportRuns(const std::vector<Run>& reports);
+ bool ReportContext(const Context& context) override;
+ void ReportRuns(const std::vector<Run>& reports) override;
protected:
virtual void PrintRunData(const Run& report);
@@ -1415,9 +1415,9 @@
class JSONReporter : public BenchmarkReporter {
public:
JSONReporter() : first_report_(true) {}
- virtual bool ReportContext(const Context& context);
- virtual void ReportRuns(const std::vector<Run>& reports);
- virtual void Finalize();
+ bool ReportContext(const Context& context) override;
+ void ReportRuns(const std::vector<Run>& reports) override;
+ void Finalize() override;
private:
void PrintRunData(const Run& report);
@@ -1428,8 +1428,8 @@
class CSVReporter : public BenchmarkReporter {
public:
CSVReporter() : printed_header_(false) {}
- virtual bool ReportContext(const Context& context);
- virtual void ReportRuns(const std::vector<Run>& reports);
+ bool ReportContext(const Context& context) override;
+ void ReportRuns(const std::vector<Run>& reports) override;
private:
void PrintRunData(const Run& report);
diff --git a/src/llvm-project/llvm/utils/benchmark/src/complexity.cc b/src/llvm-project/llvm/utils/benchmark/src/complexity.cc
index 97bf6e0..97cb0a8 100644
--- a/src/llvm-project/llvm/utils/benchmark/src/complexity.cc
+++ b/src/llvm-project/llvm/utils/benchmark/src/complexity.cc
@@ -76,7 +76,6 @@
LeastSq MinimalLeastSq(const std::vector<int64_t>& n,
const std::vector<double>& time,
BigOFunc* fitting_curve) {
- double sigma_gn = 0.0;
double sigma_gn_squared = 0.0;
double sigma_time = 0.0;
double sigma_time_gn = 0.0;
@@ -84,7 +83,6 @@
// Calculate least square fitting parameter
for (size_t i = 0; i < n.size(); ++i) {
double gn_i = fitting_curve(n[i]);
- sigma_gn += gn_i;
sigma_gn_squared += gn_i * gn_i;
sigma_time += time[i];
sigma_time_gn += time[i] * gn_i;
diff --git a/src/llvm-project/llvm/utils/benchmark/src/sysinfo.cc b/src/llvm-project/llvm/utils/benchmark/src/sysinfo.cc
index 04254bb..01dd8a0 100644
--- a/src/llvm-project/llvm/utils/benchmark/src/sysinfo.cc
+++ b/src/llvm-project/llvm/utils/benchmark/src/sysinfo.cc
@@ -176,8 +176,9 @@
return true;
}
-template <class Tp, class = std::enable_if_t<std::is_integral<Tp>::value>>
-bool GetSysctl(std::string const &Name, Tp *Out) {
+template <class Tp,
+ class = typename std::enable_if<std::is_integral<Tp>::value>::type>
+bool GetSysctl(std::string const& Name, Tp* Out) {
*Out = 0;
auto Buff = GetSysctlImp(Name);
if (!Buff) return false;
diff --git a/src/llvm-project/llvm/utils/codegen-diff b/src/llvm-project/llvm/utils/codegen-diff
index 2c3ac4c..16c6e95 100755
--- a/src/llvm-project/llvm/utils/codegen-diff
+++ b/src/llvm-project/llvm/utils/codegen-diff
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
use Getopt::Std;
$DEBUG = 0;
diff --git a/src/llvm-project/llvm/utils/emacs/llvm-mode.el b/src/llvm-project/llvm/utils/emacs/llvm-mode.el
index bc24b12..4a0b90d 100644
--- a/src/llvm-project/llvm/utils/emacs/llvm-mode.el
+++ b/src/llvm-project/llvm/utils/emacs/llvm-mode.el
@@ -22,12 +22,12 @@
(list
;; Attributes
`(,(regexp-opt
- '("alwaysinline" "argmemonly" "builtin" "cold" "convergent" "inaccessiblememonly"
- "inaccessiblemem_or_argmemonly" "inlinehint" "jumptable" "minsize" "mustprogress" "naked" "nobuiltin"
- "noduplicate" "nofree" "noimplicitfloat" "noinline" "nonlazybind" "noredzone" "noreturn"
- "norecurse" "noundef" "nounwind" "optnone" "optsize" "readnone" "readonly" "returns_twice"
- "speculatable" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" "sanitize_memtag"
- "sanitize_thread" "sanitize_memory" "strictfp" "uwtable" "willreturn" "writeonly" "immarg") 'symbols) . font-lock-constant-face)
+ '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "hot" "inaccessiblememonly"
+ "inaccessiblemem_or_argmemonly" "inalloca" "inlinehint" "jumptable" "minsize" "mustprogress" "naked" "nobuiltin" "nonnull"
+ "nocallback" "nocf_check" "noduplicate" "nofree" "noimplicitfloat" "noinline" "nomerge" "nonlazybind" "noprofile" "noredzone" "noreturn"
+ "norecurse" "nosync" "noundef" "nounwind" "nosanitize_coverage" "null_pointer_is_valid" "optforfuzzing" "optnone" "optsize" "preallocated" "readnone" "readonly" "returned" "returns_twice"
+ "shadowcallstack" "speculatable" "speculative_load_hardening" "ssp" "sspreq" "sspstrong" "safestack" "sanitize_address" "sanitize_hwaddress" "sanitize_memtag"
+ "sanitize_thread" "sanitize_memory" "strictfp" "swifterror" "uwtable" "vscale_range" "willreturn" "writeonly" "immarg") 'symbols) . font-lock-constant-face)
;; Variables
'("%[-a-zA-Z$._][-a-zA-Z$._0-9]*" . font-lock-variable-name-face)
;; Labels
@@ -35,7 +35,9 @@
;; Unnamed variable slots
'("%[-]?[0-9]+" . font-lock-variable-name-face)
;; Types
- `(,(regexp-opt '("void" "i1" "i8" "i16" "i32" "i64" "i128" "float" "double" "type" "label" "opaque") 'symbols) . font-lock-type-face)
+ `(,(regexp-opt
+ '("void" "i1" "i8" "i16" "i32" "i64" "i128" "half" "bfloat" "float" "double" "fp128" "x86_fp80" "ppc_fp128" "x86_mmx" "x86_amx"
+ "type" "label" "opaque" "token") 'symbols) . font-lock-type-face)
;; Integer literals
'("\\b[-]?[0-9]+\\b" . font-lock-preprocessor-face)
;; Floating point constants
@@ -45,19 +47,27 @@
;; Keywords
`(,(regexp-opt
'(;; Toplevel entities
- "declare" "define" "module" "target" "source_filename" "global" "constant" "const"
+ "declare" "define" "module" "target" "source_filename" "global" "constant" "const" "alias" "ifunc" "comdat"
"attributes" "uselistorder" "uselistorder_bb"
;; Linkage types
"private" "internal" "weak" "weak_odr" "linkonce" "linkonce_odr" "available_externally" "appending" "common" "extern_weak" "external"
"uninitialized" "implementation" "..."
;; Values
- "true" "false" "null" "undef" "zeroinitializer" "none" "c" "asm" "blockaddress"
+ "true" "false" "null" "undef" "zeroinitializer" "none" "c" "asm" "blockaddress" "poison"
;; Calling conventions
"ccc" "fastcc" "coldcc" "webkit_jscc" "anyregcc" "preserve_mostcc" "preserve_allcc"
- "cxx_fast_tlscc" "swiftcc"
+ "cxx_fast_tlscc" "swiftcc" "tailcc" "swifttailcc" "cfguard_checkcc"
+ ;; Visibility styles
+ "default" "hidden" "protected"
+ ;; DLL storages
+ "dllimport" "dllexport"
+ ;; Thread local
+ "thread_local" "localdynamic" "initialexec" "localexec"
+ ;; Runtime preemption specifiers
+ "dso_preemptable" "dso_local" "dso_local_equivalent"
- "atomic" "volatile" "personality" "prologue" "section") 'symbols) . font-lock-keyword-face)
+ "gc" "atomic" "volatile" "personality" "prologue" "section") 'symbols) . font-lock-keyword-face)
;; Arithmetic and Logical Operators
`(,(regexp-opt '("add" "sub" "mul" "sdiv" "udiv" "urem" "srem" "and" "or" "xor"
"setne" "seteq" "setlt" "setgt" "setle" "setge") 'symbols) . font-lock-keyword-face)
@@ -77,18 +87,16 @@
`(,(regexp-opt '("extractvalue" "insertvalue") 'symbols) . font-lock-keyword-face)
;; Metadata types
`(,(regexp-opt '("distinct") 'symbols) . font-lock-keyword-face)
+ ;; Atomic memory ordering constraints
+ `(,(regexp-opt '("unordered" "monotonic" "acquire" "release" "acq_rel" "seq_cst") 'symbols) . font-lock-keyword-face)
+ ;; Fast-math flags
+ `(,(regexp-opt '("nnan" "ninf" "nsz" "arcp" "contract" "afn" "reassoc" "fast") 'symbols) . font-lock-keyword-face)
;; Use-list order directives
`(,(regexp-opt '("uselistorder" "uselistorder_bb") 'symbols) . font-lock-keyword-face))
"Syntax highlighting for LLVM.")
-;; Emacs 23 compatibility.
-(defalias 'llvm-mode-prog-mode
- (if (fboundp 'prog-mode)
- 'prog-mode
- 'fundamental-mode))
-
;;;###autoload
-(define-derived-mode llvm-mode llvm-mode-prog-mode "LLVM"
+(define-derived-mode llvm-mode prog-mode "LLVM"
"Major mode for editing LLVM source files.
\\{llvm-mode-map}
Runs `llvm-mode-hook' on startup."
diff --git a/src/llvm-project/llvm/utils/extract-section.py b/src/llvm-project/llvm/utils/extract-section.py
new file mode 100755
index 0000000..ca19b0e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/extract-section.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+from __future__ import print_function
+'''
+Helper script to print out the raw content of an ELF section.
+Example usages:
+```
+# print out as bits by default
+extract-section.py .text --input-file=foo.o
+```
+```
+# read from stdin and print out in hex
+cat foo.o | extract-section.py -h .text
+```
+This is merely a wrapper around `llvm-readobj` that focuses on the binary
+content as well as providing more formatting options.
+'''
+
+# Unfortunately reading binary from stdin is not so trivial in Python...
+def read_raw_stdin():
+ import sys
+ if sys.version_info >= (3, 0):
+ reading_source = sys.stdin.buffer
+ else:
+ # Windows will always read as string so we need some
+ # special handling
+ if sys.platform == 'win32':
+ import os, msvcrt
+ msvcrt.setformat(sys.stdin.fileno(), os.O_BINARY)
+ reading_source = sys.stdin
+ return reading_source.read()
+
+def get_raw_section_dump(readobj_path, section_name, input_file):
+ import subprocess
+ cmd = [readobj_path, '-elf-output-style=GNU', '--hex-dump={}'.format(section_name),
+ input_file]
+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
+
+ if input_file == '-':
+ # From stdin
+ out,_ = proc.communicate(input=read_raw_stdin())
+ else:
+ out,_ = proc.communicate()
+
+ return out.decode('utf-8') if type(out) is not str else out
+
+if __name__ == '__main__':
+ import argparse
+ # The default '-h' (--help) will conflict with our '-h' (hex) format
+ arg_parser = argparse.ArgumentParser(add_help=False)
+ arg_parser.add_argument('--readobj-path', metavar='<executable path>', type=str,
+ help='Path to llvm-readobj')
+ arg_parser.add_argument('--input-file', metavar='<file>', type=str,
+ help='Input object file, or \'-\' to read from stdin')
+ arg_parser.add_argument('section', metavar='<name>', type=str,
+ help='Name of the section to extract')
+ # Output format
+ format_group = arg_parser.add_mutually_exclusive_group()
+ format_group.add_argument('-b', dest='format', action='store_const', const='bits',
+ help='Print out in bits')
+ arg_parser.add_argument('--byte-indicator', action='store_true',
+ help='Whether to print a \'.\' every 8 bits in bits printing mode')
+ format_group.add_argument('-h', dest='format', action='store_const', const='hex',
+ help='Print out in hexadecimal')
+ arg_parser.add_argument('--hex-width', metavar='<# of bytes>', type=int,
+ help='The width (in byte) of every element in hex printing mode')
+
+ arg_parser.add_argument('--help', action='help')
+ arg_parser.set_defaults(format='bits', tool_path='llvm-readobj', input_file='-',
+ byte_indicator=False, hex_width=4)
+ args = arg_parser.parse_args()
+
+ raw_section = get_raw_section_dump(args.tool_path, args.section, args.input_file)
+
+ results = []
+ for line in raw_section.splitlines(False):
+ if line.startswith('Hex dump'):
+ continue
+ parts = line.strip().split(' ')[1:]
+ for part in parts[:4]:
+ # exclude any non-hex dump string
+ try:
+ val = int(part, 16)
+ if args.format == 'bits':
+ # divided into bytes first
+ for byte in [(val >> off) & 0xFF for off in (24,16,8,0)]:
+ for bit in [(byte >> off) & 1 for off in range(7, -1, -1)]:
+ results.append(str(bit))
+ if args.byte_indicator:
+ results.append('.')
+ elif args.format == 'hex':
+ assert args.hex_width <= 4 and args.hex_width > 0
+ width_bits = args.hex_width * 8
+ offsets = [off for off in range(32 - width_bits, -1, -width_bits)]
+ mask = (1 << width_bits) - 1
+ format_str = "{:0" + str(args.hex_width * 2) + "x}"
+ for word in [(val >> i) & mask for i in offsets]:
+ results.append(format_str.format(word))
+ except:
+ break
+ print(' '.join(results), end='')
diff --git a/src/llvm-project/llvm/utils/findsym.pl b/src/llvm-project/llvm/utils/findsym.pl
index 9234657..f03e123 100755
--- a/src/llvm-project/llvm/utils/findsym.pl
+++ b/src/llvm-project/llvm/utils/findsym.pl
@@ -1,4 +1,4 @@
-#!/usr/bin/perl -w
+#!/usr/bin/env perl
#
# Program: findsym.pl
#
@@ -8,6 +8,8 @@
# Syntax: findsym.pl <directory_with_libraries_in_it> <symbol>
#
+use warnings;
+
# Give first option a name.
my $Directory = $ARGV[0];
my $Symbol = $ARGV[1];
diff --git a/src/llvm-project/llvm/utils/gn/TODO.txt b/src/llvm-project/llvm/utils/gn/TODO.txt
index f573481..1a13331 100644
--- a/src/llvm-project/llvm/utils/gn/TODO.txt
+++ b/src/llvm-project/llvm/utils/gn/TODO.txt
@@ -1,6 +1,6 @@
Ideas for things to do:
-- more projects (compiler-rt's asan/ubsan/msan/tsan, lldb)
+- more projects (lldb, check- targets for compiler-rt's asan/ubsan/msan/tsan)
- once there are more projects, have an llvm_enable_projects arg, modeled
after llvm_targets_to_build in the GN build
- a check-all build target that runs test of all projects
@@ -19,7 +19,8 @@
- move run_tablegen.py from build to tablegen folder
- figure out why -Iclang/Support gets added so often
=> https://groups.google.com/a/chromium.org/forum/?oldui=1#!msg/gn-dev/0S7KRGIXcDI/E4ahA1jQFQAJ
- - ...figure out some approach for this
+ => Fixed in https://gn-review.googlesource.com/c/gn/+/11701 !
+ `llvm/utils/gn/get.py` to get new gn binary with the fix
- plugin() template with working rpath, exports thingers
- then port clang_build_examples and enable by default so that clang
plugin tests run by default
diff --git a/src/llvm-project/llvm/utils/gn/build/BUILD.gn b/src/llvm-project/llvm/utils/gn/build/BUILD.gn
index 813f39d..8df8be1 100644
--- a/src/llvm-project/llvm/utils/gn/build/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/build/BUILD.gn
@@ -1,5 +1,6 @@
import("//llvm/utils/gn/build/buildflags.gni")
import("//llvm/utils/gn/build/mac_sdk.gni")
+import("//llvm/utils/gn/build/sysroot.gni")
import("//llvm/utils/gn/build/toolchain/compiler.gni")
import("//llvm/utils/gn/build/toolchain/target_flags.gni")
@@ -8,7 +9,7 @@
# After building with this, run tests and then run
# llvm/utils/prepare-code-coverage-artifact.py \
# .../llvm-profdata .../llvm-cov out/gn/profiles/ report/ \
- # out/gn/bin/llvm-undname ...`
+ # out/gn/bin/llvm-undname ...
# to generate a HTML report for the binaries passed in the last line.
llvm_build_instrumented_coverage = false
@@ -42,24 +43,6 @@
cflags = target_flags
ldflags = target_flags + target_ldflags
- if ((current_os == "ios" || current_os == "mac") && clang_base_path != "") {
- if (current_os == "ios" && current_cpu == "arm64") {
- sdk_path = ios_sdk_path
- } else if (current_os == "ios" && current_cpu == "x64") {
- sdk_path = iossim_sdk_path
- } else if (current_os == "mac") {
- sdk_path = mac_sdk_path
- }
- cflags += [
- "-isysroot",
- sdk_path,
- ]
- ldflags += [
- "-isysroot",
- sdk_path,
- ]
- }
-
# Mostly for compiler-rt, see compiler-rt/cmake/config-ix.cmake
if (current_os == "ios") {
asmflags += [ "-miphoneos-version-min=8.0" ]
@@ -90,7 +73,6 @@
}
} else if (symbol_level == 1) {
cflags += [ "-g1" ]
-
# For linetable-only -g1 builds, --gdb-index makes links ~8% slower, but
# links are 4x faster than -g builds so it's a fairly small absolute cost.
# On the other hand, gdb startup is well below 1s with and without the
@@ -236,11 +218,7 @@
# On Windows, the linker is not invoked through the compiler driver.
if (use_lld && host_os != "win") {
- if (host_os == "mac") {
- ldflags += [ "-fuse-ld=lld.darwinnew" ]
- } else {
- ldflags += [ "-fuse-ld=lld" ]
- }
+ ldflags += [ "-fuse-ld=lld" ]
}
if (llvm_build_instrumented_coverage) {
@@ -255,7 +233,17 @@
"-fprofile-instr-generate=" +
rebase_path("$root_build_dir/profiles/%4m.profraw"),
]
- ldflags += [ "-fprofile-instr-generate" ]
+ if (use_goma) {
+ # goma has a bug where it writes the server-side absolute path.
+ # Work around that.
+ # FIXME: Instead, set this to `.` for deterministic builds and pass
+ # the build dir to prepare-code-coverage-artifact.py instead.
+ cflags += [ "-fcoverage-compilation-dir=" + rebase_path(root_build_dir) ]
+ }
+
+ if (host_os != "win") {
+ ldflags += [ "-fprofile-instr-generate" ]
+ }
}
# Deterministic build setup, see
@@ -282,17 +270,53 @@
]
}
}
+ if (sysroot != "") {
+ if (current_os == "win") {
+ assert(is_clang, "sysroot only works with clang-cl as host compiler")
+ cflags += [ "/winsysroot" + rebase_path(sysroot, root_build_dir) ]
+ } else if (current_os != "ios" && current_os != "mac") {
+ cflags += [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ]
+ }
+ }
+ if ((current_os == "ios" || current_os == "mac") &&
+ (clang_base_path != "" || sysroot != "")) {
+ if (current_os == "ios" && current_cpu == "arm64") {
+ sdk_path = ios_sdk_path
+ } else if (current_os == "ios" && current_cpu == "x64") {
+ sdk_path = iossim_sdk_path
+ } else if (current_os == "mac") {
+ sdk_path = mac_sdk_path
+ }
+ cflags += [
+ "-isysroot",
+ rebase_path(sdk_path, root_build_dir),
+ ]
+ ldflags += [
+ "-isysroot",
+ rebase_path(sdk_path, root_build_dir),
+ ]
+ }
+ if (sysroot != "" && current_os != "win" && is_clang) {
+ cflags += [ "-Wpoison-system-directories" ]
+ }
+ assert(
+ !use_goma || sysroot != "",
+ "goma needs a sysroot: run `llvm/utils/sysroot.py make-fake --out-dir=sysroot` and add `sysroot = \"//sysroot\"` to your args.gn")
if (use_ubsan) {
assert(is_clang && current_os == "linux",
"ubsan only supported on Linux/Clang")
- cflags += [ "-fsanitize=undefined" ]
+ cflags += [
+ "-fsanitize=undefined",
+ "-fno-sanitize-recover=all",
+ ]
ldflags += [ "-fsanitize=undefined" ]
}
if (use_asan) {
- assert(is_clang && current_os == "linux",
- "asan only supported on Linux/Clang")
+ assert(is_clang && (current_os == "ios" || current_os == "linux" ||
+ current_os == "mac"),
+ "asan only supported on iOS/Clang, Linux/Clang, and macOS/Clang")
cflags += [ "-fsanitize=address" ]
ldflags += [ "-fsanitize=address" ]
}
@@ -380,6 +404,12 @@
"-gline-tables-only",
"-fvisibility=hidden",
]
+ assert(is_clang, "CRT code is always built with just-built clang")
+ cflags += [
+ "-Werror=thread-safety",
+ "-Werror=thread-safety-reference",
+ "-Werror=thread-safety-beta",
+ ]
}
config("warn_covered_switch_default") {
diff --git a/src/llvm-project/llvm/utils/gn/build/libs/xml/BUILD.gn b/src/llvm-project/llvm/utils/gn/build/libs/xml/BUILD.gn
index 3af3c85..5d52264 100644
--- a/src/llvm-project/llvm/utils/gn/build/libs/xml/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/build/libs/xml/BUILD.gn
@@ -1,5 +1,6 @@
import("//llvm/utils/gn/build/libs/xml/enable.gni")
import("//llvm/utils/gn/build/mac_sdk.gni")
+import("//llvm/utils/gn/build/sysroot.gni")
config("xml_config") {
visibility = [ ":xml" ]
@@ -7,7 +8,7 @@
if (host_os == "mac") {
include_dirs = [ "$mac_sdk_path/usr/include/libxml2" ]
} else {
- include_dirs = [ "/usr/include/libxml2" ]
+ include_dirs = [ "$sysroot/usr/include/libxml2" ]
}
}
diff --git a/src/llvm-project/llvm/utils/gn/build/mac_sdk.gni b/src/llvm-project/llvm/utils/gn/build/mac_sdk.gni
index b6c9baa..af7044b 100644
--- a/src/llvm-project/llvm/utils/gn/build/mac_sdk.gni
+++ b/src/llvm-project/llvm/utils/gn/build/mac_sdk.gni
@@ -1,20 +1,31 @@
-declare_args() {
- # Set to true if you don't have Xcode installed, but do have the commandline
- # tools.
- mac_use_commandline_tools_sdk = false
-}
+import("//llvm/utils/gn/build/sysroot.gni")
-# Location of the mac sdk.
-# The correct way to do this is to call xcrun (https://reviews.llvm.org/D70835),
-# but that makes `gn gen` take twice as long and almost everyone has Xcode
-# installed. So require that people who don't have it installed set a gn arg.
-if (mac_use_commandline_tools_sdk) {
- ios_sdk_path = "/Library/Developer/CommandLineTools/SDKs/iPhoneOS.sdk"
- iossim_sdk_path =
- "/Library/Developer/CommandLineTools/SDKs/iPhoneSimulator.sdk"
- mac_sdk_path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
+have_ios_sdks = true
+
+if (sysroot == "") {
+ declare_args() {
+ # Set to true if you don't have Xcode installed, but do have the commandline
+ # tools.
+ mac_use_commandline_tools_sdk = false
+ }
+
+ # Location of the mac sdk.
+ # The correct way to do this is to call xcrun
+ # (https://reviews.llvm.org/D70835), but that makes `gn gen` take twice as
+ # long and almost everyone has Xcode installed. So require that people who
+ # don't have it installed set a gn arg.
+ if (mac_use_commandline_tools_sdk) {
+ mac_sdk_path = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
+
+ # iOS SDKs aren't available in the commandline tools SDK.
+ have_ios_sdks = false
+ } else {
+ mac_sdk_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+ ios_sdk_path = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
+ iossim_sdk_path = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk"
+ }
} else {
- ios_sdk_path = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
- iossim_sdk_path = "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk"
- mac_sdk_path = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk"
+ ios_sdk_path = sysroot + "/iPhoneOS.sdk"
+ iossim_sdk_path = sysroot + "/iPhoneSimulator.sdk"
+ mac_sdk_path = sysroot + "/MacOSX.sdk"
}
diff --git a/src/llvm-project/llvm/utils/gn/build/symbol_exports.gni b/src/llvm-project/llvm/utils/gn/build/symbol_exports.gni
new file mode 100644
index 0000000..d81d9ea
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/build/symbol_exports.gni
@@ -0,0 +1,60 @@
+# This file defines a template for using .export files.
+#
+# Parameters:
+# exports_file (required)
+# Path of the .exports file to use.
+#
+# Example use:
+# symbol_exports("my_exports") {
+# exports_file = "//foo/bar/my.exports"
+# }
+# ...
+# shared_library("my_target") {
+# deps = [ ":my_exports" ] # Adds correct ldflags.
+# ...
+# }
+
+# Corresponds to add_llvm_symbol_exports() in the CMake build.
+template("symbol_exports") {
+ # Create a platform-appropriate name for the temporary file.
+ linker_file = get_path_info(invoker.exports_file, "name")
+ if (current_os == "mac") {
+ linker_file = linker_file + "_symbols.txt"
+ } else if (current_os == "win") {
+ linker_file = linker_file + ".def"
+ } else {
+ linker_file = linker_file + ".script"
+ }
+ linker_file = "$target_gen_dir/$linker_file"
+ rebased_linker_file = rebase_path(linker_file, root_build_dir)
+
+ config_name = "${target_name}_config"
+ config(config_name) {
+ # FIXME: With this setup, targets are not relinked automatically
+ # when the input exports file is touched but nothing else changes.
+ # https://groups.google.com/a/chromium.org/g/gn-dev/c/sN09GYS1ufE
+ visibility = [ ":$target_name" ]
+ if (current_os == "mac") {
+ ldflags = [ "-Wl,-exported_symbols_list,$rebased_linker_file" ]
+ } else if (current_os == "win") {
+ ldflags = [ "/DEF:$rebased_linker_file" ]
+ } else {
+ ldflags = [ "-Wl,--version-script,$rebased_linker_file" ]
+ }
+ }
+
+ action(target_name) {
+ forward_variables_from(invoker, [ "deps" ])
+ script = "//llvm/utils/gn/build/symbol_exports.py"
+ inputs = [ invoker.exports_file ]
+ outputs = [ linker_file ]
+ args = [
+ "--format=" + current_os,
+ rebase_path(inputs[0], root_build_dir),
+ rebased_linker_file,
+ ]
+
+ # Let targets depending on this receive the right ldflags.
+ public_configs = [ ":$config_name" ]
+ }
+}
diff --git a/src/llvm-project/llvm/utils/gn/build/symbol_exports.py b/src/llvm-project/llvm/utils/gn/build/symbol_exports.py
new file mode 100755
index 0000000..198eb05
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/build/symbol_exports.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+"""Converts a .exports file to a format consumable by linkers.
+
+An .exports file is a file with one exported symbol per line.
+This script converts a .exports file into a format that linkers
+can understand:
+- It prepends a `_` to each line for use with -exported_symbols_list for Darwin
+- It writes a .def file for use with /DEF: for Windows
+- It writes a linker script for use with --version-script elsewhere
+"""
+
+import argparse
+import sys
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument('--format', required=True,
+ choices=('linux','mac','win'))
+ parser.add_argument('source')
+ parser.add_argument('output')
+ args = parser.parse_args()
+
+ symbols = open(args.source).readlines()
+
+ if args.format == 'linux':
+ output_lines = (['FOO {\n',
+ ' global:\n',] +
+ [' %s;\n' % s.rstrip() for s in symbols] +
+ [' local:\n',
+ ' *;\n',
+ '};\n'])
+ elif args.format == 'mac':
+ output_lines = ['_' + s for s in symbols]
+ else:
+ assert args.format == 'win'
+ output_lines = ['EXPORTS\n'] + [' ' + s for s in symbols]
+
+ open(args.output, 'w').writelines(output_lines)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/src/llvm-project/llvm/utils/gn/build/sync_source_lists_from_cmake.py b/src/llvm-project/llvm/utils/gn/build/sync_source_lists_from_cmake.py
index 1906c2a..6326f4c 100755
--- a/src/llvm-project/llvm/utils/gn/build/sync_source_lists_from_cmake.py
+++ b/src/llvm-project/llvm/utils/gn/build/sync_source_lists_from_cmake.py
@@ -54,7 +54,8 @@
# Use shell=True on Windows in case git is a bat file.
def git(args): subprocess.check_call(['git'] + args, shell=os.name == 'nt')
def git_out(args):
- return subprocess.check_output(['git'] + args, shell=os.name == 'nt')
+ return subprocess.check_output(['git'] + args, shell=os.name == 'nt',
+ universal_newlines=True)
gn_files = git_out(['ls-files', '*BUILD.gn']).splitlines()
# Matches e.g. | "foo.cpp",|, captures |foo| in group 1.
diff --git a/src/llvm-project/llvm/utils/gn/build/sysroot.gni b/src/llvm-project/llvm/utils/gn/build/sysroot.gni
new file mode 100644
index 0000000..b1b4e74
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/build/sysroot.gni
@@ -0,0 +1,4 @@
+declare_args() {
+ # Path of sysroot to use.
+ sysroot = ""
+}
diff --git a/src/llvm-project/llvm/utils/gn/build/toolchain/BUILD.gn b/src/llvm-project/llvm/utils/gn/build/toolchain/BUILD.gn
index d01cad9..63e61db 100644
--- a/src/llvm-project/llvm/utils/gn/build/toolchain/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/build/toolchain/BUILD.gn
@@ -2,6 +2,7 @@
declare_args() {
# If is_goma is true, the location of the goma client install.
+ # Set this to the output of `goma_ctl goma_dir`.
if (host_os == "win") {
goma_dir = "C:/src/goma/goma-win64"
} else {
@@ -9,6 +10,9 @@
}
}
+assert(!use_goma || goma_dir != "",
+ "set goma_dir to the output of `goma_ctl goma_dir` in your args.gn")
+
template("unix_toolchain") {
toolchain(target_name) {
# https://groups.google.com/a/chromium.org/d/msg/gn-dev/F_lv5T-tNDM
@@ -21,8 +25,8 @@
cxx = "c++"
if (clang_base_path != "") {
- cc = "$clang_base_path/bin/clang"
- cxx = "$clang_base_path/bin/clang++"
+ cc = rebase_path(clang_base_path, root_build_dir) + "/bin/clang"
+ cxx = rebase_path(clang_base_path, root_build_dir) + "/bin/clang++"
}
ld = cxx # Don't use goma wrapper for linking.
@@ -181,7 +185,7 @@
toolchain_args = {
forward_variables_from(invoker.toolchain_args, "*")
- clang_base_path = "."
+ clang_base_path = root_build_dir
use_goma = false
}
@@ -235,113 +239,137 @@
}
}
-toolchain("win") {
- cl = "cl"
- link = "link"
+template("win_toolchain") {
+ toolchain(target_name) {
+ # https://groups.google.com/a/chromium.org/d/msg/gn-dev/F_lv5T-tNDM
+ forward_variables_from(invoker.toolchain_args, "*")
+ not_needed("*")
- if (clang_base_path != "") {
- cl = "$clang_base_path/bin/clang-cl"
- if (use_lld) {
- link = "$clang_base_path/bin/lld-link"
+ forward_variables_from(invoker, "*")
+
+ cl = "cl"
+ link = "link"
+
+ if (clang_base_path != "") {
+ cl = rebase_path(clang_base_path, root_build_dir) + "/bin/clang-cl"
+ if (use_lld) {
+ link = rebase_path(clang_base_path, root_build_dir) + "/bin/lld-link"
+ }
+ }
+
+ if (use_goma) {
+ cl = "$goma_dir/gomacc $cl"
+ }
+
+ tool("cc") {
+ command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
+ depsformat = "msvc"
+ description = "CC {{output}}"
+ outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
+ }
+
+ tool("cxx") {
+ command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
+ depsformat = "msvc"
+ description = "CXX {{output}}"
+ outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
+ }
+
+ tool("alink") {
+ command = "$link /lib /nologo {{arflags}} /out:{{output}} {{inputs}}"
+ description = "LIB {{output}}"
+ outputs = [ "{{output_dir}}/{{target_output_name}}.lib" ]
+ default_output_dir = "{{root_out_dir}}/lib"
+ }
+
+ tool("solink") {
+ outprefix = "{{output_dir}}/{{target_output_name}}"
+ dllfile = "$outprefix{{output_extension}}"
+ libfile = "$outprefix.lib"
+ pdbfile = "$outprefix.pdb"
+ command = "$link /nologo /dll {{ldflags}} /out:$dllfile /implib:$libfile /pdb:$pdbfile {{inputs}} {{libs}} "
+ description = "LINK $dllfile"
+ link_output = libfile
+ depend_output = libfile
+ runtime_outputs = [ dllfile ]
+ outputs = [
+ dllfile,
+ libfile,
+ ]
+ lib_switch = ""
+ default_output_extension = ".dll"
+ restat = true
+
+ # Put dlls next to the executables in bin/ on Windows, since Windows
+ # doesn't have a configurable rpath. This matches initialization of
+ # module_dir to bin/ in AddLLVM.cmake's set_output_directory().
+ default_output_dir = "{{root_out_dir}}/bin"
+ }
+
+ # Plugins for opt and clang and so on don't work in LLVM's Windows build
+ # since the code doesn't have export annotations, but there are a few
+ # standalone loadable modules used for unit-testing LLVM's dynamic library
+ # loading code.
+ tool("solink_module") {
+ outprefix = "{{output_dir}}/{{target_output_name}}"
+ dllfile = "$outprefix{{output_extension}}"
+ pdbfile = "$outprefix.pdb"
+ command = "$link /nologo /dll {{ldflags}} /out:$dllfile /pdb:$pdbfile {{inputs}} {{libs}} "
+ description = "LINK_MODULE $dllfile"
+ outputs = [ dllfile ]
+ lib_switch = ""
+ runtime_outputs = outputs
+ default_output_extension = ".dll"
+
+ # No default_output_dir, all clients set output_dir.
+ }
+
+ tool("link") {
+ outprefix = "{{output_dir}}/{{target_output_name}}"
+ outfile = "$outprefix{{output_extension}}"
+ pdbfile = "$outprefix.pdb"
+ command = "$link /nologo {{ldflags}} /out:$outfile /pdb:$pdbfile {{inputs}} {{libs}}"
+ description = "LINK $outfile"
+ outputs = [ outfile ]
+ lib_switch = ""
+ default_output_extension = ".exe"
+
+ # Setting this allows targets to override the default executable output by
+ # setting output_dir.
+ default_output_dir = "{{root_out_dir}}/bin"
+ }
+
+ tool("copy") {
+ # GN hands out slash-using paths, but cmd's copy needs backslashes.
+ # Use cmd's %foo:a=b% substitution feature to convert.
+ command = "cmd /c set source=\"{{source}}\" & set output=\"{{output}}\" & call copy /Y %source:/=\% %output:\=/% > nul"
+ description = "COPY {{source}} {{output}}"
+ }
+
+ tool("stamp") {
+ command = "cmd /c type nul > {{output}}"
+ description = "STAMP {{output}}"
}
}
+}
- if (use_goma) {
- cl = "$goma_dir/gomacc $cl"
- }
-
- tool("cc") {
- command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
- depsformat = "msvc"
- description = "CC {{output}}"
- outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
- }
-
- tool("cxx") {
- command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
- depsformat = "msvc"
- description = "CXX {{output}}"
- outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
- }
-
- tool("alink") {
- command = "$link /lib /nologo {{arflags}} /out:{{output}} {{inputs}}"
- description = "LIB {{output}}"
- outputs = [ "{{output_dir}}/{{target_output_name}}.lib" ]
- default_output_dir = "{{root_out_dir}}/lib"
- }
-
- tool("solink") {
- outprefix = "{{output_dir}}/{{target_output_name}}"
- dllfile = "$outprefix{{output_extension}}"
- libfile = "$outprefix.lib"
- pdbfile = "$outprefix.pdb"
- command = "$link /nologo /dll {{ldflags}} /out:$dllfile /implib:$libfile /pdb:$pdbfile {{inputs}} {{libs}} "
- description = "LINK $dllfile"
- link_output = libfile
- depend_output = libfile
- runtime_outputs = [ dllfile ]
- outputs = [
- dllfile,
- libfile,
- ]
- lib_switch = ""
- default_output_extension = ".dll"
- restat = true
-
- # Put dlls next to the executables in bin/ on Windows, since Windows
- # doesn't have a configurable rpath. This matches initialization of
- # module_dir to bin/ in AddLLVM.cmake's set_output_directory().
- default_output_dir = "{{root_out_dir}}/bin"
- }
-
- # Plugins for opt and clang and so on don't work in LLVM's Windows build
- # since the code doesn't have export annotations, but there are a few
- # standalone loadable modules used for unit-testing LLVM's dynamic library
- # loading code.
- tool("solink_module") {
- outprefix = "{{output_dir}}/{{target_output_name}}"
- dllfile = "$outprefix{{output_extension}}"
- pdbfile = "$outprefix.pdb"
- command = "$link /nologo /dll {{ldflags}} /out:$dllfile /pdb:$pdbfile {{inputs}} {{libs}} "
- description = "LINK_MODULE $dllfile"
- outputs = [ dllfile ]
- lib_switch = ""
- runtime_outputs = outputs
- default_output_extension = ".dll"
-
- # No default_output_dir, all clients set output_dir.
- }
-
- tool("link") {
- outprefix = "{{output_dir}}/{{target_output_name}}"
- outfile = "$outprefix{{output_extension}}"
- pdbfile = "$outprefix.pdb"
- command = "$link /nologo {{ldflags}} /out:$outfile /pdb:$pdbfile {{inputs}} {{libs}}"
- description = "LINK $outfile"
- outputs = [ outfile ]
- lib_switch = ""
- default_output_extension = ".exe"
-
- # Setting this allows targets to override the default executable output by
- # setting output_dir.
- default_output_dir = "{{root_out_dir}}/bin"
- }
-
- tool("copy") {
- # GN hands out slash-using paths, but cmd's copy needs backslashes.
- # Use cmd's %foo:a=b% substitution feature to convert.
- command = "cmd /c set source=\"{{source}}\" & set output=\"{{output}}\" & call copy /Y %source:/=\% %output:\=/% > nul"
- description = "COPY {{source}} {{output}}"
- }
-
- tool("stamp") {
- command = "cmd /c type nul > {{output}}"
- description = "STAMP {{output}}"
- }
-
+win_toolchain("win") {
toolchain_args = {
current_os = "win"
current_cpu = host_cpu
}
}
+
+win_toolchain("stage2_win") {
+ toolchain_args = {
+ current_os = host_os
+ current_cpu = host_cpu
+
+ clang_base_path = root_build_dir
+ use_goma = false
+ }
+ deps = [
+ "//:clang($host_toolchain)",
+ "//:lld($host_toolchain)",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/build/toolchain/target_flags.gni b/src/llvm-project/llvm/utils/gn/build/toolchain/target_flags.gni
index 0af52a0..573e758 100644
--- a/src/llvm-project/llvm/utils/gn/build/toolchain/target_flags.gni
+++ b/src/llvm-project/llvm/utils/gn/build/toolchain/target_flags.gni
@@ -13,8 +13,11 @@
target_flags += [
"--target=$llvm_current_triple",
"--sysroot=$android_ndk_path/toolchains/llvm/prebuilt/linux-x86_64/sysroot",
- "-B$android_ndk_path/toolchains/llvm/prebuilt/linux-x86_64",
+ "--gcc-toolchain=$android_ndk_path/toolchains/llvm/prebuilt/linux-x86_64",
]
+ if (current_cpu != "arm") {
+ target_flags += [ "-rtlib=libgcc" ]
+ }
target_ldflags += [ "-static-libstdc++" ]
if (current_cpu == "arm") {
target_flags += [ "-march=armv7-a" ]
diff --git a/src/llvm-project/llvm/utils/gn/build/write_library_dependencies.py b/src/llvm-project/llvm/utils/gn/build/write_library_dependencies.py
index 4ab6c6e..747fe2b 100644
--- a/src/llvm-project/llvm/utils/gn/build/write_library_dependencies.py
+++ b/src/llvm-project/llvm/utils/gn/build/write_library_dependencies.py
@@ -22,7 +22,7 @@
const char *RequiredLibraries[84];
} AvailableComponents[84] = {
{ "aggressiveinstcombine", "LLVMAggressiveInstCombine", true, {"analysis", "core", "support", "transformutils"} },
-{ "all", nullptr, true, {"demangle", "support", "tablegen", "core", "fuzzmutate", "filecheck", "interfacestub", "irreader", "codegen", "selectiondag", "asmprinter", "mirparser", "globalisel", "binaryformat", "bitreader", "bitwriter", "bitstreamreader", "dwarflinker", "extensions", "frontendopenmp", "transformutils", "instrumentation", "aggressiveinstcombine", "instcombine", "scalaropts", "ipo", "vectorize", "hellonew", "objcarcopts", "coroutines", "cfguard", "linker", "analysis", "lto", "mc", "mcparser", "mcdisassembler", "mca", "object", "objectyaml", "option", "remarks", "debuginfodwarf", "debuginfogsym", "debuginfomsf", "debuginfocodeview", "debuginfopdb", "symbolize", "executionengine", "interpreter", "jitlink", "mcjit", "orcjit", "orcshared", "orctargetprocess", "runtimedyld", "target", "asmparser", "lineeditor", "profiledata", "coverage", "passes", "textapi", "dlltooldriver", "libdriver", "xray", "windowsmanifest"} },
+{ "all", nullptr, true, {"demangle", "support", "tablegen", "core", "fuzzmutate", "filecheck", "interfacestub", "irreader", "codegen", "selectiondag", "asmprinter", "mirparser", "globalisel", "binaryformat", "bitreader", "bitwriter", "bitstreamreader", "dwarflinker", "extensions", "frontendopenmp", "transformutils", "instrumentation", "aggressiveinstcombine", "instcombine", "scalaropts", "ipo", "vectorize", "objcarcopts", "coroutines", "cfguard", "linker", "analysis", "lto", "mc", "mcparser", "mcdisassembler", "mca", "object", "objectyaml", "option", "remarks", "debuginfodwarf", "debuginfogsym", "debuginfomsf", "debuginfocodeview", "debuginfopdb", "symbolize", "executionengine", "interpreter", "jitlink", "mcjit", "orcjit", "orcshared", "orctargetprocess", "runtimedyld", "target", "asmparser", "lineeditor", "profiledata", "coverage", "passes", "textapi", "dlltooldriver", "libdriver", "xray", "windowsmanifest"} },
{ "all-targets", nullptr, true, {} },
{ "analysis", "LLVMAnalysis", true, {"binaryformat", "core", "object", "profiledata", "support"} },
{ "asmparser", "LLVMAsmParser", true, {"binaryformat", "core", "support"} },
@@ -51,7 +51,6 @@
{ "frontendopenmp", "LLVMFrontendOpenMP", true, {"core", "support", "transformutils"} },
{ "fuzzmutate", "LLVMFuzzMutate", true, {"analysis", "bitreader", "bitwriter", "core", "scalaropts", "support", "target"} },
{ "globalisel", "LLVMGlobalISel", true, {"analysis", "codegen", "core", "mc", "selectiondag", "support", "target", "transformutils"} },
-{ "hellonew", "LLVMHelloNew", true, {"core", "support"} },
{ "instcombine", "LLVMInstCombine", true, {"analysis", "core", "support", "transformutils"} },
{ "instrumentation", "LLVMInstrumentation", true, {"analysis", "core", "mc", "support", "transformutils", "profiledata"} },
{ "interfacestub", "LLVMInterfaceStub", true, {"object", "support"} },
@@ -78,7 +77,7 @@
{ "orcjit", "LLVMOrcJIT", true, {"core", "executionengine", "jitlink", "object", "orcshared", "orctargetprocess", "mc", "passes", "runtimedyld", "support", "target", "transformutils"} },
{ "orcshared", "LLVMOrcShared", true, {"support"} },
{ "orctargetprocess", "LLVMOrcTargetProcess", true, {"orcshared", "support"} },
-{ "passes", "LLVMPasses", true, {"aggressiveinstcombine", "analysis", "core", "coroutines", "hellonew", "ipo", "instcombine", "objcarcopts", "scalaropts", "support", "target", "transformutils", "vectorize", "instrumentation"} },
+{ "passes", "LLVMPasses", true, {"aggressiveinstcombine", "analysis", "core", "coroutines", "ipo", "instcombine", "objcarcopts", "scalaropts", "support", "target", "transformutils", "vectorize", "instrumentation"} },
{ "profiledata", "LLVMProfileData", true, {"core", "support", "demangle"} },
{ "remarks", "LLVMRemarks", true, {"bitstreamreader", "support"} },
{ "runtimedyld", "LLVMRuntimeDyld", true, {"core", "mc", "object", "support"} },
diff --git a/src/llvm-project/llvm/utils/gn/secondary/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/BUILD.gn
index 43c5b8a..16b4c98 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/BUILD.gn
@@ -8,24 +8,24 @@
"//clang-tools-extra/test",
"//clang/test",
"//clang/tools/scan-build",
+ "//compiler-rt",
"//compiler-rt/include",
"//compiler-rt/lib/scudo",
"//lld/test",
"//llvm/test",
]
- if (current_os == "linux" || current_os == "mac") {
- deps += [ "//compiler-rt" ]
- }
if (current_os == "linux") {
deps += [
"//libcxx",
"//libcxxabi",
- "//libunwind",
]
}
if (current_os == "linux" || current_os == "android") {
deps += [ "//compiler-rt/test/hwasan" ]
}
+ if (current_os == "linux" || current_os == "mac") {
+ deps += [ "//libunwind" ]
+ }
testonly = true
}
@@ -76,6 +76,9 @@
group("llvm-objdump") {
deps = [ "//llvm/tools/llvm-objdump:symlinks" ]
}
+group("llvm-rc") {
+ deps = [ "//llvm/tools/llvm-rc:symlinks" ]
+}
group("llvm-readobj") {
deps = [ "//llvm/tools/llvm-readobj:symlinks" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn
index dff088d..4da3865 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/altera/BUILD.gn
@@ -13,8 +13,10 @@
]
sources = [
"AlteraTidyModule.cpp",
+ "IdDependentBackwardBranchCheck.cpp",
"KernelNameRestrictionCheck.cpp",
"SingleWorkItemBarrierCheck.cpp",
"StructPackAlignCheck.cpp",
+ "UnrollLoopsCheck.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn
index 200ea1d..259a030 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/bugprone/BUILD.gn
@@ -23,10 +23,12 @@
"CopyConstructorInitCheck.cpp",
"DanglingHandleCheck.cpp",
"DynamicStaticInitializersCheck.cpp",
+ "EasilySwappableParametersCheck.cpp",
"ExceptionEscapeCheck.cpp",
"FoldInitTypeCheck.cpp",
"ForwardDeclarationNamespaceCheck.cpp",
"ForwardingReferenceOverloadCheck.cpp",
+ "ImplicitWideningOfMultiplicationResultCheck.cpp",
"InaccurateEraseCheck.cpp",
"IncorrectRoundingsCheck.cpp",
"InfiniteLoopCheck.cpp",
@@ -65,6 +67,7 @@
"TooSmallLoopVariableCheck.cpp",
"UndefinedMemoryManipulationCheck.cpp",
"UndelegatedConstructorCheck.cpp",
+ "UnhandledExceptionAtNewCheck.cpp",
"UnhandledSelfAssignmentCheck.cpp",
"UnusedRaiiCheck.cpp",
"UnusedReturnValueCheck.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/concurrency/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/concurrency/BUILD.gn
index 09c61f3..fa078bd 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/concurrency/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/concurrency/BUILD.gn
@@ -15,5 +15,6 @@
sources = [
"ConcurrencyTidyModule.cpp",
"MtUnsafeCheck.cpp",
+ "ThreadCanceltypeAsynchronousCheck.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
index fa1e24d..89198c8 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/readability/BUILD.gn
@@ -18,7 +18,6 @@
"ContainerSizeEmptyCheck.cpp",
"ConvertMemberFunctionsToStatic.cpp",
"DeleteNullPointerCheck.cpp",
- "DeletedDefaultCheck.cpp",
"ElseAfterReturnCheck.cpp",
"FunctionCognitiveComplexityCheck.cpp",
"FunctionSizeCheck.cpp",
@@ -49,6 +48,7 @@
"StaticAccessedThroughInstanceCheck.cpp",
"StaticDefinitionInAnonymousNamespaceCheck.cpp",
"StringCompareCheck.cpp",
+ "SuspiciousCallArgumentCheck.cpp",
"UniqueptrDeleteReleaseCheck.cpp",
"UppercaseLiteralSuffixCheck.cpp",
"UseAnyOfAllOfCheck.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn
index 88a5195..44a3e5c 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn
@@ -14,6 +14,8 @@
values = [
"CLANGD_ENABLE_REMOTE=0",
"CLANGD_MALLOC_TRIM=1",
+ "CLANGD_TIDY_CHECKS=1",
+ "ENABLE_GRPC_REFLECTION=0",
]
if (clangd_build_xpc) {
values += [ "CLANGD_BUILD_XPC=1" ]
@@ -84,6 +86,8 @@
"DumpAST.cpp",
"ExpectedTypes.cpp",
"FS.cpp",
+ "FeatureModule.cpp",
+ "Features.cpp",
"FileDistance.cpp",
"FindSymbols.cpp",
"FindTarget.cpp",
@@ -92,8 +96,10 @@
"GlobalCompilationDatabase.cpp",
"HeaderSourceSwitch.cpp",
"Headers.cpp",
+ "HeuristicResolver.cpp",
"Hover.cpp",
"IncludeFixer.cpp",
+ "InlayHints.cpp",
"JSONTransport.cpp",
"ParsedAST.cpp",
"PathMapping.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/support/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/support/BUILD.gn
index 07d4e1e..e963847 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/support/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/support/BUILD.gn
@@ -15,6 +15,7 @@
"Logger.cpp",
"Markup.cpp",
"MemoryTree.cpp",
+ "Path.cpp",
"Shutdown.cpp",
"Threading.cpp",
"ThreadsafeFS.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn
index e6ea3b5..02ccf1d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/test/BUILD.gn
@@ -31,6 +31,7 @@
"CLANG_LIBS_DIR=", # needed only for shared builds
"CLANG_TOOLS_DIR=",
"CLANGD_ENABLE_REMOTE=0",
+ "CLANGD_TIDY_CHECKS=1",
"LLVM_HOST_TRIPLE=$llvm_current_triple",
"LLVM_LIT_TOOLS_DIR=", # Intentionally empty, matches cmake build.
"LLVM_TOOLS_DIR=" + rebase_path("$root_out_dir/bin"),
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn
index 26cc183..7f53e0e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/unittests/BUILD.gn
@@ -65,6 +65,7 @@
"DumpASTTests.cpp",
"ExpectedTypeTest.cpp",
"FSTests.cpp",
+ "FeatureModulesTests.cpp",
"FileDistanceTests.cpp",
"FileIndexTests.cpp",
"FindSymbolsTests.cpp",
@@ -77,7 +78,9 @@
"HoverTests.cpp",
"IndexActionTests.cpp",
"IndexTests.cpp",
+ "InlayHintTests.cpp",
"JSONTransportTests.cpp",
+ "LSPBinderTests.cpp",
"LSPClient.cpp",
"LoggerTests.cpp",
"ModulesTests.cpp",
@@ -102,6 +105,7 @@
"TestIndex.cpp",
"TestTU.cpp",
"TestWorkspace.cpp",
+ "TidyProviderTests.cpp",
"TypeHierarchyTests.cpp",
"URITests.cpp",
"XRefsTests.cpp",
@@ -110,6 +114,7 @@
"support/FunctionTests.cpp",
"support/MarkupTests.cpp",
"support/MemoryTreeTests.cpp",
+ "support/PathTests.cpp",
"support/TestTracer.cpp",
"support/ThreadingTests.cpp",
"support/TraceTests.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/xpc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/xpc/BUILD.gn
index 0d37539..921e0db 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/xpc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/clangd/xpc/BUILD.gn
@@ -16,6 +16,7 @@
deps = [
":conversions",
"//clang-tools-extra/clangd",
+ "//clang-tools-extra/clangd:features",
"//clang-tools-extra/clangd/support",
"//llvm/lib/Support",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/test/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/test/BUILD.gn
index e8b1f15..136d6b6 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/test/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang-tools-extra/test/BUILD.gn
@@ -1,6 +1,5 @@
import("//clang-tools-extra/clang-tidy/enable.gni")
import("//clang/lib/StaticAnalyzer/Frontend/enable.gni")
-import("//clang/tools/libclang/include_clang_tools_extra.gni")
import("//llvm/triples.gni")
import("//llvm/utils/gn/build/write_cmake_config.gni")
import("clang_tools_extra_lit_site_cfg_files.gni")
@@ -44,12 +43,6 @@
} else {
extra_values += [ "CLANG_TIDY_ENABLE_STATIC_ANALYZER=0" ]
}
-
- if (libclang_include_clang_tools_extra) {
- extra_values += [ "LIBCLANG_INCLUDE_CLANG_TOOLS_EXTRA=1" ]
- } else {
- extra_values += [ "LIBCLANG_INCLUDE_CLANG_TOOLS_EXTRA=0" ]
- }
}
write_lit_config("lit_unit_site_cfg") {
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn
index 8db5b99..6b5ab7c 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Basic/BUILD.gn
@@ -63,29 +63,17 @@
# Attributes
clang_tablegen("AttrList") {
- args = [
- "-gen-clang-attr-list",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-list" ]
td_file = "Attr.td"
}
clang_tablegen("AttrSubMatchRulesList") {
- args = [
- "-gen-clang-attr-subject-match-rule-list",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-subject-match-rule-list" ]
td_file = "Attr.td"
}
clang_tablegen("AttrHasAttributeImpl") {
- args = [
- "-gen-clang-attr-has-attribute-impl",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-has-attribute-impl" ]
td_file = "Attr.td"
}
@@ -158,3 +146,15 @@
args = [ "-gen-arm-cde-builtin-aliases" ]
td_file = "arm_cde.td"
}
+
+# RISC-V
+
+clang_tablegen("riscv_vector_builtins") {
+ args = [ "-gen-riscv-vector-builtins" ]
+ td_file = "riscv_vector.td"
+}
+
+clang_tablegen("riscv_vector_builtin_cg") {
+ args = [ "-gen-riscv-vector-builtin-codegen" ]
+ td_file = "riscv_vector.td"
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
index 66c5a17..aa3e40a 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Config/BUILD.gn
@@ -4,11 +4,6 @@
import("//llvm/utils/gn/build/write_cmake_config.gni")
import("//llvm/version.gni")
-config("Config_config") {
- visibility = [ ":Config" ]
- include_dirs = [ "$target_gen_dir/clang/include" ]
-}
-
write_cmake_config("Config") {
input = "config.h.cmake"
output = "$target_gen_dir/config.h"
@@ -70,7 +65,4 @@
} else {
values += [ "HOST_LINK_VERSION=" ]
}
-
- # Let targets depending on this find the generated file.
- public_configs = [ ":Config_config" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Parse/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Parse/BUILD.gn
index 24aaaea..53ba5e6 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Parse/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Parse/BUILD.gn
@@ -1,19 +1,11 @@
import("//clang/utils/TableGen/clang_tablegen.gni")
clang_tablegen("AttrParserStringSwitches") {
- args = [
- "-gen-clang-attr-parser-string-switches",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-parser-string-switches" ]
td_file = "../Basic/Attr.td"
}
clang_tablegen("AttrSubMatchRulesParserStringSwitches") {
- args = [
- "-gen-clang-attr-subject-match-rules-parser-string-switches",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-subject-match-rules-parser-string-switches" ]
td_file = "../Basic/Attr.td"
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn
index 1f41189..097bcce 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Sema/BUILD.gn
@@ -1,46 +1,26 @@
import("//clang/utils/TableGen/clang_tablegen.gni")
clang_tablegen("AttrTemplateInstantiate") {
- args = [
- "-gen-clang-attr-template-instantiate",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-template-instantiate" ]
td_file = "../Basic/Attr.td"
}
clang_tablegen("AttrParsedAttrList") {
- args = [
- "-gen-clang-attr-parsed-attr-list",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-parsed-attr-list" ]
td_file = "../Basic/Attr.td"
}
clang_tablegen("AttrParsedAttrKinds") {
- args = [
- "-gen-clang-attr-parsed-attr-kinds",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-parsed-attr-kinds" ]
td_file = "../Basic/Attr.td"
}
clang_tablegen("AttrSpellingListIndex") {
- args = [
- "-gen-clang-attr-spelling-index",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-spelling-index" ]
td_file = "../Basic/Attr.td"
}
clang_tablegen("AttrParsedAttrImpl") {
- args = [
- "-gen-clang-attr-parsed-attr-impl",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-parsed-attr-impl" ]
td_file = "../Basic/Attr.td"
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Serialization/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Serialization/BUILD.gn
index bf90e06..e221de0 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Serialization/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/include/clang/Serialization/BUILD.gn
@@ -1,19 +1,11 @@
import("//clang/utils/TableGen/clang_tablegen.gni")
clang_tablegen("AttrPCHRead") {
- args = [
- "-gen-clang-attr-pch-read",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-pch-read" ]
td_file = "../Basic/Attr.td"
}
clang_tablegen("AttrPCHWrite") {
- args = [
- "-gen-clang-attr-pch-write",
- "-I",
- rebase_path("../..", root_out_dir),
- ]
+ args = [ "-gen-clang-attr-pch-write" ]
td_file = "../Basic/Attr.td"
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Analysis/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Analysis/BUILD.gn
index 49ec784..444308c 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Analysis/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Analysis/BUILD.gn
@@ -26,6 +26,7 @@
"ExprMutationAnalyzer.cpp",
"IssueHash.cpp",
"LiveVariables.cpp",
+ "MacroExpansionContext.cpp",
"ObjCNoReturn.cpp",
"PathDiagnostic.cpp",
"PostOrderCFGView.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
index d6e322f..3556746 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn
@@ -29,7 +29,16 @@
"//clang/include/clang/Basic:arm_sve_builtins",
"//clang/include/clang/Basic:arm_sve_typeflags",
"//clang/include/clang/Basic:diags_tablegen",
+ "//clang/include/clang/Basic:riscv_vector_builtins",
"//clang/include/clang/Basic:version",
+
+ # public_dep because public header AttributeCommonInfo.h includes generated
+ # AttrParsedAttrList.inc.
+ "//clang/include/clang/Sema:AttrParsedAttrList",
+
+ # public_dep because public header OpenMPKinds.h includes generated
+ # OMP.h.inc.
+ "//llvm/include/llvm/Frontend/OpenMP:public_tablegen",
]
deps = [
":write_vcsversion",
@@ -37,9 +46,9 @@
"//clang/include/clang/Basic:arm_fp16",
"//clang/include/clang/Basic:arm_neon",
"//clang/include/clang/Config",
+ "//clang/include/clang/Sema:AttrParsedAttrKinds",
+ "//clang/include/clang/Sema:AttrSpellingListIndex",
"//llvm/include/llvm/Config:llvm-config",
- "//llvm/lib/IR",
- "//llvm/lib/MC",
"//llvm/lib/Support",
]
include_dirs = [ "." ]
@@ -49,6 +58,7 @@
"CharInfo.cpp",
"CodeGenOptions.cpp",
"Cuda.cpp",
+ "DarwinSDKInfo.cpp",
"Diagnostic.cpp",
"DiagnosticIDs.cpp",
"DiagnosticOptions.cpp",
@@ -60,12 +70,12 @@
"LangOptions.cpp",
"LangStandards.cpp",
"Module.cpp",
+ "NoSanitizeList.cpp",
"ObjCRuntime.cpp",
"OpenCLOptions.cpp",
"OpenMPKinds.cpp",
"OperatorPrecedence.cpp",
"ProfileList.cpp",
- "SanitizerBlacklist.cpp",
"SanitizerSpecialCaseList.cpp",
"Sanitizers.cpp",
"SourceLocation.cpp",
@@ -83,6 +93,7 @@
"Targets/Hexagon.cpp",
"Targets/Lanai.cpp",
"Targets/Le64.cpp",
+ "Targets/M68k.cpp",
"Targets/MSP430.cpp",
"Targets/Mips.cpp",
"Targets/NVPTX.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/CodeGen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/CodeGen/BUILD.gn
index b7ecb64..bdc0b91 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/CodeGen/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/CodeGen/BUILD.gn
@@ -5,6 +5,7 @@
"//clang/include/clang/Basic:arm_cde_builtin_cg",
"//clang/include/clang/Basic:arm_mve_builtin_cg",
"//clang/include/clang/Basic:arm_sve_builtin_cg",
+ "//clang/include/clang/Basic:riscv_vector_builtin_cg",
"//clang/lib/AST",
"//clang/lib/Analysis",
"//clang/lib/Basic",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn
index ab29e6b..73cdf4a 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Driver/BUILD.gn
@@ -30,7 +30,6 @@
sources = [
"Action.cpp",
"Compilation.cpp",
- "DarwinSDKInfo.cpp",
"Distro.cpp",
"Driver.cpp",
"DriverOptions.cpp",
@@ -43,10 +42,12 @@
"ToolChain.cpp",
"ToolChains/AIX.cpp",
"ToolChains/AMDGPU.cpp",
+ "ToolChains/AMDGPUOpenMP.cpp",
"ToolChains/AVR.cpp",
"ToolChains/Ananas.cpp",
"ToolChains/Arch/AArch64.cpp",
"ToolChains/Arch/ARM.cpp",
+ "ToolChains/Arch/M68k.cpp",
"ToolChains/Arch/Mips.cpp",
"ToolChains/Arch/PPC.cpp",
"ToolChains/Arch/RISCV.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn
index b13b6e5..b169d14 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Headers/BUILD.gn
@@ -43,7 +43,14 @@
output_name = "arm_cde.h"
}
-copy("arm_headers") {
+# Generate riscv_vector.h
+clang_tablegen("riscv_vector") {
+ args = [ "-gen-riscv-vector-header" ]
+ td_file = "//clang/include/clang/Basic/riscv_vector.td"
+ output_name = "riscv_vector.h"
+}
+
+copy("tablegen_headers") {
visibility = [ ":Headers" ]
deps = [
":arm_bf16",
@@ -52,6 +59,7 @@
":arm_mve",
":arm_neon",
":arm_sve",
+ ":riscv_vector",
]
sources = []
foreach(dep, deps) {
@@ -61,7 +69,7 @@
}
copy("Headers") {
- deps = [ ":arm_headers" ]
+ deps = [ ":tablegen_headers" ]
sources = [
"__clang_cuda_builtin_vars.h",
@@ -119,6 +127,7 @@
"avxvnniintrin.h",
"bmi2intrin.h",
"bmiintrin.h",
+ "builtins.h",
"cet.h",
"cetintrin.h",
"cldemoteintrin.h",
@@ -137,9 +146,13 @@
"fmaintrin.h",
"fxsrintrin.h",
"gfniintrin.h",
+ "hexagon_circ_brev_intrinsics.h",
+ "hexagon_protos.h",
+ "hexagon_types.h",
"hresetintrin.h",
"htmintrin.h",
"htmxlintrin.h",
+ "hvx_hexagon_protos.h",
"ia32intrin.h",
"immintrin.h",
"intrin.h",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Interpreter/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Interpreter/BUILD.gn
new file mode 100644
index 0000000..8f686f2
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Interpreter/BUILD.gn
@@ -0,0 +1,29 @@
+static_library("Interpreter") {
+ output_name = "clangInterpreter"
+ configs += [ "//llvm/utils/gn/build:clang_code" ]
+ deps = [
+ "//clang/lib/AST",
+ "//clang/lib/Analysis",
+ "//clang/lib/Basic",
+ "//clang/lib/CodeGen",
+ "//clang/lib/Driver",
+ "//clang/lib/Edit",
+ "//clang/lib/Frontend",
+ "//clang/lib/FrontendTool",
+ "//clang/lib/Lex",
+ "//clang/lib/Parse",
+ "//clang/lib/Sema",
+ "//clang/lib/Serialization",
+ "//llvm/lib/ExecutionEngine/Orc",
+ "//llvm/lib/IR",
+ "//llvm/lib/Option",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target",
+ "//llvm/lib/Target:NativeTarget",
+ ]
+ sources = [
+ "IncrementalExecutor.cpp",
+ "IncrementalParser.cpp",
+ "Interpreter.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
index 8ec471e..93d6b7d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Sema/BUILD.gn
@@ -25,6 +25,7 @@
"//clang/lib/Edit",
"//clang/lib/Lex",
"//llvm/lib/Frontend/OpenMP",
+ "//llvm/lib/MC",
"//llvm/lib/Support",
]
sources = [
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Core/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Core/BUILD.gn
index c16c37d..50e174a 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Core/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/StaticAnalyzer/Core/BUILD.gn
@@ -29,7 +29,7 @@
"CommonBugCategories.cpp",
"ConstraintManager.cpp",
"CoreEngine.cpp",
- "DynamicSize.cpp",
+ "DynamicExtent.cpp",
"DynamicType.cpp",
"Environment.cpp",
"ExplodedGraph.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn
index 5bc4241..2be7255 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/BUILD.gn
@@ -1,7 +1,21 @@
+# FIXME: The cmake build runs DumpTool:clang-ast-dump to generate a json
+# file and feeds it into this step in non-debug builds or if an option is set.
+action("node_introspection_inc") {
+ script = "DumpTool/generate_cxx_src_locs.py"
+ outputs = [ "$target_gen_dir/clang/Tooling/NodeIntrospection.inc" ]
+ sources = [ "EmptyNodeIntrospection.inc.in" ]
+ args = [
+ "--use-empty-implementation=1",
+ "--empty-implementation=" + rebase_path(sources[0], root_build_dir),
+ "--output-file=" + rebase_path(outputs[0], root_build_dir),
+ ]
+}
+
static_library("Tooling") {
output_name = "clangTooling"
configs += [ "//llvm/utils/gn/build:clang_code" ]
deps = [
+ ":node_introspection_inc",
"//clang/include/clang/Driver:Options",
"//clang/lib/AST",
"//clang/lib/ASTMatchers",
@@ -13,6 +27,7 @@
"//clang/lib/Rewrite",
"//clang/lib/Tooling/Core",
]
+ include_dirs = [ target_gen_dir ]
sources = [
"AllTUsExecution.cpp",
"ArgumentsAdjusters.cpp",
@@ -25,6 +40,7 @@
"GuessTargetAndModeCompilationDatabase.cpp",
"InterpolatingCompilationDatabase.cpp",
"JSONCompilationDatabase.cpp",
+ "NodeIntrospection.cpp",
"Refactoring.cpp",
"RefactoringCallbacks.cpp",
"StandaloneExecution.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DependencyScanning/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DependencyScanning/BUILD.gn
index 6bae1f9..0d01876 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DependencyScanning/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DependencyScanning/BUILD.gn
@@ -4,6 +4,7 @@
deps = [
"//clang/lib/AST",
"//clang/lib/Basic",
+ "//clang/lib/CodeGen",
"//clang/lib/Driver",
"//clang/lib/Frontend",
"//clang/lib/FrontendTool",
@@ -13,6 +14,7 @@
"//clang/lib/Tooling",
"//llvm/lib/IR",
"//llvm/lib/Support",
+ "//llvm/lib/Target:TargetsToBuild",
]
sources = [
"DependencyScanningFilesystem.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DumpTool/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DumpTool/BUILD.gn
new file mode 100644
index 0000000..7d9d211
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/lib/Tooling/DumpTool/BUILD.gn
@@ -0,0 +1,20 @@
+executable("clang-ast-dump") {
+ configs += [ "//llvm/utils/gn/build:clang_code" ]
+ deps = [
+ "//clang/lib/AST",
+ "//clang/lib/ASTMatchers",
+ "//clang/lib/Basic",
+ "//clang/lib/Driver",
+ "//clang/lib/Format",
+ "//clang/lib/Frontend",
+ "//clang/lib/Lex",
+ "//clang/lib/Rewrite",
+ "//clang/lib/Serialization",
+ "//clang/lib/Tooling/Core",
+ ]
+
+ sources = [
+ "ASTSrcLocProcessor.cpp",
+ "ClangSrcLocDump.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/test/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/test/BUILD.gn
index bda694b..f819b95 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/test/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/test/BUILD.gn
@@ -56,8 +56,10 @@
# that's also read here -- but that should happen after multi-toolchain
# builds exist, to make sure it's a toolchain var.
"CMAKE_CXX_COMPILER=c++",
+ "CMAKE_C_COMPILER=cc",
"ENABLE_BACKTRACES=1",
- "LLVM_ENABLE_NEW_PASS_MANAGER=0",
+ "LLVM_ENABLE_NEW_PASS_MANAGER=1",
+ "LLVM_EXTERNAL_LIT=",
"LLVM_HOST_TRIPLE=$llvm_current_triple",
"LLVM_LIT_TOOLS_DIR=", # Intentionally empty, matches cmake build.
"LLVM_USE_SANITIZER=",
@@ -102,10 +104,19 @@
}
if (host_os == "win") {
- extra_values += [ "LLVM_ENABLE_PLUGINS=0" ]
+ extra_values += [
+ # See comment for Windows solink in llvm/utils/gn/build/toolchain/BUILD.gn
+ "CMAKE_LIBRARY_OUTPUT_DIRECTORY=" + rebase_path("$root_out_dir/bin", dir),
+ "LLVM_ENABLE_PLUGINS=0",
+ "LLVM_LIT_ERRC_MESSAGES=no such file or directory;is a directory;" +
+ "invalid argument;permission denied",
+ ]
} else {
- # FIXME: Analysis/plugins need global -fPIC
- extra_values += [ "LLVM_ENABLE_PLUGINS=0" ]
+ extra_values += [
+ "CMAKE_LIBRARY_OUTPUT_DIRECTORY=" + rebase_path("$root_out_dir/lib", dir),
+ "LLVM_ENABLE_PLUGINS=0", # FIXME: Analysis/plugins need global -fPIC
+ "LLVM_LIT_ERRC_MESSAGES=",
+ ]
}
if (llvm_enable_threads) {
@@ -138,6 +149,7 @@
"//clang/tools/clang-offload-bundler",
"//clang/tools/clang-refactor",
"//clang/tools/clang-rename",
+ "//clang/tools/clang-repl",
"//clang/tools/clang-scan-deps",
"//clang/tools/diagtool",
"//clang/tools/driver:symlinks",
@@ -160,6 +172,7 @@
"//llvm/tools/llvm-objcopy:symlinks",
"//llvm/tools/llvm-objdump:symlinks",
"//llvm/tools/llvm-profdata",
+ "//llvm/tools/llvm-rc:symlinks",
"//llvm/tools/llvm-readobj:symlinks",
"//llvm/tools/llvm-symbolizer:symlinks",
"//llvm/tools/opt",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn
index cc2e46d..39a92f6 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-check/BUILD.gn
@@ -8,6 +8,7 @@
"//clang/lib/Frontend/Rewrite",
"//clang/lib/StaticAnalyzer/Frontend",
"//clang/lib/Tooling",
+ "//clang/lib/Tooling/Syntax",
"//llvm/lib/Option",
"//llvm/lib/Support",
"//llvm/lib/Target:TargetsToBuild",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn
index b2a6e8d..d1a83fa 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn
@@ -11,6 +11,8 @@
"//clang/lib/AST/",
"//clang/lib/Frontend/",
"//clang/lib/Sema/",
+ "//llvm/lib/IR",
+ "//llvm/lib/MC",
]
sources = [ "ClangFormat.cpp" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-repl/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-repl/BUILD.gn
new file mode 100644
index 0000000..ebc27f3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/clang-repl/BUILD.gn
@@ -0,0 +1,15 @@
+executable("clang-repl") {
+ configs += [ "//llvm/utils/gn/build:clang_code" ]
+ deps = [
+ "//clang/lib/Basic",
+ "//clang/lib/Interpreter",
+ "//clang/lib/Tooling",
+ "//llvm/lib/ExecutionEngine/Orc",
+ "//llvm/lib/IR",
+ "//llvm/lib/LineEditor",
+ "//llvm/lib/Option",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target:TargetsToBuild",
+ ]
+ sources = [ "ClangRepl.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn
index a91ee25..24a95e1 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/driver/BUILD.gn
@@ -86,7 +86,7 @@
# clang. This is different from the CMake build, which requires devs to
# explicitly build the "libcxx" target (which also needlessly compiles the
# libcxx sources) to get a working compiler.
- deps += [ "//libcxx/include" ]
+ deps += [ "//libcxx/include:copy_headers" ]
}
sources = [
"cc1_main.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
index 4cef8fa..556c878 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/BUILD.gn
@@ -1,10 +1,9 @@
import("//clang/lib/ARCMigrate/enable.gni")
-import("//clang/tools/libclang/include_clang_tools_extra.gni")
+import("//llvm/utils/gn/build/symbol_exports.gni")
import("//llvm/version.gni")
# This build file is just enough to get check-clang to pass, it's missing
# several things from the CMake build:
-# - using libclang.exports
# - a build target copying the Python bindings
# - the GN linux build always builds without -fPIC (as if LLVM_ENABLE_PIC=OFF
# in the CMake build), so libclang is always a static library on linux
@@ -15,6 +14,21 @@
# ELF targets need -fPIC to build shared libs but they aren't on by default.
# For now, make libclang a static lib there.
libclang_target_type = "static_library"
+} else {
+ action("linker_script_to_exports") {
+ script = "linker-script-to-export-list.py"
+ inputs = [ "libclang.map" ]
+ outputs = [ "$target_gen_dir/libclang.exports" ]
+ args = [
+ rebase_path(inputs[0], root_build_dir),
+ rebase_path(outputs[0], root_build_dir),
+ ]
+ }
+
+ symbol_exports("exports") {
+ deps = [ ":linker_script_to_exports" ]
+ exports_file = "$target_gen_dir/libclang.exports"
+ }
}
target(libclang_target_type, "libclang") {
@@ -38,18 +52,12 @@
deps += [ "//clang/lib/ARCMigrate" ]
}
- defines = []
-
- # FIXME: Once the GN build has a way to select which bits to build,
- # only include this dependency if clang-tools-extra is part of the build.
- if (libclang_include_clang_tools_extra) {
- defines += [ "CLANG_TOOL_EXTRA_BUILD" ]
- deps += [
- "//clang-tools-extra/clang-include-fixer/plugin",
- "//clang-tools-extra/clang-tidy/plugin",
- ]
+ if (libclang_target_type == "shared_library") {
+ deps += [ ":exports" ]
}
+ defines = []
+
if (host_os == "win") {
defines += [ "_CINDEX_LIB_" ]
}
@@ -98,6 +106,4 @@
"-Wl,-rpath,@loader_path/../lib",
]
}
-
- # FIXME: Use libclang.exports
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/include_clang_tools_extra.gni b/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/include_clang_tools_extra.gni
deleted file mode 100644
index 0beaa37..0000000
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/tools/libclang/include_clang_tools_extra.gni
+++ /dev/null
@@ -1,4 +0,0 @@
-declare_args() {
- # Whether to include code from clang-tools-extra in libclang.
- libclang_include_clang_tools_extra = false
-}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn
index f25ead0..127542d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/AST/BUILD.gn
@@ -18,6 +18,7 @@
"ASTImporterFixtures.cpp",
"ASTImporterGenericRedeclTest.cpp",
"ASTImporterODRStrategiesTest.cpp",
+ "ASTImporterObjCTest.cpp",
"ASTImporterTest.cpp",
"ASTImporterVisibilityTest.cpp",
"ASTTraverserTest.cpp",
@@ -37,5 +38,6 @@
"SourceLocationTest.cpp",
"StmtPrinterTest.cpp",
"StructuralEquivalenceTest.cpp",
+ "TypePrinterTest.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Analysis/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Analysis/BUILD.gn
index f3d2c54..5e104ed 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Analysis/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Analysis/BUILD.gn
@@ -16,5 +16,6 @@
"CFGTest.cpp",
"CloneDetectionTest.cpp",
"ExprMutationAnalyzerTest.cpp",
+ "MacroExpansionContextTest.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/BUILD.gn
index 23f5d2d..319205b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/BUILD.gn
@@ -12,6 +12,8 @@
"Format:FormatTests",
"Frontend:FrontendTests",
"Index:IndexTests",
+ "Interpreter:ClangReplInterpreterTests",
+ "Introspection:IntrospectionTests",
"Lex:LexTests",
"Rename:ClangRenameTests",
"Rewrite:RewriteTests",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Basic/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Basic/BUILD.gn
index 9b17cb1..aea01ec 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Basic/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Basic/BUILD.gn
@@ -9,10 +9,12 @@
]
sources = [
"CharInfoTest.cpp",
+ "DarwinSDKInfoTest.cpp",
"DiagnosticTest.cpp",
"FileEntryTest.cpp",
"FileManagerTest.cpp",
"LineOffsetMappingTest.cpp",
+ "SanitizersTest.cpp",
"SourceManagerTest.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/CodeGen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/CodeGen/BUILD.gn
index 09d296d..54a0600 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/CodeGen/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/CodeGen/BUILD.gn
@@ -16,7 +16,6 @@
"BufferSourceTest.cpp",
"CheckTargetFeaturesTest.cpp",
"CodeGenExternalTest.cpp",
- "IncrementalProcessingTest.cpp",
"TBAAMetadataTest.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Format/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Format/BUILD.gn
index b5f50a6..b5632ce 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Format/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Format/BUILD.gn
@@ -17,6 +17,7 @@
"FormatTestComments.cpp",
"FormatTestJS.cpp",
"FormatTestJava.cpp",
+ "FormatTestJson.cpp",
"FormatTestObjC.cpp",
"FormatTestProto.cpp",
"FormatTestRawStrings.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Interpreter/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Interpreter/BUILD.gn
new file mode 100644
index 0000000..26d2e2c
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Interpreter/BUILD.gn
@@ -0,0 +1,16 @@
+import("//llvm/utils/unittest/unittest.gni")
+
+unittest("ClangReplInterpreterTests") {
+ configs += [ "//llvm/utils/gn/build:clang_code" ]
+ deps = [
+ "//clang/lib/AST",
+ "//clang/lib/Basic",
+ "//clang/lib/Frontend",
+ "//clang/lib/Interpreter",
+ "//llvm/lib/IR",
+ ]
+ sources = [
+ "IncrementalProcessingTest.cpp",
+ "InterpreterTest.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Introspection/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Introspection/BUILD.gn
new file mode 100644
index 0000000..cac9b01
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Introspection/BUILD.gn
@@ -0,0 +1,19 @@
+import("//llvm/utils/unittest/unittest.gni")
+
+unittest("IntrospectionTests") {
+ configs += [ "//llvm/utils/gn/build:clang_code" ]
+ deps = [
+ "//clang/lib/AST",
+ "//clang/lib/ASTMatchers",
+ "//clang/lib/Basic",
+ "//clang/lib/Frontend",
+ "//clang/lib/Serialization",
+ "//clang/lib/Tooling",
+ "//llvm/lib/Support",
+ "//llvm/lib/Testing/Support",
+ ]
+
+ defines = [ "SKIP_INTROSPECTION_GENERATION" ]
+
+ sources = [ "IntrospectionTest.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Serialization/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Serialization/BUILD.gn
index ca29912..508f5e2 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Serialization/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Serialization/BUILD.gn
@@ -5,11 +5,15 @@
deps = [
"//clang/lib/AST",
"//clang/lib/Basic",
+ "//clang/lib/Frontend",
"//clang/lib/Lex",
"//clang/lib/Sema",
"//clang/lib/Serialization",
"//llvm/lib/Bitcode/Reader",
"//llvm/lib/Support",
]
- sources = [ "InMemoryModuleCacheTest.cpp" ]
+ sources = [
+ "InMemoryModuleCacheTest.cpp",
+ "ModuleCacheTest.cpp",
+ ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/StaticAnalyzer/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/StaticAnalyzer/BUILD.gn
index dcd3fa8..b82b83d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/StaticAnalyzer/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/StaticAnalyzer/BUILD.gn
@@ -12,12 +12,15 @@
]
sources = [
"AnalyzerOptionsTest.cpp",
+ "BugReportInterestingnessTest.cpp",
"CallDescriptionTest.cpp",
"CallEventTest.cpp",
"FalsePositiveRefutationBRVisitorTest.cpp",
"ParamRegionTest.cpp",
"RangeSetTest.cpp",
"RegisterCustomCheckersTest.cpp",
+ "SValTest.cpp",
+ "StoreTest.cpp",
"SymbolReaperTest.cpp",
"TestReturnValueUnderConstruction.cpp",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn
index 0921508..c442336 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/unittests/Tooling/BUILD.gn
@@ -13,6 +13,7 @@
"//clang/lib/Rewrite",
"//clang/lib/Tooling",
"//clang/lib/Tooling/Core",
+ "//clang/lib/Tooling/DependencyScanning",
"//clang/lib/Tooling/Refactoring",
"//clang/lib/Tooling/Transformer",
"//llvm/lib/Support",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/BUILD.gn
index 860f2b8..c94f76a 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/BUILD.gn
@@ -21,6 +21,7 @@
"ClangTypeNodesEmitter.cpp",
"MveEmitter.cpp",
"NeonEmitter.cpp",
+ "RISCVVEmitter.cpp",
"SveEmitter.cpp",
"TableGen.cpp",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/clang_tablegen.gni b/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/clang_tablegen.gni
index 4dd28ff..1231a1d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/clang_tablegen.gni
+++ b/src/llvm-project/llvm/utils/gn/secondary/clang/utils/TableGen/clang_tablegen.gni
@@ -1,9 +1,9 @@
-# This file introduces a templates for running clang-tblgen.
+# This file introduces a template for running clang-tblgen.
#
# Parameters:
#
# args (required)
-# [list of strings] Flags to pass to llvm-tblgen.
+# [list of strings] Flags to pass to clang-tblgen.
#
# output_name (optional)
# Basename of the generated output file.
@@ -36,7 +36,7 @@
args = [
"-I",
- rebase_path("//clang/include", root_out_dir),
+ rebase_path("//clang/include", root_build_dir),
] + invoker.args
tblgen_target = "//clang/utils/TableGen:clang-tblgen"
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/BUILD.gn
index af23e33..6d7b54f 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/BUILD.gn
@@ -5,7 +5,11 @@
# In the GN build, compiler-rt is always built by just-built clang and lld.
# FIXME: For macOS and iOS builds, depend on lib in all needed target arch
# toolchains and then lipo them together for the final output.
-supported_toolchains = [ "//llvm/utils/gn/build/toolchain:stage2_unix" ]
+if (current_os == "win") {
+ supported_toolchains = [ "//llvm/utils/gn/build/toolchain:stage2_win" ]
+} else {
+ supported_toolchains = [ "//llvm/utils/gn/build/toolchain:stage2_unix" ]
+}
if (android_ndk_path != "") {
supported_toolchains += [
"//llvm/utils/gn/build/toolchain:stage2_android_aarch64",
@@ -20,8 +24,7 @@
# FIXME: Do this only if a gn arg compiler_rt_enable_ios is set?
# That would match the cmake build.
- # iOS SDKs aren't available in the commandline tools SDK.
- if (host_os == "mac" && !mac_use_commandline_tools_sdk) {
+ if (host_os == "mac" && have_ios_sdks) {
if (llvm_build_AArch64) {
deps += [ "//compiler-rt/lib/builtins(//llvm/utils/gn/build/toolchain:stage2_ios_aarch64)" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/BUILD.gn
index 7133d9d..43bc7fd 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/BUILD.gn
@@ -1,7 +1,18 @@
group("lib") {
- deps = [
- "//compiler-rt/lib/asan",
- "//compiler-rt/lib/builtins",
- "//compiler-rt/lib/profile",
- ]
+ deps = [ "//compiler-rt/lib/profile" ]
+ if (current_os == "linux") {
+ deps += [ "//compiler-rt/lib/msan" ]
+ }
+ if (current_os == "linux" || current_os == "android") {
+ deps += [ "//compiler-rt/lib/ubsan_minimal" ]
+ }
+ if (current_os != "win") {
+ deps += [
+ "//compiler-rt/lib/asan",
+ "//compiler-rt/lib/builtins",
+ ]
+ if (current_cpu == "x64" || current_cpu == "arm64") {
+ deps += [ "//compiler-rt/lib/tsan" ]
+ }
+ }
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn
index 1f754d0..3f679c9 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/asan/BUILD.gn
@@ -28,7 +28,6 @@
"//compiler-rt/lib/interception:sources",
"//compiler-rt/lib/lsan:common_sources",
"//compiler-rt/lib/sanitizer_common:sources",
- "//compiler-rt/lib/ubsan:cxx_sources",
"//compiler-rt/lib/ubsan:sources",
]
@@ -37,7 +36,10 @@
configs -= [ "//llvm/utils/gn/build:thin_archive" ]
deps += [ ":asan_cxx" ]
} else {
- deps += [ ":cxx_sources" ]
+ deps += [
+ ":cxx_sources",
+ "//compiler-rt/lib/ubsan:cxx_sources",
+ ]
defines = [ "ASAN_DYNAMIC" ]
}
@@ -72,11 +74,9 @@
"asan_lock.h",
"asan_mac.cpp",
"asan_malloc_linux.cpp",
- "asan_malloc_local.h",
"asan_malloc_mac.cpp",
"asan_malloc_win.cpp",
"asan_mapping.h",
- "asan_mapping_myriad.h",
"asan_memory_profile.cpp",
"asan_poisoning.cpp",
"asan_poisoning.h",
@@ -85,7 +85,6 @@
"asan_premap_shadow.h",
"asan_report.cpp",
"asan_report.h",
- "asan_rtems.cpp",
"asan_rtl.cpp",
"asan_scariness_score.h",
"asan_shadow_setup.cpp",
@@ -118,7 +117,7 @@
# FIXME: add_sanitizer_rt_version_list (cf hwasan)
# FIXME: need libclang_rt.asan*.a.syms?
# FIXME: windows flags (-Zl -nodefaultlibs)
- # FIXME: asan_blacklist.txt
+ # FIXME: asan_ignorelist.txt
if (target_os == "android") {
ldflags = [ "-Wl,-z,global" ]
@@ -183,7 +182,10 @@
output_name = "clang_rt.asan_cxx$crt_current_target_suffix"
complete_static_lib = true
configs -= [ "//llvm/utils/gn/build:thin_archive" ]
- deps = [ ":cxx_sources" ]
+ deps = [
+ ":cxx_sources",
+ "//compiler-rt/lib/ubsan:cxx_sources",
+ ]
}
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn
index 4f07382..ef1251b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/builtins/BUILD.gn
@@ -429,8 +429,8 @@
if (current_cpu == "arm64") {
sources -= [ "fp_mode.c" ]
sources += [
- "cpu_model.c",
"aarch64/fp_mode.c",
+ "cpu_model.c",
]
if (current_os == "mingw") {
sources += [ "aarch64/chkstk.S" ]
@@ -486,6 +486,12 @@
]
}
+ if (current_cpu == "riscv" || current_cpu == "riscv64") {
+ sources += [
+ "riscv/restore.S",
+ "riscv/save.S",
+ ]
+ }
if (current_cpu == "riscv") {
sources += [ "riscv/mulsi3.S" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/cfi/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/cfi/BUILD.gn
index 3ff5f3f..b9ff5c5 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/cfi/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/cfi/BUILD.gn
@@ -6,7 +6,7 @@
sources = [ "cfi.cpp" ]
}
-copy("blacklist") {
- sources = [ "cfi_blacklist.txt" ]
+copy("ignorelist") {
+ sources = [ "cfi_ignorelist.txt" ]
outputs = [ "$clang_resource_dir/share/{{source_target_relative}}" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn
index 919d234..32047fe 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/hwasan/BUILD.gn
@@ -1,5 +1,11 @@
import("//compiler-rt/target.gni")
+if (current_cpu == "x64") {
+ hwasan_name = "hwasan_aliases"
+} else {
+ hwasan_name = "hwasan"
+}
+
action("version_script") {
script = "//compiler-rt/lib/sanitizer_common/scripts/gen_dynamic_list.py"
sources = [ "hwasan.syms.extra" ]
@@ -13,10 +19,10 @@
"--extra",
rebase_path(sources[0], root_build_dir),
rebase_path(
- "$crt_current_out_dir/libclang_rt.hwasan$crt_current_target_suffix.a",
+ "$crt_current_out_dir/libclang_rt.$hwasan_name$crt_current_target_suffix.a",
root_build_dir),
rebase_path(
- "$crt_current_out_dir/libclang_rt.hwasan_cxx$crt_current_target_suffix.a",
+ "$crt_current_out_dir/libclang_rt.${hwasan_name}_cxx$crt_current_target_suffix.a",
root_build_dir),
"--nm-executable",
"nm",
@@ -29,6 +35,9 @@
configs -= [ "//llvm/utils/gn/build:llvm_code" ]
configs += [ "//llvm/utils/gn/build:crt_code" ]
defines = [ "HWASAN_WITH_INTERCEPTORS=1" ]
+ if (current_cpu == "x64") {
+ defines += [ "HWASAN_ALIASING_MODE" ]
+ }
deps = [
"//compiler-rt/lib/interception:sources",
"//compiler-rt/lib/sanitizer_common:sources",
@@ -37,12 +46,14 @@
sources = [
"hwasan.cpp",
"hwasan.h",
+ "hwasan_allocation_functions.cpp",
"hwasan_allocator.cpp",
"hwasan_allocator.h",
"hwasan_dynamic_shadow.cpp",
"hwasan_dynamic_shadow.h",
"hwasan_exceptions.cpp",
"hwasan_flags.h",
+ "hwasan_fuchsia.cpp",
"hwasan_globals.cpp",
"hwasan_globals.h",
"hwasan_interceptors.cpp",
@@ -76,7 +87,7 @@
static_library("hwasan") {
output_dir = crt_current_out_dir
- output_name = "clang_rt.hwasan$crt_current_target_suffix"
+ output_name = "clang_rt.$hwasan_name$crt_current_target_suffix"
complete_static_lib = true
configs -= [
"//llvm/utils/gn/build:llvm_code",
@@ -88,7 +99,7 @@
static_library("hwasan_cxx") {
output_dir = crt_current_out_dir
- output_name = "clang_rt.hwasan_cxx$crt_current_target_suffix"
+ output_name = "clang_rt.${hwasan_name}_cxx$crt_current_target_suffix"
complete_static_lib = true
configs -= [
"//llvm/utils/gn/build:llvm_code",
@@ -100,7 +111,7 @@
shared_library("hwasan_shared") {
output_dir = crt_current_out_dir
- output_name = "clang_rt.hwasan$crt_current_target_suffix"
+ output_name = "clang_rt.$hwasan_name$crt_current_target_suffix"
configs -= [ "//llvm/utils/gn/build:llvm_code" ]
configs += [ "//llvm/utils/gn/build:crt_code" ]
deps = [
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/msan/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/msan/BUILD.gn
new file mode 100644
index 0000000..92be6df
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/msan/BUILD.gn
@@ -0,0 +1,73 @@
+import("//compiler-rt/target.gni")
+
+static_library("msan") {
+ configs -= [ "//llvm/utils/gn/build:llvm_code" ]
+ configs += [ "//llvm/utils/gn/build:crt_code" ]
+
+ output_dir = crt_current_out_dir
+ assert(current_os == "linux", "MSan only works on Linux")
+ output_name = "clang_rt.msan$crt_current_target_suffix"
+
+ deps = [
+ "//compiler-rt/lib/interception:sources",
+ "//compiler-rt/lib/sanitizer_common:sources",
+ "//compiler-rt/lib/ubsan:sources",
+ ]
+
+ complete_static_lib = true
+ configs -= [ "//llvm/utils/gn/build:thin_archive" ]
+ deps += [ ":msan_cxx" ]
+
+ sources = [
+ "msan.cpp",
+ "msan.h",
+ "msan_allocator.cpp",
+ "msan_allocator.h",
+ "msan_chained_origin_depot.cpp",
+ "msan_chained_origin_depot.h",
+ "msan_flags.h",
+ "msan_flags.inc",
+ "msan_interceptors.cpp",
+ "msan_interface_internal.h",
+ "msan_linux.cpp",
+ "msan_origin.h",
+ "msan_poisoning.cpp",
+ "msan_poisoning.h",
+ "msan_report.cpp",
+ "msan_report.h",
+ "msan_thread.cpp",
+ "msan_thread.h",
+ ]
+
+ # To be able to include sanitizer_common.
+ include_dirs = [ ".." ]
+
+ # FIXME: have SANITIZER_COMMON_CFLAGS thingy? should fno-builtin be in
+ # crt_code?
+ cflags = [ "-fno-builtin" ]
+
+ cflags += [ "-fPIE" ]
+
+ # Prevent clang from generating libc calls.
+ cflags += [ "-ffreestanding" ]
+
+ # FIXME: link rt dl m pthread log
+ # FIXME: need libclang_rt.msan*.a.syms?
+ # FIXME: msan_ignorelist.txt
+}
+
+static_library("msan_cxx") {
+ configs -= [ "//llvm/utils/gn/build:llvm_code" ]
+ configs += [ "//llvm/utils/gn/build:crt_code" ]
+
+ output_dir = crt_current_out_dir
+ assert(current_os == "linux", "MSan only works on Linux")
+ output_name = "clang_rt.msan_cxx$crt_current_target_suffix"
+
+ complete_static_lib = true
+ configs -= [ "//llvm/utils/gn/build:thin_archive" ]
+
+ deps = [ "//compiler-rt/lib/ubsan:cxx_sources" ]
+
+ sources = [ "msan_new_delete.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/profile/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/profile/BUILD.gn
index 5fab007..a0bc9b7 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/profile/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/profile/BUILD.gn
@@ -34,7 +34,6 @@
"GCDAProfiling.c",
"InstrProfiling.c",
"InstrProfiling.h",
- "InstrProfilingBiasVar.c",
"InstrProfilingBuffer.c",
"InstrProfilingFile.c",
"InstrProfilingInternal.c",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn
index 79b6bf0..2cafcba 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/sanitizer_common/BUILD.gn
@@ -38,6 +38,8 @@
"sanitizer_atomic_msvc.h",
"sanitizer_bitvector.h",
"sanitizer_bvgraph.h",
+ "sanitizer_chained_origin_depot.cpp",
+ "sanitizer_chained_origin_depot.h",
"sanitizer_common.cpp",
"sanitizer_common.h",
"sanitizer_common_libcdep.cpp",
@@ -79,6 +81,7 @@
"sanitizer_mac.cpp",
"sanitizer_mac.h",
"sanitizer_mac_libcdep.cpp",
+ "sanitizer_mutex.cpp",
"sanitizer_mutex.h",
"sanitizer_netbsd.cpp",
"sanitizer_persistent_allocator.cpp",
@@ -109,8 +112,6 @@
"sanitizer_quarantine.h",
"sanitizer_report_decorator.h",
"sanitizer_ring_buffer.h",
- "sanitizer_rtems.cpp",
- "sanitizer_rtems.h",
"sanitizer_solaris.cpp",
"sanitizer_stackdepot.cpp",
"sanitizer_stackdepot.h",
@@ -140,11 +141,11 @@
"sanitizer_symbolizer_markup.cpp",
"sanitizer_symbolizer_posix_libcdep.cpp",
"sanitizer_symbolizer_report.cpp",
- "sanitizer_symbolizer_rtems.h",
"sanitizer_symbolizer_win.cpp",
"sanitizer_termination.cpp",
"sanitizer_thread_registry.cpp",
"sanitizer_thread_registry.h",
+ "sanitizer_thread_safety.h",
"sanitizer_tls_get_addr.cpp",
"sanitizer_tls_get_addr.h",
"sanitizer_type_traits.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/BUILD.gn
index d6b125a..4833177 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/BUILD.gn
@@ -18,6 +18,7 @@
"chunk.h",
"combined.h",
"common.cpp",
+ "common.h",
"crc32_hw.cpp",
"flags.cpp",
"flags.h",
@@ -31,7 +32,9 @@
"linux.h",
"list.h",
"local_cache.h",
+ "memtag.h",
"mutex.h",
+ "options.h",
"platform.h",
"primary32.h",
"primary64.h",
@@ -42,6 +45,7 @@
"report.h",
"secondary.h",
"size_class_map.h",
+ "stack_depot.h",
"stats.h",
"string_utils.cpp",
"string_utils.h",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/tests/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/tests/BUILD.gn
index 4161e96..757871a 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/tests/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/scudo/standalone/tests/BUILD.gn
@@ -13,14 +13,17 @@
"checksum_test.cpp",
"chunk_test.cpp",
"combined_test.cpp",
+ "common_test.cpp",
"flags_test.cpp",
"list_test.cpp",
"map_test.cpp",
+ "memtag_test.cpp",
"mutex_test.cpp",
"primary_test.cpp",
"quarantine_test.cpp",
"release_test.cpp",
"report_test.cpp",
+ "scudo_unit_test.h",
"scudo_unit_test_main.cpp",
"secondary_test.cpp",
"size_class_map_test.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/tsan/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/tsan/BUILD.gn
new file mode 100644
index 0000000..d3b726e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/tsan/BUILD.gn
@@ -0,0 +1,180 @@
+import("//compiler-rt/target.gni")
+
+source_set("cxx_sources") {
+ configs -= [ "//llvm/utils/gn/build:llvm_code" ]
+ configs += [ "//llvm/utils/gn/build:crt_code" ]
+ sources = [ "rtl/tsan_new_delete.cpp" ]
+}
+
+if (current_os == "mac") {
+ tsan_target_type = "shared_library"
+} else {
+ tsan_target_type = "static_library"
+}
+
+target(tsan_target_type, "tsan") {
+ configs -= [ "//llvm/utils/gn/build:llvm_code" ]
+ configs += [ "//llvm/utils/gn/build:crt_code" ]
+
+ output_dir = crt_current_out_dir
+ if (current_os == "mac") {
+ output_name = "clang_rt.tsan_osx_dynamic"
+ } else {
+ assert(current_os != "win", "Tsan does not work on Windows")
+ output_name = "clang_rt.tsan$crt_current_target_suffix"
+ }
+
+ deps = [
+ "//compiler-rt/lib/interception:sources",
+ "//compiler-rt/lib/sanitizer_common:sources",
+ "//compiler-rt/lib/ubsan:sources",
+ ]
+
+ if (tsan_target_type == "static_library") {
+ complete_static_lib = true
+ configs -= [ "//llvm/utils/gn/build:thin_archive" ]
+ deps += [ ":tsan_cxx" ]
+ } else {
+ deps += [
+ ":cxx_sources",
+ "//compiler-rt/lib/ubsan:cxx_sources",
+ ]
+ }
+
+ # It's performance-critical for TSan runtime to be built with -fPIE to reduce
+ # the number of register spills.
+ cflags = [ "-fPIE" ]
+
+ sources = [
+ "rtl/tsan_clock.cpp",
+ "rtl/tsan_clock.h",
+ "rtl/tsan_debugging.cpp",
+ "rtl/tsan_defs.h",
+ "rtl/tsan_dense_alloc.h",
+ "rtl/tsan_external.cpp",
+ "rtl/tsan_fd.cpp",
+ "rtl/tsan_fd.h",
+ "rtl/tsan_flags.cpp",
+ "rtl/tsan_flags.h",
+ "rtl/tsan_flags.inc",
+ "rtl/tsan_ignoreset.cpp",
+ "rtl/tsan_ignoreset.h",
+ "rtl/tsan_interceptors.h",
+ "rtl/tsan_interceptors_posix.cpp",
+ "rtl/tsan_interface.cpp",
+ "rtl/tsan_interface.h",
+ "rtl/tsan_interface_ann.cpp",
+ "rtl/tsan_interface_ann.h",
+ "rtl/tsan_interface_atomic.cpp",
+ "rtl/tsan_interface_inl.h",
+ "rtl/tsan_interface_java.cpp",
+ "rtl/tsan_interface_java.h",
+ "rtl/tsan_malloc_mac.cpp",
+ "rtl/tsan_md5.cpp",
+ "rtl/tsan_mman.cpp",
+ "rtl/tsan_mman.h",
+ "rtl/tsan_mutexset.cpp",
+ "rtl/tsan_mutexset.h",
+ "rtl/tsan_platform.h",
+ "rtl/tsan_ppc_regs.h",
+ "rtl/tsan_preinit.cpp",
+ "rtl/tsan_report.cpp",
+ "rtl/tsan_report.h",
+ "rtl/tsan_rtl.cpp",
+ "rtl/tsan_rtl.h",
+ "rtl/tsan_rtl_mutex.cpp",
+ "rtl/tsan_rtl_proc.cpp",
+ "rtl/tsan_rtl_report.cpp",
+ "rtl/tsan_rtl_thread.cpp",
+ "rtl/tsan_stack_trace.cpp",
+ "rtl/tsan_stack_trace.h",
+ "rtl/tsan_suppressions.cpp",
+ "rtl/tsan_suppressions.h",
+ "rtl/tsan_symbolize.cpp",
+ "rtl/tsan_symbolize.h",
+ "rtl/tsan_sync.cpp",
+ "rtl/tsan_sync.h",
+ "rtl/tsan_trace.h",
+ "rtl/tsan_update_shadow_word_inl.h",
+ ]
+ if (target_os == "mac") {
+ sources += [
+ "rtl/tsan_interceptors_libdispatch.cpp",
+ "rtl/tsan_interceptors_mac.cpp",
+ "rtl/tsan_interceptors_mach_vm.cpp",
+ "rtl/tsan_platform_mac.cpp",
+ "rtl/tsan_platform_posix.cpp",
+ ]
+ cflags += [ "-fblocks" ]
+ } else {
+ # Assume Linux
+ sources += [
+ "rtl/tsan_platform_linux.cpp",
+ "rtl/tsan_platform_posix.cpp",
+ ]
+ }
+ if (target_cpu == "x64") {
+ sources += [ "rtl/tsan_rtl_amd64.S" ]
+ } else if (target_cpu == "arm64") {
+ sources += [ "rtl/tsan_rtl_aarch64.S" ]
+ } else if (target_cpu == "powerpc64") {
+ sources += [ "rtl/tsan_rtl_ppc64.S" ]
+ } else if (target_cpu == "mips64") {
+ sources += [ "rtl/tsan_rtl_mips64.S" ]
+ } else if (target_cpu == "s390x") {
+ sources += [ "rtl/tsan_rtl_s390x.S" ]
+ }
+
+ # To be able to include sanitizer_common.
+ include_dirs = [ ".." ]
+
+ # FIXME: have SANITIZER_COMMON_CFLAGS thingy? should fno-builtin be in
+ # crt_code?
+ cflags += [ "-fno-builtin" ]
+
+ # FIXME: link rt dl m pthread log
+ # FIXME: dep on libcxx-headers?
+ # FIXME: add_sanitizer_rt_version_list (cf hwasan)
+ # FIXME: need libclang_rt.tsan*.a.syms?
+ # FIXME: tsan_ignorelist.txt
+
+ if (target_os == "mac") {
+ # The -U flags below correspond to the add_weak_symbols() calls in CMake.
+ ldflags = [
+ "-lc++",
+ "-lc++abi",
+ "-lobjc",
+
+ # sanitizer_common
+ "-Wl,-U,___sanitizer_free_hook",
+ "-Wl,-U,___sanitizer_malloc_hook",
+ "-Wl,-U,___sanitizer_report_error_summary",
+ "-Wl,-U,___sanitizer_sandbox_on_notify",
+ "-Wl,-U,___sanitizer_symbolize_code",
+ "-Wl,-U,___sanitizer_symbolize_data",
+ "-Wl,-U,___sanitizer_symbolize_demangle",
+ "-Wl,-U,___sanitizer_symbolize_flush",
+
+ # FIXME: better
+ "-Wl,-install_name,@rpath/libclang_rt.tsan_osx_dynamic.dylib",
+ ]
+ # FIXME: -Wl,-rpath
+ # FIXME: codesign (??)
+ }
+}
+
+if (tsan_target_type == "static_library") {
+ static_library("tsan_cxx") {
+ assert(current_os != "win", "FIXME")
+ output_dir = crt_current_out_dir
+ output_name = "clang_rt.tsan_cxx$crt_current_target_suffix"
+ complete_static_lib = true
+ configs -= [ "//llvm/utils/gn/build:thin_archive" ]
+ deps = [
+ ":cxx_sources",
+ "//compiler-rt/lib/ubsan:cxx_sources",
+ ]
+ }
+}
+# FIXME:
+# Build libcxx instrumented with TSan.
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/ubsan_minimal/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/ubsan_minimal/BUILD.gn
new file mode 100644
index 0000000..afea502
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/lib/ubsan_minimal/BUILD.gn
@@ -0,0 +1,18 @@
+import("//compiler-rt/target.gni")
+
+source_set("sources") {
+ configs -= [ "//llvm/utils/gn/build:llvm_code" ]
+ configs += [ "//llvm/utils/gn/build:crt_code" ]
+}
+
+static_library("ubsan_minimal") {
+ output_dir = crt_current_out_dir
+ output_name = "clang_rt.ubsan_minimal$crt_current_target_suffix"
+ complete_static_lib = true
+ configs -= [
+ "//llvm/utils/gn/build:llvm_code",
+ "//llvm/utils/gn/build:thin_archive",
+ ]
+ configs += [ "//llvm/utils/gn/build:crt_code" ]
+ sources = [ "ubsan_minimal_handlers.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/target.gni b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/target.gni
index ead515f..ac27337 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/target.gni
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/target.gni
@@ -28,6 +28,9 @@
}
} else if (current_os == "ios" || current_os == "mac") {
crt_current_out_dir = "$clang_resource_dir/lib/darwin"
+} else if (current_os == "win") {
+ crt_current_out_dir = "$clang_resource_dir/lib/windows"
+ crt_current_target_suffix = "-$crt_current_target_arch"
} else {
assert(false, "unimplemented current_os " + current_os)
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/BUILD.gn
index 5cbfaf3..03f7fe7 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/BUILD.gn
@@ -50,6 +50,7 @@
"COMPILER_RT_EMULATOR=",
"COMPILER_RT_ASAN_SHADOW_SCALE=",
"COMPILER_RT_MEMPROF_SHADOW_SCALE=",
+ "COMPILER_RT_TEST_STANDALONE_BUILD_LIBS_PYBOOL=False",
"COMPILER_RT_TEST_USE_LLD_PYBOOL=0", # FIXME: base off use_lld?
"SANITIZER_CAN_USE_CXXABI_PYBOOL=True",
"COMPILER_RT_HAS_LLD_PYBOOL=True",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/hwasan/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/hwasan/BUILD.gn
index e58637b..2c39486 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/hwasan/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/compiler-rt/test/hwasan/BUILD.gn
@@ -11,6 +11,8 @@
values = [
"LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit",
+ "HWASAN_ENABLE_ALIASES=1",
+
"HWASAN_TEST_CONFIG_SUFFIX=$crt_current_target_suffix",
"HWASAN_TEST_TARGET_CFLAGS=$target_flags_string",
"HWASAN_TEST_TARGET_ARCH=$crt_current_target_arch",
@@ -33,7 +35,7 @@
deps = [
":lit_site_cfg",
"//compiler-rt/include($host_toolchain)",
- "//compiler-rt/lib/cfi:blacklist($host_toolchain)",
+ "//compiler-rt/lib/cfi:ignorelist($host_toolchain)",
"//compiler-rt/lib/hwasan:hwasan_shared",
"//compiler-rt/test:lit_common_configured",
"//llvm/utils/FileCheck($host_toolchain)",
@@ -84,10 +86,10 @@
outputs = [ "$target_gen_dir/run-lit" ] # Non-existing, so that ninja runs
# it each time.
- # Since check-hwasan is always dirty, //:default doesn't depend on it so that
- # it's not part of the default ninja target. Hence, check-hwasan shouldn't
- # have any deps except :hwasan. so that the default target is sure to build
- # all the deps.
+ # Since check-hwasan is always dirty, //:default doesn't depend on it so
+ # that it's not part of the default ninja target. Hence, check-hwasan
+ # shouldn't have any deps except :hwasan. so that the default target is
+ # sure to build all the deps.
deps = [ ":hwasan" ]
testonly = true
diff --git a/src/llvm-project/llvm/utils/gn/secondary/libcxx/include/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
index 2ca495b..32f81da 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/libcxx/include/BUILD.gn
@@ -1,269 +1,473 @@
import("//libcxx/config.gni")
import("//llvm/utils/gn/build/write_cmake_config.gni")
-write_cmake_config("write_config") {
- input = "__config_site.in"
- output = "$target_gen_dir/__config_site"
+libcxx_generated_include_dir = "$root_build_dir/include/c++/v1"
- values = [
- "_LIBCPP_ABI_FORCE_ITANIUM=",
- "_LIBCPP_ABI_FORCE_MICROSOFT=",
- "_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT=",
- "_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY=",
- "_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE=",
- "_LIBCPP_HAS_NO_STDIN=",
- "_LIBCPP_HAS_NO_STDOUT=",
- "_LIBCPP_HAS_NO_THREADS=",
- "_LIBCPP_HAS_NO_MONOTONIC_CLOCK=",
- "_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS=",
- "_LIBCPP_HAS_MUSL_LIBC=",
- "_LIBCPP_HAS_THREAD_API_PTHREAD=",
- "_LIBCPP_HAS_THREAD_API_EXTERNAL=",
- "_LIBCPP_HAS_THREAD_API_WIN32=",
- "_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL=",
- "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=",
- "_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS=1",
- "_LIBCPP_NO_VCRUNTIME=",
- "_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=",
- "_LIBCPP_HAS_PARALLEL_ALGORITHMS=",
- "_LIBCPP_HAS_NO_RANDOM_DEVICE=",
- "_LIBCPP_HAS_NO_LOCALIZATION=",
- "_LIBCPP_ABI_DEFINES=",
- ]
- if (libcxx_abi_version != 1) {
- values += [ "_LIBCPP_ABI_VERSION=$libcxx_abi_version" ]
- } else {
- values += [ "_LIBCPP_ABI_VERSION=" ]
+# This is a bit weird. For now, we assume that __config_site is identical
+# in all toolchains, and only copy it (and all other libcxx headers)
+# to 'include' in the root build dir, so that it's the same for all toolchains.
+# Maybe we want to make this per-toolchain eventually (and then use root_out_dir
+# in libcxx_generated_include_dir) -- e.g. for cross-builds that for example
+# use for-linux-configured libc++ for the host build but for-windows-configured
+# libc++ for the target build.
+if (current_toolchain == default_toolchain) {
+ write_cmake_config("write_config_site") {
+ input = "__config_site.in"
+ output = "$libcxx_generated_include_dir/__config_site"
+
+ values = [
+ "_LIBCPP_ABI_FORCE_ITANIUM=",
+ "_LIBCPP_ABI_FORCE_MICROSOFT=",
+ "_LIBCPP_HIDE_FROM_ABI_PER_TU_BY_DEFAULT=",
+ "_LIBCPP_HAS_NO_FILESYSTEM_LIBRARY=",
+ "_LIBCPP_HAS_NO_INCOMPLETE_FORMAT=",
+ "_LIBCPP_HAS_NO_INCOMPLETE_RANGES=",
+ "_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE=",
+ "_LIBCPP_HAS_NO_STDIN=",
+ "_LIBCPP_HAS_NO_STDOUT=",
+ "_LIBCPP_HAS_NO_THREADS=",
+ "_LIBCPP_HAS_NO_MONOTONIC_CLOCK=",
+ "_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS=",
+ "_LIBCPP_HAS_MUSL_LIBC=",
+ "_LIBCPP_HAS_THREAD_API_PTHREAD=",
+ "_LIBCPP_HAS_THREAD_API_EXTERNAL=",
+ "_LIBCPP_HAS_THREAD_API_WIN32=",
+ "_LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL=",
+ "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=",
+ "_LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS=1",
+ "_LIBCPP_NO_VCRUNTIME=",
+ "_LIBCPP_TYPEINFO_COMPARISON_IMPLEMENTATION=",
+ "_LIBCPP_HAS_PARALLEL_ALGORITHMS=",
+ "_LIBCPP_HAS_NO_RANDOM_DEVICE=",
+ "_LIBCPP_HAS_NO_LOCALIZATION=",
+ "_LIBCPP_ABI_DEFINES=",
+ ]
+ if (libcxx_abi_version != 1) {
+ values += [ "_LIBCPP_ABI_VERSION=$libcxx_abi_version" ]
+ } else {
+ values += [ "_LIBCPP_ABI_VERSION=" ]
+ }
+ if (libcxx_abi_namespace != "") {
+ values += [ "_LIBCPP_ABI_NAMESPACE=$libcxx_abi_namespace" ]
+ } else {
+ values += [ "_LIBCPP_ABI_NAMESPACE=" ]
+ }
+ if (libcxx_abi_unstable) {
+ values += [ "_LIBCPP_ABI_UNSTABLE=1" ]
+ } else {
+ values += [ "_LIBCPP_ABI_UNSTABLE=" ]
+ }
}
- if (libcxx_abi_namespace != "") {
- values += [ "_LIBCPP_ABI_NAMESPACE=$libcxx_abi_namespace" ]
- } else {
- values += [ "_LIBCPP_ABI_NAMESPACE=" ]
- }
- if (libcxx_abi_unstable) {
- values += [ "_LIBCPP_ABI_UNSTABLE=1" ]
- } else {
- values += [ "_LIBCPP_ABI_UNSTABLE=" ]
+
+ copy("copy_headers") {
+ sources = [
+ "__algorithm/adjacent_find.h",
+ "__algorithm/all_of.h",
+ "__algorithm/any_of.h",
+ "__algorithm/binary_search.h",
+ "__algorithm/clamp.h",
+ "__algorithm/comp.h",
+ "__algorithm/comp_ref_type.h",
+ "__algorithm/copy.h",
+ "__algorithm/copy_backward.h",
+ "__algorithm/copy_if.h",
+ "__algorithm/copy_n.h",
+ "__algorithm/count.h",
+ "__algorithm/count_if.h",
+ "__algorithm/equal.h",
+ "__algorithm/equal_range.h",
+ "__algorithm/fill.h",
+ "__algorithm/fill_n.h",
+ "__algorithm/find.h",
+ "__algorithm/find_end.h",
+ "__algorithm/find_first_of.h",
+ "__algorithm/find_if.h",
+ "__algorithm/find_if_not.h",
+ "__algorithm/for_each.h",
+ "__algorithm/for_each_n.h",
+ "__algorithm/generate.h",
+ "__algorithm/generate_n.h",
+ "__algorithm/half_positive.h",
+ "__algorithm/includes.h",
+ "__algorithm/inplace_merge.h",
+ "__algorithm/is_heap.h",
+ "__algorithm/is_heap_until.h",
+ "__algorithm/is_partitioned.h",
+ "__algorithm/is_permutation.h",
+ "__algorithm/is_sorted.h",
+ "__algorithm/is_sorted_until.h",
+ "__algorithm/iter_swap.h",
+ "__algorithm/lexicographical_compare.h",
+ "__algorithm/lower_bound.h",
+ "__algorithm/make_heap.h",
+ "__algorithm/max.h",
+ "__algorithm/max_element.h",
+ "__algorithm/merge.h",
+ "__algorithm/min.h",
+ "__algorithm/min_element.h",
+ "__algorithm/minmax.h",
+ "__algorithm/minmax_element.h",
+ "__algorithm/mismatch.h",
+ "__algorithm/move.h",
+ "__algorithm/move_backward.h",
+ "__algorithm/next_permutation.h",
+ "__algorithm/none_of.h",
+ "__algorithm/nth_element.h",
+ "__algorithm/partial_sort.h",
+ "__algorithm/partial_sort_copy.h",
+ "__algorithm/partition.h",
+ "__algorithm/partition_copy.h",
+ "__algorithm/partition_point.h",
+ "__algorithm/pop_heap.h",
+ "__algorithm/prev_permutation.h",
+ "__algorithm/push_heap.h",
+ "__algorithm/remove.h",
+ "__algorithm/remove_copy.h",
+ "__algorithm/remove_copy_if.h",
+ "__algorithm/remove_if.h",
+ "__algorithm/replace.h",
+ "__algorithm/replace_copy.h",
+ "__algorithm/replace_copy_if.h",
+ "__algorithm/replace_if.h",
+ "__algorithm/reverse.h",
+ "__algorithm/reverse_copy.h",
+ "__algorithm/rotate.h",
+ "__algorithm/rotate_copy.h",
+ "__algorithm/sample.h",
+ "__algorithm/search.h",
+ "__algorithm/search_n.h",
+ "__algorithm/set_difference.h",
+ "__algorithm/set_intersection.h",
+ "__algorithm/set_symmetric_difference.h",
+ "__algorithm/set_union.h",
+ "__algorithm/shift_left.h",
+ "__algorithm/shift_right.h",
+ "__algorithm/shuffle.h",
+ "__algorithm/sift_down.h",
+ "__algorithm/sort.h",
+ "__algorithm/sort_heap.h",
+ "__algorithm/stable_partition.h",
+ "__algorithm/stable_sort.h",
+ "__algorithm/swap_ranges.h",
+ "__algorithm/transform.h",
+ "__algorithm/unique.h",
+ "__algorithm/unique_copy.h",
+ "__algorithm/unwrap_iter.h",
+ "__algorithm/upper_bound.h",
+ "__availability",
+ "__bit_reference",
+ "__bits",
+ "__bsd_locale_defaults.h",
+ "__bsd_locale_fallbacks.h",
+ "__config",
+ "__debug",
+ "__errc",
+ "__format/format_error.h",
+ "__format/format_parse_context.h",
+ "__function_like.h",
+ "__functional/binary_function.h",
+ "__functional/binary_negate.h",
+ "__functional/bind.h",
+ "__functional/bind_front.h",
+ "__functional/binder1st.h",
+ "__functional/binder2nd.h",
+ "__functional/default_searcher.h",
+ "__functional/function.h",
+ "__functional/hash.h",
+ "__functional/identity.h",
+ "__functional/invoke.h",
+ "__functional/is_transparent.h",
+ "__functional/mem_fn.h",
+ "__functional/mem_fun_ref.h",
+ "__functional/not_fn.h",
+ "__functional/operations.h",
+ "__functional/perfect_forward.h",
+ "__functional/pointer_to_binary_function.h",
+ "__functional/pointer_to_unary_function.h",
+ "__functional/ranges_operations.h",
+ "__functional/reference_wrapper.h",
+ "__functional/unary_function.h",
+ "__functional/unary_negate.h",
+ "__functional/unwrap_ref.h",
+ "__functional/weak_result_type.h",
+ "__functional_base",
+ "__hash_table",
+ "__iterator/access.h",
+ "__iterator/advance.h",
+ "__iterator/back_insert_iterator.h",
+ "__iterator/common_iterator.h",
+ "__iterator/concepts.h",
+ "__iterator/counted_iterator.h",
+ "__iterator/data.h",
+ "__iterator/default_sentinel.h",
+ "__iterator/distance.h",
+ "__iterator/empty.h",
+ "__iterator/erase_if_container.h",
+ "__iterator/front_insert_iterator.h",
+ "__iterator/incrementable_traits.h",
+ "__iterator/insert_iterator.h",
+ "__iterator/istream_iterator.h",
+ "__iterator/istreambuf_iterator.h",
+ "__iterator/iter_move.h",
+ "__iterator/iter_swap.h",
+ "__iterator/iterator.h",
+ "__iterator/iterator_traits.h",
+ "__iterator/move_iterator.h",
+ "__iterator/next.h",
+ "__iterator/ostream_iterator.h",
+ "__iterator/ostreambuf_iterator.h",
+ "__iterator/prev.h",
+ "__iterator/projected.h",
+ "__iterator/readable_traits.h",
+ "__iterator/reverse_access.h",
+ "__iterator/reverse_iterator.h",
+ "__iterator/size.h",
+ "__iterator/wrap_iter.h",
+ "__libcpp_version",
+ "__locale",
+ "__memory/addressof.h",
+ "__memory/allocation_guard.h",
+ "__memory/allocator.h",
+ "__memory/allocator_arg_t.h",
+ "__memory/allocator_traits.h",
+ "__memory/auto_ptr.h",
+ "__memory/compressed_pair.h",
+ "__memory/construct_at.h",
+ "__memory/pointer_safety.h",
+ "__memory/pointer_traits.h",
+ "__memory/raw_storage_iterator.h",
+ "__memory/shared_ptr.h",
+ "__memory/temporary_buffer.h",
+ "__memory/uninitialized_algorithms.h",
+ "__memory/unique_ptr.h",
+ "__memory/uses_allocator.h",
+ "__mutex_base",
+ "__node_handle",
+ "__nullptr",
+ "__random/uniform_int_distribution.h",
+ "__ranges/access.h",
+ "__ranges/all.h",
+ "__ranges/common_view.h",
+ "__ranges/concepts.h",
+ "__ranges/copyable_box.h",
+ "__ranges/dangling.h",
+ "__ranges/data.h",
+ "__ranges/drop_view.h",
+ "__ranges/empty.h",
+ "__ranges/empty_view.h",
+ "__ranges/enable_borrowed_range.h",
+ "__ranges/enable_view.h",
+ "__ranges/non_propagating_cache.h",
+ "__ranges/ref_view.h",
+ "__ranges/size.h",
+ "__ranges/subrange.h",
+ "__ranges/transform_view.h",
+ "__ranges/view_interface.h",
+ "__split_buffer",
+ "__std_stream",
+ "__string",
+ "__support/android/locale_bionic.h",
+ "__support/fuchsia/xlocale.h",
+ "__support/ibm/gettod_zos.h",
+ "__support/ibm/limits.h",
+ "__support/ibm/locale_mgmt_aix.h",
+ "__support/ibm/locale_mgmt_zos.h",
+ "__support/ibm/nanosleep.h",
+ "__support/ibm/support.h",
+ "__support/ibm/xlocale.h",
+ "__support/musl/xlocale.h",
+ "__support/newlib/xlocale.h",
+ "__support/nuttx/xlocale.h",
+ "__support/openbsd/xlocale.h",
+ "__support/solaris/floatingpoint.h",
+ "__support/solaris/wchar.h",
+ "__support/solaris/xlocale.h",
+ "__support/win32/limits_msvc_win32.h",
+ "__support/win32/locale_win32.h",
+ "__support/xlocale/__nop_locale_mgmt.h",
+ "__support/xlocale/__posix_l_fallback.h",
+ "__support/xlocale/__strtonum_fallback.h",
+ "__threading_support",
+ "__tree",
+ "__tuple",
+ "__undef_macros",
+ "__utility/__decay_copy.h",
+ "__utility/as_const.h",
+ "__utility/cmp.h",
+ "__utility/declval.h",
+ "__utility/exchange.h",
+ "__utility/forward.h",
+ "__utility/in_place.h",
+ "__utility/integer_sequence.h",
+ "__utility/move.h",
+ "__utility/pair.h",
+ "__utility/piecewise_construct.h",
+ "__utility/rel_ops.h",
+ "__utility/swap.h",
+ "__utility/to_underlying.h",
+ "__variant/monostate.h",
+ "algorithm",
+ "any",
+ "array",
+ "atomic",
+ "barrier",
+ "bit",
+ "bitset",
+ "cassert",
+ "ccomplex",
+ "cctype",
+ "cerrno",
+ "cfenv",
+ "cfloat",
+ "charconv",
+ "chrono",
+ "cinttypes",
+ "ciso646",
+ "climits",
+ "clocale",
+ "cmath",
+ "codecvt",
+ "compare",
+ "complex",
+ "complex.h",
+ "concepts",
+ "condition_variable",
+ "csetjmp",
+ "csignal",
+ "cstdarg",
+ "cstdbool",
+ "cstddef",
+ "cstdint",
+ "cstdio",
+ "cstdlib",
+ "cstring",
+ "ctgmath",
+ "ctime",
+ "ctype.h",
+ "cwchar",
+ "cwctype",
+ "deque",
+ "errno.h",
+ "exception",
+ "execution",
+ "experimental/__config",
+ "experimental/__memory",
+ "experimental/algorithm",
+ "experimental/coroutine",
+ "experimental/deque",
+ "experimental/filesystem",
+ "experimental/forward_list",
+ "experimental/functional",
+ "experimental/iterator",
+ "experimental/list",
+ "experimental/map",
+ "experimental/memory_resource",
+ "experimental/propagate_const",
+ "experimental/regex",
+ "experimental/set",
+ "experimental/simd",
+ "experimental/string",
+ "experimental/type_traits",
+ "experimental/unordered_map",
+ "experimental/unordered_set",
+ "experimental/utility",
+ "experimental/vector",
+ "ext/__hash",
+ "ext/hash_map",
+ "ext/hash_set",
+ "fenv.h",
+ "filesystem",
+ "float.h",
+ "format",
+ "forward_list",
+ "fstream",
+ "functional",
+ "future",
+ "initializer_list",
+ "inttypes.h",
+ "iomanip",
+ "ios",
+ "iosfwd",
+ "iostream",
+ "istream",
+ "iterator",
+ "latch",
+ "limits",
+ "limits.h",
+ "list",
+ "locale",
+ "locale.h",
+ "map",
+ "math.h",
+ "memory",
+ "module.modulemap",
+ "mutex",
+ "new",
+ "numbers",
+ "numeric",
+ "optional",
+ "ostream",
+ "queue",
+ "random",
+ "ratio",
+ "regex",
+ "scoped_allocator",
+ "semaphore",
+ "set",
+ "setjmp.h",
+ "shared_mutex",
+ "span",
+ "sstream",
+ "stack",
+ "stdbool.h",
+ "stddef.h",
+ "stdexcept",
+ "stdint.h",
+ "stdio.h",
+ "stdlib.h",
+ "streambuf",
+ "string",
+ "string.h",
+ "string_view",
+ "strstream",
+ "system_error",
+ "tgmath.h",
+ "thread",
+ "tuple",
+ "type_traits",
+ "typeindex",
+ "typeinfo",
+ "unordered_map",
+ "unordered_set",
+ "utility",
+ "valarray",
+ "variant",
+ "vector",
+ "version",
+ "wchar.h",
+ "wctype.h",
+ ]
+ deps = [ ":write_config_site" ]
+ if (target_os != "mac" && target_os != "win") {
+ # libcxx/cmake/Modules/HandleLibCXXABI.cmake sets
+ # LIBCXX_CXX_ABI_HEADER_TARGET if the libcxx abi library either of
+ # "libstdc++", "libsupc++", "libcxxabi", "libcxxrt", but not if it's "none",
+ # "default", or "vcruntime". So on Windows, these don't get copied due to
+ # LIBCXX_CXX_ABI_HEADER_TARGET not being set.
+ # On macOS, libcxx/CMakeLists.txt sets LIBCXX_CXX_ABI_SYSTEM to 1, which
+ # causes an empty header list to be passed to setup_abi_lib, so these
+ # don't get copied on macOS due to that.
+ deps += [ "//libcxxabi/include" ]
+ }
+ outputs = [ "$root_build_dir/include/c++/v1/{{source_target_relative}}" ]
}
}
-# Generate a custom __config header. The new header is created
-# by prepending __config_site to the current __config header.
-action("concat_config") {
- script = "//libcxx/utils/cat_files.py"
- inputs = [
- "$target_gen_dir/__config_site",
- "__config",
- ]
- outputs = [ "$root_build_dir/include/c++/v1/__config" ]
- args = [
- rebase_path("$target_gen_dir/__config_site", root_build_dir),
- rebase_path("__config", root_build_dir),
- "-o",
- rebase_path(outputs[0], root_build_dir)
- ]
- deps = [ ":write_config" ]
+config("include_config") {
+ include_dirs = [ libcxx_generated_include_dir ]
}
-copy("include") {
- sources = [
- "__availability",
- "__bit_reference",
- "__bsd_locale_defaults.h",
- "__bsd_locale_fallbacks.h",
- "__debug",
- "__errc",
- "__functional_03",
- "__functional_base",
- "__functional_base_03",
- "__hash_table",
- "__libcpp_version",
- "__locale",
- "__memory/allocator_traits.h",
- "__memory/base.h",
- "__memory/pointer_traits.h",
- "__memory/utilities.h",
- "__mutex_base",
- "__node_handle",
- "__nullptr",
- "__split_buffer",
- "__sso_allocator",
- "__std_stream",
- "__string",
- "__threading_support",
- "__tree",
- "__tuple",
- "__undef_macros",
- "algorithm",
- "any",
- "array",
- "atomic",
- "barrier",
- "bit",
- "bitset",
- "cassert",
- "ccomplex",
- "cctype",
- "cerrno",
- "cfenv",
- "cfloat",
- "charconv",
- "chrono",
- "cinttypes",
- "ciso646",
- "climits",
- "clocale",
- "cmath",
- "codecvt",
- "compare",
- "complex",
- "complex.h",
- "concepts",
- "condition_variable",
- "csetjmp",
- "csignal",
- "cstdarg",
- "cstdbool",
- "cstddef",
- "cstdint",
- "cstdio",
- "cstdlib",
- "cstring",
- "ctgmath",
- "ctime",
- "ctype.h",
- "cwchar",
- "cwctype",
- "deque",
- "errno.h",
- "exception",
- "execution",
- "experimental/__config",
- "experimental/__memory",
- "experimental/algorithm",
- "experimental/coroutine",
- "experimental/deque",
- "experimental/filesystem",
- "experimental/forward_list",
- "experimental/functional",
- "experimental/iterator",
- "experimental/list",
- "experimental/map",
- "experimental/memory_resource",
- "experimental/propagate_const",
- "experimental/regex",
- "experimental/set",
- "experimental/simd",
- "experimental/string",
- "experimental/type_traits",
- "experimental/unordered_map",
- "experimental/unordered_set",
- "experimental/utility",
- "experimental/vector",
- "ext/__hash",
- "ext/hash_map",
- "ext/hash_set",
- "fenv.h",
- "filesystem",
- "float.h",
- "forward_list",
- "fstream",
- "functional",
- "future",
- "initializer_list",
- "inttypes.h",
- "iomanip",
- "ios",
- "iosfwd",
- "iostream",
- "istream",
- "iterator",
- "latch",
- "limits",
- "limits.h",
- "list",
- "locale",
- "locale.h",
- "map",
- "math.h",
- "memory",
- "module.modulemap",
- "mutex",
- "new",
- "numbers",
- "numeric",
- "optional",
- "ostream",
- "queue",
- "random",
- "ratio",
- "regex",
- "scoped_allocator",
- "semaphore",
- "set",
- "setjmp.h",
- "shared_mutex",
- "span",
- "sstream",
- "stack",
- "stdbool.h",
- "stddef.h",
- "stdexcept",
- "stdint.h",
- "stdio.h",
- "stdlib.h",
- "streambuf",
- "string",
- "string.h",
- "string_view",
- "strstream",
- "__support/android/locale_bionic.h",
- "__support/fuchsia/xlocale.h",
- "__support/ibm/limits.h",
- "__support/ibm/locale_mgmt_aix.h",
- "__support/ibm/nanosleep.h",
- "__support/ibm/support.h",
- "__support/ibm/xlocale.h",
- "__support/musl/xlocale.h",
- "__support/newlib/xlocale.h",
- "__support/nuttx/xlocale.h",
- "__support/openbsd/xlocale.h",
- "__support/solaris/floatingpoint.h",
- "__support/solaris/wchar.h",
- "__support/solaris/xlocale.h",
- "__support/win32/limits_msvc_win32.h",
- "__support/win32/locale_win32.h",
- "__support/xlocale/__nop_locale_mgmt.h",
- "__support/xlocale/__posix_l_fallback.h",
- "__support/xlocale/__strtonum_fallback.h",
- "system_error",
- "tgmath.h",
- "thread",
- "tuple",
- "type_traits",
- "typeindex",
- "typeinfo",
- "unordered_map",
- "unordered_set",
- "utility",
- "valarray",
- "variant",
- "vector",
- "version",
- "wchar.h",
- "wctype.h",
- ]
- deps = [ ":concat_config" ]
- if (target_os != "mac" && target_os != "win") {
- # libcxx/cmake/Modules/HandleLibCXXABI.cmake sets
- # LIBCXX_CXX_ABI_HEADER_TARGET if the libcxx abi library either of
- # "libstdc++", "libsupc++", "libcxxabi", "libcxxrt", but not if it's "none",
- # "default", or "vcruntime". So on Windows, these don't get copied due to
- # LIBCXX_CXX_ABI_HEADER_TARGET not being set.
- # On macOS, libcxx/CMakeLists.txt sets LIBCXX_CXX_ABI_SYSTEM to 1, which
- # causes an empty header list to be passed to setup_abi_lib, so these
- # don't get copied on macOS due to that.
- deps += [ "//libcxxabi/include" ]
- }
- outputs = [ "$root_build_dir/include/c++/v1/{{source_target_relative}}" ]
+group("include") {
+ deps = [ ":copy_headers($default_toolchain)" ]
+ public_configs = [ ":include_config" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/libcxx/src/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/libcxx/src/BUILD.gn
index 7403ebf..e91d9ce 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/libcxx/src/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/libcxx/src/BUILD.gn
@@ -1,4 +1,5 @@
import("//clang/runtimes.gni")
+import("//libcxx/config.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
declare_args() {
@@ -37,10 +38,7 @@
}
config("cxx_config") {
- include_dirs = [
- "//libcxxabi/include",
- "//libcxx/include",
- ]
+ include_dirs = [ "//libcxxabi/include" ]
cflags = [
"-Wall",
"-Wextra",
@@ -54,7 +52,7 @@
"-Wno-covered-switch-default",
]
cflags_cc = [
- "-std=c++17",
+ "-std=c++20",
"-nostdinc++",
]
defines = [ "_LIBCPP_BUILDING_LIBRARY" ]
@@ -122,6 +120,7 @@
"condition_variable.cpp",
"condition_variable_destructor.cpp",
"exception.cpp",
+ "format.cpp",
"functional.cpp",
"future.cpp",
"hash.cpp",
@@ -129,6 +128,7 @@
"include/atomic_support.h",
"include/config_elast.h",
"include/refstring.h",
+ "include/sso_allocator.h",
"ios.cpp",
"ios.instantiations.cpp",
"iostream.cpp",
@@ -175,6 +175,9 @@
if (target_os == "solaris") {
cxx_sources += [ "support/solaris/xlocale.cpp" ]
}
+if (target_os == "zos") {
+ cxx_sources += [ "support/ibm/xlocale_zos.cpp" ]
+}
if (libcxx_enable_debug_mode) {
cxx_sources += [ "debug.cpp" ]
}
@@ -183,6 +186,7 @@
"filesystem/directory_iterator.cpp",
"filesystem/filesystem_common.h",
"filesystem/operations.cpp",
+ "filesystem/posix_compat.h",
]
if (libcxx_use_compiler_rt) {
cxx_sources += [ "filesystem/int128_builtins.cpp" ]
@@ -207,6 +211,7 @@
sources = cxx_sources
deps = [
"//compiler-rt/lib/builtins",
+ "//libcxx/include",
"//libcxxabi/src:cxxabi_shared",
"//libunwind/src:unwind_shared",
]
@@ -256,6 +261,7 @@
}
deps = [
"//compiler-rt/lib/builtins",
+ "//libcxx/include",
"//libcxxabi/src:cxxabi_static",
"//libunwind/src:unwind_static",
]
@@ -272,6 +278,7 @@
output_dir = runtimes_dir
output_name = "c++experimental"
sources = [ "experimental/memory_resource.cpp" ]
+ deps = [ "//libcxx/include" ]
configs += [ ":cxx_config" ]
configs -= [
"//llvm/utils/gn/build:no_exceptions",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/libcxxabi/src/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/libcxxabi/src/BUILD.gn
index 3e6063a..8a981d2 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/libcxxabi/src/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/libcxxabi/src/BUILD.gn
@@ -61,7 +61,9 @@
config("cxxabi_config") {
include_dirs = [
"//libcxxabi/include",
- "//libcxx/include",
+
+ # stdlib_stdexcept.cpp depends on libc++ internals.
+ "//libcxx",
]
cflags_cc = [ "-nostdinc++" ]
defines = [ "_LIBCXXABI_BUILDING_LIBRARY" ]
@@ -86,6 +88,7 @@
public = cxxabi_headers
deps = [
"//compiler-rt/lib/builtins",
+ "//libcxx/include",
"//libunwind/src:unwind_shared",
]
configs += [ ":cxxabi_config" ]
@@ -116,6 +119,7 @@
}
deps = [
"//compiler-rt/lib/builtins",
+ "//libcxx/include",
"//libunwind/src:unwind_static",
]
configs += [ ":cxxabi_config" ]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/libunwind/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/libunwind/BUILD.gn
index 07c3cf0..f66246d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/libunwind/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/libunwind/BUILD.gn
@@ -1,3 +1,16 @@
+import("//llvm/utils/gn/build/toolchain/compiler.gni")
+
+supported_toolchains = [ "//llvm/utils/gn/build/toolchain:stage2_unix" ]
+if (android_ndk_path != "") {
+ supported_toolchains += [
+ "//llvm/utils/gn/build/toolchain:stage2_android_aarch64",
+ "//llvm/utils/gn/build/toolchain:stage2_android_arm",
+ ]
+}
+
group("libunwind") {
- deps = [ "//libunwind/src(//llvm/utils/gn/build/toolchain:stage2_unix)" ]
+ deps = []
+ foreach(toolchain, supported_toolchains) {
+ deps += [ "//libunwind/src($toolchain)" ]
+ }
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/libunwind/src/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/libunwind/src/BUILD.gn
index 6c91b7a..2886929 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/libunwind/src/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/libunwind/src/BUILD.gn
@@ -1,4 +1,5 @@
import("//clang/runtimes.gni")
+import("//compiler-rt/target.gni")
declare_args() {
# Build libunwind as a shared library.
@@ -6,16 +7,13 @@
# Build libunwind as a static library.
libunwind_enable_static = true
-
- # Do not export any symbols from the static library.
- libunwind_hermetic_static_library = true
}
unwind_headers = [
"../include/libunwind.h",
"../include/unwind.h",
]
-if (target_os == "mac") {
+if (current_os == "mac") {
unwind_headers += [
# Make `gn format` not collapse this, for sync_source_lists_from_cmake.py.
"../include/mach-o/compact_unwind_encoding.h",
@@ -44,25 +42,39 @@
"libunwind.cpp",
"libunwind_ext.h",
]
-if (target_os == "mac") {
+if (current_os == "mac") {
unwind_sources += [ "Unwind_AppleExtras.cpp" ]
}
+if (current_os == "android") {
+ if (current_cpu == "arm64") {
+ unwind_output_dir = "$crt_current_out_dir/aarch64"
+ } else if (current_cpu == "arm") {
+ unwind_output_dir = "$crt_current_out_dir/arm"
+ }
+} else {
+ unwind_output_dir = runtimes_dir
+}
+
config("unwind_config") {
cflags = []
cflags_c = [ "-std=c99" ]
cflags_cc = [ "-fno-rtti" ]
+ defines = [ "_LIBUNWIND_IS_NATIVE_ONLY" ]
include_dirs = [ "//libunwind/include" ]
- if (target_os == "mac") {
+ if (current_os == "mac") {
cflags += [ "-U__STRICT_ANSI__" ]
}
+ if (current_os == "android") {
+ defines += [ "_LIBUNWIND_USE_DLADDR=0" ]
+ }
}
if (libunwind_enable_shared) {
shared_library("unwind_shared") {
- output_dir = runtimes_dir
+ output_dir = unwind_output_dir
output_name = "unwind"
- if (target_os == "linux" || target_os == "mac") {
+ if (current_os == "linux" || current_os == "mac") {
cflags = [ "-fPIC" ]
ldflags = [ "-nostdlib++" ]
libs = [
@@ -70,10 +82,10 @@
"pthread",
]
}
- if (target_os == "mac") {
+ if (current_os == "mac") {
ldflags += [
- "-compatibility_version 1",
- "-install_name /usr/lib/libunwind.1.dylib",
+ "-Wl,-compatibility_version,1",
+ "-Wl,-install_name,/usr/lib/libunwind.1.dylib",
]
}
sources = unwind_sources
@@ -88,24 +100,35 @@
}
if (libunwind_enable_static) {
- static_library("unwind_static") {
- output_dir = runtimes_dir
- output_name = "unwind"
- complete_static_lib = true
- configs -= [ "//llvm/utils/gn/build:thin_archive" ]
- sources = unwind_sources
- public = unwind_headers
- if (libunwind_hermetic_static_library) {
- cflags = [ "-fvisibility=hidden" ]
- cflags_cc = [ "-fvisibility-global-new-delete-hidden" ]
- defines = [ "_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS" ]
+ template("libunwind_static_library") {
+ static_library(target_name) {
+ output_dir = unwind_output_dir
+ output_name = invoker.output_name
+ complete_static_lib = true
+ configs -= [ "//llvm/utils/gn/build:thin_archive" ]
+ sources = unwind_sources
+ public = unwind_headers
+ if (!invoker.export) {
+ cflags = [ "-fvisibility=hidden" ]
+ cflags_cc = [ "-fvisibility-global-new-delete-hidden" ]
+ defines = [ "_LIBUNWIND_HIDE_SYMBOLS" ]
+ }
+ deps = [ "//compiler-rt/lib/builtins" ]
+ configs += [ ":unwind_config" ]
+ configs -= [
+ "//llvm/utils/gn/build:no_exceptions",
+ "//llvm/utils/gn/build:no_rtti",
+ ]
}
- deps = [ "//compiler-rt/lib/builtins" ]
- configs += [ ":unwind_config" ]
- configs -= [
- "//llvm/utils/gn/build:no_exceptions",
- "//llvm/utils/gn/build:no_rtti",
- ]
+ }
+
+ libunwind_static_library("unwind_static_exported") {
+ output_name = "unwind-exported"
+ export = true
+ }
+ libunwind_static_library("unwind_static") {
+ output_name = "unwind"
+ export = false
}
}
@@ -115,6 +138,9 @@
deps += [ ":unwind_shared" ]
}
if (libunwind_enable_static) {
- deps += [ ":unwind_static" ]
+ deps += [
+ ":unwind_static",
+ ":unwind_static_exported",
+ ]
}
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/lld/MachO/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/lld/MachO/BUILD.gn
index a55b577..6ed0221 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/lld/MachO/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/lld/MachO/BUILD.gn
@@ -22,18 +22,26 @@
"//libunwind/include",
]
sources = [
+ "Arch/ARM.cpp",
+ "Arch/ARM64.cpp",
+ "Arch/ARM64Common.cpp",
+ "Arch/ARM64_32.cpp",
"Arch/X86_64.cpp",
+ "ConcatOutputSection.cpp",
"Driver.cpp",
"DriverUtils.cpp",
"Dwarf.cpp",
"ExportTrie.cpp",
+ "ICF.cpp",
"InputFiles.cpp",
"InputSection.cpp",
"LTO.cpp",
- "MergedOutputSection.cpp",
+ "MapFile.cpp",
+ "MarkLive.cpp",
"ObjC.cpp",
"OutputSection.cpp",
"OutputSegment.cpp",
+ "Relocations.cpp",
"SymbolTable.cpp",
"Symbols.cpp",
"SyntheticSections.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/lld/test/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/lld/test/BUILD.gn
index bf2f440..7bfbb30 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/lld/test/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/lld/test/BUILD.gn
@@ -1,5 +1,6 @@
import("//llvm/lib/DebugInfo/PDB/enable_dia.gni")
import("//llvm/triples.gni")
+import("//llvm/utils/gn/build/libs/xar/enable.gni")
import("//llvm/utils/gn/build/libs/xml/enable.gni")
import("//llvm/utils/gn/build/libs/zlib/enable.gni")
import("//llvm/utils/gn/build/write_cmake_config.gni")
@@ -14,13 +15,13 @@
"LIT_SITE_CFG_IN_HEADER=## Autogenerated from $input, do not edit",
"LLD_BINARY_DIR=" +
rebase_path(get_label_info("//lld", "target_out_dir")),
+ "LLD_LIBS_DIR=", # FIXME: for shared builds only (?)
+ "LLD_TOOLS_DIR=" + rebase_path("$root_out_dir/bin"),
"LLD_SOURCE_DIR=" + rebase_path("//lld"),
"LLVM_BINARY_DIR=" +
rebase_path(get_label_info("//llvm", "target_out_dir")),
- "LLVM_LIBRARY_OUTPUT_INTDIR=", # FIXME: for shared builds only (?)
"LLVM_LIBS_DIR=", # needed only for shared builds
"LLVM_LIT_TOOLS_DIR=", # Intentionally empty, matches cmake build.
- "LLVM_RUNTIME_OUTPUT_INTDIR=" + rebase_path("$root_out_dir/bin"),
"LLVM_SOURCE_DIR=" + rebase_path("//llvm"),
"LLVM_TOOLS_DIR=" + rebase_path("$root_out_dir/bin"),
"Python3_EXECUTABLE=$python_path",
@@ -37,12 +38,26 @@
extra_values = [ "LLD_DEFAULT_LD_LLD_IS_MINGW=0" ] # Must be 0.
+ if (host_os == "win") {
+ extra_values +=
+ [ "LLVM_LIT_ERRC_MESSAGES=no such file or directory;is a directory;" +
+ "invalid argument;permission denied" ]
+ } else {
+ extra_values += [ "LLVM_LIT_ERRC_MESSAGES=" ]
+ }
+
if (llvm_enable_dia_sdk) {
extra_values += [ "LLVM_ENABLE_DIA_SDK=1" ]
} else {
extra_values += [ "LLVM_ENABLE_DIA_SDK=0" ] # Must be 0.
}
+ if (llvm_enable_libxar) {
+ extra_values += [ "LLVM_HAVE_LIBXAR=1" ]
+ } else {
+ extra_values += [ "LLVM_HAVE_LIBXAR=0" ] # Must be 0.
+ }
+
if (llvm_enable_libxml2) {
extra_values += [ "LLVM_ENABLE_LIBXML2=1" ]
} else {
@@ -79,6 +94,7 @@
":lit_unit_site_cfg",
"//lld/tools/lld:symlinks",
"//lld/unittests",
+ "//llvm/tools/dsymutil",
"//llvm/tools/llc",
"//llvm/tools/llvm-ar:symlinks",
"//llvm/tools/llvm-as",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/lld/tools/lld/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/lld/tools/lld/BUILD.gn
index 51489a4..f593408 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/lld/tools/lld/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/lld/tools/lld/BUILD.gn
@@ -5,6 +5,7 @@
"ld.lld",
"ld64.lld",
"ld64.lld.darwinnew",
+ "ld64.lld.darwinold",
"wasm-ld",
]
foreach(target, symlinks) {
@@ -33,6 +34,7 @@
"//lld/lib/Driver",
"//lld/wasm",
"//llvm/lib/Support",
+ "//llvm/utils/gn/build/libs/xar",
]
sources = [ "lld.cpp" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/lld/wasm/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/lld/wasm/BUILD.gn
index 98bc93e..8384dd9b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/lld/wasm/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/lld/wasm/BUILD.gn
@@ -25,6 +25,7 @@
"MapFile.cpp",
"MarkLive.cpp",
"OutputSections.cpp",
+ "OutputSegment.cpp",
"Relocations.cpp",
"SymbolTable.cpp",
"Symbols.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
index 389d5e9..178b71d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
@@ -88,6 +88,7 @@
"HAVE_LIBPFM=",
"HAVE_LIBPSAPI=",
"HAVE_MALLCTL=",
+ "HAVE_MALLINFO2=",
"HAVE_SIGNAL_H=1",
"HAVE_STD_IS_TRIVIALLY_COPYABLE=1",
"HAVE_STRERROR=1",
@@ -126,9 +127,6 @@
"LLVM_GISEL_COV_ENABLED=",
"LLVM_GISEL_COV_PREFIX=",
- # FIXME: Set to 1 on mac once the 10.14 SDK is in common use.
- "LLVM_SUPPORT_XCODE_SIGNPOSTS=",
-
# This is both in llvm-config.h and config.h; llvm-config.h doesn't
# define it if it's not set while config.h defines it to empty in that case.
"LLVM_DEFAULT_TARGET_TRIPLE=$llvm_target_triple",
@@ -162,6 +160,7 @@
"HAVE_MACH_MACH_H=1",
"HAVE_MALLOC_MALLOC_H=1",
"HAVE_MALLOC_ZONE_STATISTICS=1",
+ "HAVE_PROC_PID_RUSAGE=1",
"HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1",
]
} else {
@@ -172,6 +171,7 @@
"HAVE_MACH_MACH_H=",
"HAVE_MALLOC_MALLOC_H=",
"HAVE_MALLOC_ZONE_STATISTICS=",
+ "HAVE_PROC_PID_RUSAGE=",
"HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=",
]
}
@@ -276,12 +276,16 @@
}
if (current_os == "mac") {
- values += [ "LTDL_SHLIB_EXT=.dylib" ]
+ shlib_ext = ".dylib"
} else if (current_os == "win") {
- values += [ "LTDL_SHLIB_EXT=.dll" ]
+ shlib_ext = ".dll"
} else {
- values += [ "LTDL_SHLIB_EXT=.so" ]
+ shlib_ext = ".so"
}
+ values += [
+ "LLVM_PLUGIN_EXT=$shlib_ext",
+ "LTDL_SHLIB_EXT=$shlib_ext",
+ ]
if (llvm_enable_libedit) {
values += [ "HAVE_LIBEDIT=1" ]
@@ -289,12 +293,6 @@
values += [ "HAVE_LIBEDIT=" ]
}
- if (llvm_enable_libxar) {
- values += [ "HAVE_LIBXAR=1" ]
- } else {
- values += [ "HAVE_LIBXAR=" ]
- }
-
if (llvm_enable_terminfo) {
values += [ "LLVM_ENABLE_TERMINFO=1" ]
} else {
@@ -324,8 +322,9 @@
input = "llvm-config.h.cmake"
output = "$target_gen_dir/llvm-config.h"
values = [
- "LLVM_ENABLE_DUMP=",
"LLVM_DEFAULT_TARGET_TRIPLE=$llvm_target_triple",
+ "LLVM_ENABLE_DUMP=",
+ "LLVM_ENABLE_NEW_PASS_MANAGER=1",
"LLVM_FORCE_ENABLE_STATS=",
"LLVM_HAS_ATOMICS=1",
"LLVM_HAVE_TF_AOT=",
@@ -338,6 +337,10 @@
"LLVM_NATIVE_TARGET=1",
"LLVM_NATIVE_TARGETINFO=1",
"LLVM_NATIVE_TARGETMC=1",
+
+ # FIXME: Set to 1 on mac once the 10.14 SDK is in common use.
+ "LLVM_SUPPORT_XCODE_SIGNPOSTS=",
+
"LLVM_USE_INTEL_JITEVENTS=",
"LLVM_USE_OPROFILE=",
"LLVM_USE_PERF=",
@@ -346,7 +349,6 @@
"LLVM_VERSION_PATCH=$llvm_version_patch",
"LLVM_WITH_Z3=",
"PACKAGE_VERSION=${llvm_version}git",
- "LLVM_ENABLE_NEW_PASS_MANAGER=",
]
if (current_os == "win") {
@@ -361,6 +363,12 @@
]
}
+ if (llvm_enable_libxar) {
+ values += [ "LLVM_HAVE_LIBXAR=1" ]
+ } else {
+ values += [ "LLVM_HAVE_LIBXAR=" ]
+ }
+
if (llvm_enable_threads) {
values += [ "LLVM_ENABLE_THREADS=1" ]
} else {
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenACC/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenACC/BUILD.gn
index 995b7f2..c6d80b2 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenACC/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenACC/BUILD.gn
@@ -8,7 +8,7 @@
tablegen("ACCcpp") {
visibility = [ ":acc_gen" ]
- args = [ "-gen-directive-gen" ]
+ args = [ "-gen-directive-impl" ]
output_name = "ACC.inc"
td_file = "ACC.td"
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenMP/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenMP/BUILD.gn
index bb1c880..d99b8b5 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenMP/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/include/llvm/Frontend/OpenMP/BUILD.gn
@@ -9,7 +9,7 @@
tablegen("OMP") {
visibility = [ ":public_tablegen" ]
- args = [ "-gen-directive-gen" ]
+ args = [ "-gen-directive-impl" ]
}
# Groups all tablegen() calls that create .inc files that are included in
@@ -19,7 +19,7 @@
group("public_tablegen") {
public_deps = [
# Frontend/OpenMP's public headers include OMP.h.inc.
- ":OMPh",
":OMP",
+ ":OMPh",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
index acb8389..e0c30c0 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
@@ -95,6 +95,7 @@
"ObjCARCAnalysisUtils.cpp",
"ObjCARCInstKind.cpp",
"OptimizationRemarkEmitter.cpp",
+ "OverflowInstAnalysis.cpp",
"PHITransAddr.cpp",
"PhiValues.cpp",
"PostDominators.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/BinaryFormat/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/BinaryFormat/BUILD.gn
index 50afba0..a70ffd1 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/BinaryFormat/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/BinaryFormat/BUILD.gn
@@ -4,6 +4,7 @@
sources = [
"AMDGPUMetadataVerifier.cpp",
"Dwarf.cpp",
+ "ELF.cpp",
"MachO.cpp",
"Magic.cpp",
"Minidump.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
index 49cbd51..2022477 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/BUILD.gn
@@ -26,7 +26,6 @@
"BranchFolding.cpp",
"BranchRelaxation.cpp",
"BreakFalseDeps.cpp",
- "BuiltinGCs.cpp",
"CFGuardLongjmp.cpp",
"CFIInstrInserter.cpp",
"CalcSpillWeights.cpp",
@@ -40,12 +39,14 @@
"DeadMachineInstructionElim.cpp",
"DetectDeadLanes.cpp",
"DwarfEHPrepare.cpp",
+ "EHContGuardCatchret.cpp",
"EarlyIfConversion.cpp",
"EdgeBundles.cpp",
"ExecutionDomainFix.cpp",
"ExpandMemCmp.cpp",
"ExpandPostRAPseudos.cpp",
"ExpandReductions.cpp",
+ "ExpandVectorPredication.cpp",
"FEntryInserter.cpp",
"FaultMaps.cpp",
"FinalizeISel.cpp",
@@ -54,7 +55,6 @@
"GCMetadata.cpp",
"GCMetadataPrinter.cpp",
"GCRootLowering.cpp",
- "GCStrategy.cpp",
"GlobalMerge.cpp",
"HardwareLoops.cpp",
"IfConversion.cpp",
@@ -91,10 +91,12 @@
"LowerEmuTLS.cpp",
"MBFIWrapper.cpp",
"MIRCanonicalizerPass.cpp",
+ "MIRFSDiscriminator.cpp",
"MIRNamerPass.cpp",
"MIRPrinter.cpp",
"MIRPrintingPass.cpp",
"MIRVRegNamerUtils.cpp",
+ "MIRYamlMapping.cpp",
"MachineBasicBlock.cpp",
"MachineBlockFrequencyInfo.cpp",
"MachineBlockPlacement.cpp",
@@ -118,6 +120,7 @@
"MachineLoopUtils.cpp",
"MachineModuleInfo.cpp",
"MachineModuleInfoImpls.cpp",
+ "MachineModuleSlotTracker.cpp",
"MachineOperand.cpp",
"MachineOptimizationRemarkEmitter.cpp",
"MachineOutliner.cpp",
@@ -167,7 +170,9 @@
"RegisterPressure.cpp",
"RegisterScavenging.cpp",
"RegisterUsageInfo.cpp",
+ "RemoveRedundantDebugValues.cpp",
"RenameIndependentSubregs.cpp",
+ "ReplaceWithVeclib.cpp",
"ResetMachineFunctionPass.cpp",
"SafeStack.cpp",
"SafeStackLayout.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/GlobalISel/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/GlobalISel/BUILD.gn
index dad5ee8..57144b2 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/GlobalISel/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/CodeGen/GlobalISel/BUILD.gn
@@ -24,6 +24,7 @@
"InlineAsmLowering.cpp",
"InstructionSelect.cpp",
"InstructionSelector.cpp",
+ "LegacyLegalizerInfo.cpp",
"LegalityPredicates.cpp",
"LegalizeMutations.cpp",
"Legalizer.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/DWP/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/DWP/BUILD.gn
new file mode 100644
index 0000000..3212591
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/DWP/BUILD.gn
@@ -0,0 +1,14 @@
+static_library("DWP") {
+ output_name = "LLVMDWP"
+ deps = [
+ "//llvm/lib/DebugInfo/DWARF",
+ "//llvm/lib/MC",
+ "//llvm/lib/Object",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target",
+ ]
+ sources = [
+ "DWP.cpp",
+ "DWPError.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Demangle/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Demangle/BUILD.gn
index 81ddb6c..bf10f6c 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Demangle/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Demangle/BUILD.gn
@@ -6,5 +6,6 @@
"ItaniumDemangle.cpp",
"MicrosoftDemangle.cpp",
"MicrosoftDemangleNodes.cpp",
+ "RustDemangle.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/BUILD.gn
index ac73dd4..a612bf4 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/BUILD.gn
@@ -6,6 +6,7 @@
"//llvm/include/llvm/Config:llvm-config",
]
deps = [
+ "//llvm/lib/ExecutionEngine/Orc/TargetProcess",
"//llvm/lib/IR",
"//llvm/lib/MC",
"//llvm/lib/Object",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn
index a0af193..8319651 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/JITLink/BUILD.gn
@@ -9,6 +9,8 @@
sources = [
"EHFrameSupport.cpp",
"ELF.cpp",
+ "ELFLinkGraphBuilder.cpp",
+ "ELF_riscv.cpp",
"ELF_x86_64.cpp",
"JITLink.cpp",
"JITLinkGeneric.cpp",
@@ -17,5 +19,7 @@
"MachOLinkGraphBuilder.cpp",
"MachO_arm64.cpp",
"MachO_x86_64.cpp",
+ "riscv.cpp",
+ "x86_64.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn
index c64a3f8..41226d6 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/BUILD.gn
@@ -16,8 +16,14 @@
"CompileOnDemandLayer.cpp",
"CompileUtils.cpp",
"Core.cpp",
+ "DebugObjectManagerPlugin.cpp",
"DebugUtils.cpp",
+ "EPCDebugObjectRegistrar.cpp",
+ "EPCDynamicLibrarySearchGenerator.cpp",
+ "EPCEHFrameRegistrar.cpp",
+ "EPCIndirectionUtils.cpp",
"ExecutionUtils.cpp",
+ "ExecutorProcessControl.cpp",
"IRCompileLayer.cpp",
"IRTransformLayer.cpp",
"IndirectionUtils.cpp",
@@ -34,10 +40,6 @@
"RTDyldObjectLinkingLayer.cpp",
"SpeculateAnalyses.cpp",
"Speculation.cpp",
- "TPCDynamicLibrarySearchGenerator.cpp",
- "TPCEHFrameRegistrar.cpp",
- "TPCIndirectionUtils.cpp",
- "TargetProcessControl.cpp",
"ThreadSafeModule.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Shared/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Shared/BUILD.gn
index 812e79d..e9d48a1 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Shared/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/Shared/BUILD.gn
@@ -4,6 +4,5 @@
sources = [
"OrcError.cpp",
"RPCError.cpp",
- "TargetProcessControlTypes.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/TargetProcess/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/TargetProcess/BUILD.gn
index f885fac..29d894b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/TargetProcess/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ExecutionEngine/Orc/TargetProcess/BUILD.gn
@@ -5,6 +5,7 @@
"//llvm/lib/Support",
]
sources = [
+ "JITLoaderGDB.cpp",
"RegisterEHFrames.cpp",
"TargetExecutionUtils.cpp",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenACC/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenACC/BUILD.gn
index 51b8c26..f37bed7 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenACC/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenACC/BUILD.gn
@@ -1,18 +1,8 @@
import("//llvm/utils/TableGen/tablegen.gni")
-tablegen("ACCImpl") {
- visibility = [ ":OpenACC" ]
- args = [ "-gen-directive-impl" ]
- td_file = "//llvm/include/llvm/Frontend/OpenACC/ACC.td"
- output_name = "ACC.cpp"
-}
-
static_library("OpenACC") {
output_name = "LLVMFrontendOpenACC"
- deps = [
- ":ACCImpl",
- "//llvm/lib/Support",
- ]
+ deps = [ "//llvm/lib/Support" ]
public_deps = [ "//llvm/include/llvm/Frontend/OpenACC:acc_gen" ]
- sources = get_target_outputs(":ACCImpl")
+ sources = [ "ACC.cpp" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenMP/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenMP/BUILD.gn
index 579e37c..d061eda 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenMP/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Frontend/OpenMP/BUILD.gn
@@ -1,23 +1,16 @@
import("//llvm/utils/TableGen/tablegen.gni")
-tablegen("OMPImpl") {
- visibility = [ ":OpenMP" ]
- args = [ "-gen-directive-impl" ]
- td_file = "//llvm/include/llvm/Frontend/OpenMP/OMP.td"
- output_name = "OMP.cpp"
-}
-
static_library("OpenMP") {
output_name = "LLVMFrontendOpenMP"
deps = [
- ":OMPImpl",
"//llvm/lib/IR",
"//llvm/lib/Support",
"//llvm/lib/Transforms/Utils",
]
public_deps = [ "//llvm/include/llvm/Frontend/OpenMP:public_tablegen" ]
sources = [
- "OMPContext.cpp",
- "OMPIRBuilder.cpp",
- ] + get_target_outputs(":OMPImpl")
+ "OMP.cpp",
+ "OMPContext.cpp",
+ "OMPIRBuilder.cpp",
+ ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
index afe67a1..3b08735 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn
@@ -20,6 +20,7 @@
"Attributes.cpp",
"AutoUpgrade.cpp",
"BasicBlock.cpp",
+ "BuiltinGCs.cpp",
"Comdat.cpp",
"ConstantFold.cpp",
"ConstantRange.cpp",
@@ -36,6 +37,7 @@
"Dominators.cpp",
"FPEnv.cpp",
"Function.cpp",
+ "GCStrategy.cpp",
"GVMaterializer.cpp",
"Globals.cpp",
"IRBuilder.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/InterfaceStub/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/InterfaceStub/BUILD.gn
index 4778cb5..1e9fb07 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/InterfaceStub/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/InterfaceStub/BUILD.gn
@@ -7,7 +7,7 @@
sources = [
"ELFObjHandler.cpp",
- "ELFStub.cpp",
- "TBEHandler.cpp",
+ "IFSHandler.cpp",
+ "IFSStub.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/BUILD.gn
index 9aa3f85..f538c86 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/BUILD.gn
@@ -2,6 +2,7 @@
output_name = "LLVMMC"
deps = [
"//llvm/include/llvm/Config:config",
+ "//llvm/lib/BinaryFormat",
"//llvm/lib/DebugInfo/CodeView",
"//llvm/lib/Support",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/MCParser/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/MCParser/BUILD.gn
index 8eaacc8..19de757 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/MCParser/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MC/MCParser/BUILD.gn
@@ -18,5 +18,6 @@
"MCTargetAsmParser.cpp",
"MasmParser.cpp",
"WasmAsmParser.cpp",
+ "XCOFFAsmParser.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MCA/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MCA/BUILD.gn
index 6aaa993..9e56116 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MCA/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/MCA/BUILD.gn
@@ -9,6 +9,7 @@
sources = [
"CodeEmitter.cpp",
"Context.cpp",
+ "CustomBehaviour.cpp",
"HWEventListener.cpp",
"HardwareUnits/HardwareUnit.cpp",
"HardwareUnits/LSUnit.cpp",
@@ -22,6 +23,7 @@
"Stages/DispatchStage.cpp",
"Stages/EntryStage.cpp",
"Stages/ExecuteStage.cpp",
+ "Stages/InOrderIssueStage.cpp",
"Stages/InstructionTables.cpp",
"Stages/MicroOpQueueStage.cpp",
"Stages/RetireStage.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Object/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Object/BUILD.gn
index 42dde29..122ed64 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Object/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Object/BUILD.gn
@@ -23,6 +23,7 @@
"ELF.cpp",
"ELFObjectFile.cpp",
"Error.cpp",
+ "FaultMapParser.cpp",
"IRObjectFile.cpp",
"IRSymtab.cpp",
"MachOObjectFile.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn
index 0f6c2e8..b02ac5e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/ObjectYAML/BUILD.gn
@@ -26,6 +26,7 @@
"ObjectYAML.cpp",
"WasmEmitter.cpp",
"WasmYAML.cpp",
+ "XCOFFEmitter.cpp",
"XCOFFYAML.cpp",
"YAML.cpp",
"yaml2obj.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Passes/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Passes/BUILD.gn
index bb8a671..ff5238b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Passes/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Passes/BUILD.gn
@@ -8,7 +8,6 @@
"//llvm/lib/Target",
"//llvm/lib/Transforms/AggressiveInstCombine",
"//llvm/lib/Transforms/Coroutines",
- "//llvm/lib/Transforms/HelloNew",
"//llvm/lib/Transforms/IPO",
"//llvm/lib/Transforms/InstCombine",
"//llvm/lib/Transforms/Instrumentation",
@@ -19,6 +18,7 @@
]
sources = [
"PassBuilder.cpp",
+ "PassBuilderBindings.cpp",
"PassPlugin.cpp",
"StandardInstrumentations.cpp",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
index a9a19d0..476353e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
@@ -43,6 +43,7 @@
"ARMTargetParser.cpp",
"ARMWinEH.cpp",
"Allocator.cpp",
+ "AutoConvert.cpp",
"BinaryStreamError.cpp",
"BinaryStreamReader.cpp",
"BinaryStreamRef.cpp",
@@ -110,6 +111,7 @@
"RandomNumberGenerator.cpp",
"Regex.cpp",
"SHA1.cpp",
+ "SHA256.cpp",
"ScaledNumber.cpp",
"ScopedPrinter.cpp",
"Signposts.cpp",
@@ -134,6 +136,7 @@
"TrigramIndex.cpp",
"Triple.cpp",
"Twine.cpp",
+ "TypeSize.cpp",
"Unicode.cpp",
"UnicodeCaseFold.cpp",
"VersionTuple.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn
index d2fe579..fda5320 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AArch64/BUILD.gn
@@ -18,6 +18,15 @@
td_file = "AArch64.td"
}
+tablegen("AArch64GenO0PreLegalizeGICombiner") {
+ visibility = [ ":LLVMAArch64CodeGen" ]
+ args = [
+ "-gen-global-isel-combiner",
+ "-combiners=AArch64O0PreLegalizerCombinerHelper",
+ ]
+ td_file = "AArch64.td"
+}
+
tablegen("AArch64GenGlobalISel") {
visibility = [ ":LLVMAArch64CodeGen" ]
args = [ "-gen-global-isel" ]
@@ -70,6 +79,7 @@
":AArch64GenFastISel",
":AArch64GenGlobalISel",
":AArch64GenMCPseudoLowering",
+ ":AArch64GenO0PreLegalizeGICombiner",
":AArch64GenPostLegalizeGICombiner",
":AArch64GenPostLegalizeGILowering",
":AArch64GenPreLegalizeGICombiner",
@@ -117,6 +127,7 @@
"AArch64ISelLowering.cpp",
"AArch64InstrInfo.cpp",
"AArch64LoadStoreOptimizer.cpp",
+ "AArch64LowerHomogeneousPrologEpilog.cpp",
"AArch64MCInstLower.cpp",
"AArch64MachineFunctionInfo.cpp",
"AArch64MacroFusion.cpp",
@@ -136,8 +147,10 @@
"AArch64TargetObjectFile.cpp",
"AArch64TargetTransformInfo.cpp",
"GISel/AArch64CallLowering.cpp",
+ "GISel/AArch64GlobalISelUtils.cpp",
"GISel/AArch64InstructionSelector.cpp",
"GISel/AArch64LegalizerInfo.cpp",
+ "GISel/AArch64O0PreLegalizerCombiner.cpp",
"GISel/AArch64PostLegalizerCombiner.cpp",
"GISel/AArch64PostLegalizerLowering.cpp",
"GISel/AArch64PostSelectOptimize.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn
index 40b6143..058a17b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/BUILD.gn
@@ -128,6 +128,7 @@
"AMDGPUArgumentUsageInfo.cpp",
"AMDGPUAsmPrinter.cpp",
"AMDGPUAtomicOptimizer.cpp",
+ "AMDGPUAttributor.cpp",
"AMDGPUCallLowering.cpp",
"AMDGPUCodeGenPrepare.cpp",
"AMDGPUExportClustering.cpp",
@@ -147,6 +148,7 @@
"AMDGPULowerIntrinsics.cpp",
"AMDGPULowerKernelArguments.cpp",
"AMDGPULowerKernelAttributes.cpp",
+ "AMDGPULowerModuleLDSPass.cpp",
"AMDGPUMCInstLower.cpp",
"AMDGPUMIRFormatter.cpp",
"AMDGPUMachineCFGStructurizer.cpp",
@@ -162,6 +164,8 @@
"AMDGPUPropagateAttributes.cpp",
"AMDGPURegBankCombiner.cpp",
"AMDGPURegisterBankInfo.cpp",
+ "AMDGPUReplaceLDSUseWithPointer.cpp",
+ "AMDGPUResourceUsageAnalysis.cpp",
"AMDGPURewriteOutArguments.cpp",
"AMDGPUSubtarget.cpp",
"AMDGPUTargetMachine.cpp",
@@ -176,7 +180,7 @@
"GCNIterativeScheduler.cpp",
"GCNMinRegStrategy.cpp",
"GCNNSAReassign.cpp",
- "GCNRegBankReassign.cpp",
+ "GCNPreRAOptimizations.cpp",
"GCNRegPressure.cpp",
"GCNSchedStrategy.cpp",
"R600AsmPrinter.cpp",
@@ -193,7 +197,6 @@
"R600OptimizeVectorRegisters.cpp",
"R600Packetizer.cpp",
"R600RegisterInfo.cpp",
- "SIAddIMGInit.cpp",
"SIAnnotateControlFlow.cpp",
"SIFixSGPRCopies.cpp",
"SIFixVGPRCopies.cpp",
@@ -202,9 +205,9 @@
"SIFrameLowering.cpp",
"SIISelLowering.cpp",
"SIInsertHardClauses.cpp",
- "SIInsertSkips.cpp",
"SIInsertWaitcnts.cpp",
"SIInstrInfo.cpp",
+ "SILateBranchLowering.cpp",
"SILoadStoreOptimizer.cpp",
"SILowerControlFlow.cpp",
"SILowerI1Copies.cpp",
@@ -215,13 +218,13 @@
"SIModeRegister.cpp",
"SIOptimizeExecMasking.cpp",
"SIOptimizeExecMaskingPreRA.cpp",
+ "SIOptimizeVGPRLiveRange.cpp",
"SIPeepholeSDWA.cpp",
"SIPostRABundler.cpp",
"SIPreAllocateWWMRegs.cpp",
"SIPreEmitPeephole.cpp",
"SIProgramInfo.cpp",
"SIRegisterInfo.cpp",
- "SIRemoveShortExecBranches.cpp",
"SIShrinkInstructions.cpp",
"SIWholeQuadMode.cpp",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/Utils/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/Utils/BUILD.gn
index 41c6162..5e1a385 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/Utils/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AMDGPU/Utils/BUILD.gn
@@ -25,6 +25,7 @@
sources = [
"AMDGPUAsmUtils.cpp",
"AMDGPUBaseInfo.cpp",
+ "AMDGPULDSUtils.cpp",
"AMDGPUPALMetadata.cpp",
"AMDKernelCodeTUtils.cpp",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn
index e98d3a7..272da88 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/ARM/BUILD.gn
@@ -58,6 +58,7 @@
"//llvm/lib/Support",
"//llvm/lib/Target",
"//llvm/lib/Transforms/CFGuard",
+ "//llvm/lib/Transforms/IPO",
"//llvm/lib/Transforms/Utils",
]
include_dirs = [ "." ]
@@ -98,9 +99,10 @@
"ARMTargetTransformInfo.cpp",
"MLxExpansionPass.cpp",
"MVEGatherScatterLowering.cpp",
+ "MVELaneInterleavingPass.cpp",
+ "MVETPAndVPTOptimisationsPass.cpp",
"MVETailPredication.cpp",
"MVEVPTBlockPass.cpp",
- "MVEVPTOptimisationsPass.cpp",
"Thumb1FrameLowering.cpp",
"Thumb1InstrInfo.cpp",
"Thumb2ITBlockPass.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AVR/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AVR/BUILD.gn
index 40ab437..223d171 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AVR/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/AVR/BUILD.gn
@@ -38,6 +38,7 @@
"AVRMCInstLower.cpp",
"AVRRegisterInfo.cpp",
"AVRRelaxMemOperations.cpp",
+ "AVRShiftExpand.cpp",
"AVRSubtarget.cpp",
"AVRTargetMachine.cpp",
"AVRTargetObjectFile.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn
index e0145fe..7ca9032 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/NVPTX/BUILD.gn
@@ -30,6 +30,7 @@
"NVPTXAllocaHoisting.cpp",
"NVPTXAsmPrinter.cpp",
"NVPTXAssignValidGlobalNames.cpp",
+ "NVPTXAtomicLower.cpp",
"NVPTXFrameLowering.cpp",
"NVPTXGenericToNVVM.cpp",
"NVPTXISelDAGToDAG.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn
index 9adb514..209b342 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/BUILD.gn
@@ -65,6 +65,7 @@
"PPCCTRLoops.cpp",
"PPCCallingConv.cpp",
"PPCEarlyReturn.cpp",
+ "PPCExpandAtomicPseudoInsts.cpp",
"PPCExpandISEL.cpp",
"PPCFastISel.cpp",
"PPCFrameLowering.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/MCTargetDesc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/MCTargetDesc/BUILD.gn
index e587529..a8ec32e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/MCTargetDesc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/PowerPC/MCTargetDesc/BUILD.gn
@@ -60,5 +60,6 @@
"PPCMCTargetDesc.cpp",
"PPCPredicates.cpp",
"PPCXCOFFObjectWriter.cpp",
+ "PPCXCOFFStreamer.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn
index 366623c..08a8855 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/BUILD.gn
@@ -63,12 +63,12 @@
sources = [
"RISCVAsmPrinter.cpp",
"RISCVCallLowering.cpp",
- "RISCVCleanupVSETVLI.cpp",
"RISCVExpandAtomicPseudoInsts.cpp",
"RISCVExpandPseudoInsts.cpp",
"RISCVFrameLowering.cpp",
"RISCVISelDAGToDAG.cpp",
"RISCVISelLowering.cpp",
+ "RISCVInsertVSETVLI.cpp",
"RISCVInstrInfo.cpp",
"RISCVInstructionSelector.cpp",
"RISCVLegalizerInfo.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn
index 47d5268..a600684 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/RISCV/MCTargetDesc/BUILD.gn
@@ -40,9 +40,7 @@
# by other targets. .inc files only used by .cpp files in this directory
# should be in deps on the static_library instead.
group("tablegen") {
- visibility = [
- ":MCTargetDesc",
- ]
+ visibility = [ ":MCTargetDesc" ]
public_deps = [
":RISCVGenInstrInfo",
":RISCVGenRegisterInfo",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/AsmParser/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/AsmParser/BUILD.gn
index d7180b5..5747742 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/AsmParser/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/AsmParser/BUILD.gn
@@ -15,7 +15,11 @@
"//llvm/lib/Support",
"//llvm/lib/Target/WebAssembly/MCTargetDesc",
"//llvm/lib/Target/WebAssembly/TargetInfo",
+ "//llvm/lib/Target/WebAssembly/Utils",
]
include_dirs = [ ".." ]
- sources = [ "WebAssemblyAsmParser.cpp" ]
+ sources = [
+ "WebAssemblyAsmParser.cpp",
+ "WebAssemblyAsmTypeCheck.cpp",
+ ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn
index dba1f98..39cfa79 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/BUILD.gn
@@ -53,8 +53,10 @@
"WebAssemblyLowerEmscriptenEHSjLj.cpp",
"WebAssemblyLowerGlobalDtors.cpp",
"WebAssemblyMCInstLower.cpp",
+ "WebAssemblyMCLowerPrePass.cpp",
"WebAssemblyMachineFunctionInfo.cpp",
"WebAssemblyMemIntrinsicResults.cpp",
+ "WebAssemblyNullifyDebugValueLists.cpp",
"WebAssemblyOptimizeLiveIntervals.cpp",
"WebAssemblyOptimizeReturned.cpp",
"WebAssemblyPeephole.cpp",
@@ -72,7 +74,6 @@
"WebAssemblyTargetMachine.cpp",
"WebAssemblyTargetObjectFile.cpp",
"WebAssemblyTargetTransformInfo.cpp",
- "WebAssemblyUtilities.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Disassembler/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Disassembler/BUILD.gn
index 8a86b67..e78002e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Disassembler/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Disassembler/BUILD.gn
@@ -15,6 +15,7 @@
"//llvm/lib/Support",
"//llvm/lib/Target/WebAssembly/MCTargetDesc",
"//llvm/lib/Target/WebAssembly/TargetInfo",
+ "//llvm/lib/Target/WebAssembly/Utils",
]
include_dirs = [ ".." ]
sources = [ "WebAssemblyDisassembler.cpp" ]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/MCTargetDesc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/MCTargetDesc/BUILD.gn
index 2249138..22d9ae8 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/MCTargetDesc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/MCTargetDesc/BUILD.gn
@@ -13,7 +13,7 @@
}
tablegen("WebAssemblyGenRegisterInfo") {
- visibility = [ ":MCTargetDesc" ]
+ visibility = [ ":tablegen" ]
args = [ "-gen-register-info" ]
td_file = "../WebAssembly.td"
}
@@ -24,6 +24,17 @@
td_file = "../WebAssembly.td"
}
+# This should contain tablegen targets generating .inc files included
+# by other targets. .inc files only used by .cpp files in this directory
+# should be in deps on the static_library instead.
+group("tablegen") {
+ visibility = [
+ ":MCTargetDesc",
+ "../Utils",
+ ]
+ public_deps = [ ":WebAssemblyGenRegisterInfo" ]
+}
+
static_library("MCTargetDesc") {
output_name = "LLVMWebAssemblyDesc"
@@ -31,8 +42,8 @@
# by other targets. .inc files only used by .cpp files in this directory
# should be in deps instead.
public_deps = [
- ":WebAssemblyGenRegisterInfo",
":WebAssemblyGenSubtargetInfo",
+ ":tablegen",
]
deps = [
":WebAssemblyGenAsmWriter",
@@ -40,6 +51,7 @@
"//llvm/lib/MC",
"//llvm/lib/Support",
"//llvm/lib/Target/WebAssembly/TargetInfo",
+ "//llvm/lib/Target/WebAssembly/Utils",
]
include_dirs = [ ".." ]
sources = [
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Utils/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Utils/BUILD.gn
new file mode 100644
index 0000000..b37a00a
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/WebAssembly/Utils/BUILD.gn
@@ -0,0 +1,19 @@
+static_library("Utils") {
+ output_name = "LLVMWebAssemblyUtils"
+ deps = [
+ "//llvm/lib/CodeGen",
+ "//llvm/lib/IR",
+ "//llvm/lib/MC",
+ "//llvm/lib/Support",
+
+ # MCTargetDesc depends on Utils, so we can't depend on the full
+ # MCTargetDesc target here: it would form a cycle.
+ "//llvm/lib/Target/WebAssembly/MCTargetDesc:tablegen",
+ "//llvm/lib/Target/WebAssembly/TargetInfo",
+ ]
+ include_dirs = [ ".." ]
+ sources = [
+ "WebAssemblyTypeUtilities.cpp",
+ "WebAssemblyUtilities.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn
index dee40f4..876d051 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/X86/BUILD.gn
@@ -87,6 +87,7 @@
"X86EvexToVex.cpp",
"X86ExpandPseudo.cpp",
"X86FastISel.cpp",
+ "X86FastTileConfig.cpp",
"X86FixupBWInsts.cpp",
"X86FixupLEAs.cpp",
"X86FixupSetCC.cpp",
@@ -108,13 +109,16 @@
"X86LegalizerInfo.cpp",
"X86LoadValueInjectionLoadHardening.cpp",
"X86LoadValueInjectionRetHardening.cpp",
+ "X86LowerAMXIntrinsics.cpp",
"X86LowerAMXType.cpp",
+ "X86LowerTileCopy.cpp",
"X86MCInstLower.cpp",
"X86MachineFunctionInfo.cpp",
"X86MacroFusion.cpp",
"X86OptimizeLEAs.cpp",
"X86PadShortFunction.cpp",
"X86PartialReduction.cpp",
+ "X86PreAMXConfig.cpp",
"X86PreTileConfig.cpp",
"X86RegisterBankInfo.cpp",
"X86RegisterInfo.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/targets.gni b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/targets.gni
index 102040c2..22da518 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/targets.gni
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Target/targets.gni
@@ -49,6 +49,7 @@
llvm_build_BPF = false
llvm_build_Mips = false
llvm_build_PowerPC = false
+llvm_build_SystemZ = false
llvm_build_WebAssembly = false
llvm_build_X86 = false
foreach(target, llvm_targets_to_build) {
@@ -64,6 +65,8 @@
llvm_build_Mips = true
} else if (target == "PowerPC") {
llvm_build_PowerPC = true
+ } else if (target == "SystemZ") {
+ llvm_build_SystemZ = true
} else if (target == "WebAssembly") {
llvm_build_WebAssembly = true
} else if (target == "X86") {
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/TextAPI/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/TextAPI/BUILD.gn
index 6df06f9..2a508a0 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/TextAPI/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/TextAPI/BUILD.gn
@@ -4,16 +4,15 @@
"//llvm/lib/BinaryFormat",
"//llvm/lib/Support",
]
- include_dirs = [ "." ]
sources = [
- "MachO/Architecture.cpp",
- "MachO/ArchitectureSet.cpp",
- "MachO/InterfaceFile.cpp",
- "MachO/PackedVersion.cpp",
- "MachO/Platform.cpp",
- "MachO/Symbol.cpp",
- "MachO/Target.cpp",
- "MachO/TextStub.cpp",
- "MachO/TextStubCommon.cpp",
+ "Architecture.cpp",
+ "ArchitectureSet.cpp",
+ "InterfaceFile.cpp",
+ "PackedVersion.cpp",
+ "Platform.cpp",
+ "Symbol.cpp",
+ "Target.cpp",
+ "TextStub.cpp",
+ "TextStubCommon.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
index 5ed1019..a55d956 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Hello/BUILD.gn
@@ -1,8 +1,16 @@
+import("//llvm/utils/gn/build/symbol_exports.gni")
+
assert(host_os != "win", "loadable modules not supported on win")
+symbol_exports("exports") {
+ exports_file = "Hello.exports"
+}
+
loadable_module("Hello") {
output_name = "LLVMHello"
deps = [
+ ":exports",
+
# LLVMHello doesn't want to link in any LLVM code, it just
# needs its headers.
"//llvm/include/llvm/IR:public_tablegen",
@@ -15,6 +23,4 @@
# for loadable_modules for now.
cflags = [ "-fPIC" ]
}
-
- # FIXME: Use Hello.exports to remove all exports.
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/HelloNew/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/HelloNew/BUILD.gn
deleted file mode 100644
index 5e61673..0000000
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/HelloNew/BUILD.gn
+++ /dev/null
@@ -1,9 +0,0 @@
-static_library("HelloNew") {
- output_name = "LLVMHelloNew"
- deps = [
- "//llvm/lib/Analysis",
- "//llvm/lib/IR",
- "//llvm/lib/Support",
- ]
- sources = [ "HelloWorld.cpp" ]
-}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
index e6a2a87..2739afe 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
@@ -35,6 +35,7 @@
"ForceFunctionAttrs.cpp",
"FunctionAttrs.cpp",
"FunctionImport.cpp",
+ "FunctionSpecialization.cpp",
"GlobalDCE.cpp",
"GlobalOpt.cpp",
"GlobalSplit.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn
index 3842ab2..91e96d9 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Scalar/BUILD.gn
@@ -19,6 +19,7 @@
"ConstraintElimination.cpp",
"CorrelatedValuePropagation.cpp",
"DCE.cpp",
+ "DFAJumpThreading.cpp",
"DeadStoreElimination.cpp",
"DivRemPairs.cpp",
"EarlyCSE.cpp",
@@ -36,6 +37,7 @@
"JumpThreading.cpp",
"LICM.cpp",
"LoopAccessAnalysisPrinter.cpp",
+ "LoopBoundSplit.cpp",
"LoopDataPrefetch.cpp",
"LoopDeletion.cpp",
"LoopDistribute.cpp",
@@ -76,13 +78,12 @@
"SCCP.cpp",
"SROA.cpp",
"Scalar.cpp",
- "Scalarizer.cpp",
"ScalarizeMaskedMemIntrin.cpp",
+ "Scalarizer.cpp",
"SeparateConstOffsetFromGEP.cpp",
"SimpleLoopUnswitch.cpp",
"SimplifyCFGPass.cpp",
"Sink.cpp",
- "SpeculateAroundPHIs.cpp",
"SpeculativeExecution.cpp",
"StraightLineStrengthReduce.cpp",
"StructurizeCFG.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn
index efdded3..ac8e0e4 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/lib/Transforms/Utils/BUILD.gn
@@ -34,6 +34,7 @@
"FunctionImportUtils.cpp",
"GlobalStatus.cpp",
"GuardUtils.cpp",
+ "HelloWorld.cpp",
"InjectTLIMappings.cpp",
"InlineFunction.cpp",
"InstructionNamer.cpp",
@@ -54,13 +55,17 @@
"LowerSwitch.cpp",
"MatrixUtils.cpp",
"Mem2Reg.cpp",
+ "MemoryOpRemark.cpp",
"MetaRenamer.cpp",
"ModuleUtils.cpp",
"NameAnonGlobals.cpp",
"PredicateInfo.cpp",
"PromoteMemoryToRegister.cpp",
+ "RelLookupTableConverter.cpp",
+ "SCCPSolver.cpp",
"SSAUpdater.cpp",
"SSAUpdaterBulk.cpp",
+ "SampleProfileLoaderBaseUtil.cpp",
"SanitizerStats.cpp",
"ScalarEvolutionExpander.cpp",
"SimplifyCFG.cpp",
@@ -73,7 +78,6 @@
"SymbolRewriter.cpp",
"UnifyFunctionExitNodes.cpp",
"UnifyLoopExits.cpp",
- "UniqueInternalLinkageNames.cpp",
"Utils.cpp",
"VNCoercion.cpp",
"ValueMapper.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/test/BUILD.gn
index d474ea0..1cee926 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/test/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/test/BUILD.gn
@@ -6,6 +6,7 @@
import("//llvm/utils/gn/build/libs/xar/enable.gni")
import("//llvm/utils/gn/build/libs/xml/enable.gni")
import("//llvm/utils/gn/build/libs/zlib/enable.gni")
+import("//llvm/utils/gn/build/mac_sdk.gni")
import("//llvm/utils/gn/build/write_cmake_config.gni")
import("//llvm/utils/llvm-lit/lit_path_function.gni")
import("llvm_lit_site_cfg_files.gni")
@@ -59,7 +60,7 @@
"LLVM_ENABLE_FFI=0",
"LLVM_HAVE_OPT_VIEWER_MODULES=0",
"LLVM_HOST_TRIPLE=$llvm_current_triple",
- "LLVM_LIBRARY_DIR=" + rebase_path("$root_out_dir/lib", dir),
+ "LLVM_LIBS_DIR=" + rebase_path("$root_out_dir/lib", dir),
"LLVM_LINK_LLVM_DYLIB=0",
"LLVM_LIT_TOOLS_DIR=", # Intentionally empty, matches cmake build.
"LLVM_NATIVE_ARCH=$native_target",
@@ -98,23 +99,35 @@
}
if (host_os == "win") {
- extra_values += [ "EXEEXT=.exe" ]
+ extra_values += [
+ "EXEEXT=.exe",
+ "LLVM_ENABLE_PLUGINS=0",
+ "LLVM_LIT_ERRC_MESSAGES=no such file or directory;is a directory;" +
+ "invalid argument;permission denied",
+ ]
} else {
- extra_values += [ "EXEEXT=" ]
- }
-
- if (host_os == "win") {
- extra_values += [ "LLVM_ENABLE_PLUGINS=0" ]
- } else {
- extra_values += [ "LLVM_ENABLE_PLUGINS=1" ]
+ extra_values += [
+ "EXEEXT=",
+ "LLVM_ENABLE_PLUGINS=1",
+ "LLVM_LIT_ERRC_MESSAGES=",
+ ]
}
if (host_os == "mac") {
- extra_values += [ "SHLIBEXT=.dylib" ]
+ extra_values += [
+ "LLVM_PLUGIN_EXT=.dylib",
+ "SHLIBEXT=.dylib",
+ ]
} else if (host_os == "win") {
- extra_values += [ "SHLIBEXT=.dll" ]
+ extra_values += [
+ "LLVM_PLUGIN_EXT=.dll",
+ "SHLIBEXT=.dll",
+ ]
} else {
- extra_values += [ "SHLIBEXT=.so" ]
+ extra_values += [
+ "LLVM_PLUGIN_EXT=.so",
+ "SHLIBEXT=.so",
+ ]
}
if (host_os == "freebsd") {
@@ -138,9 +151,15 @@
extra_values += [ "GOLD_EXECUTABLE=" ]
}
if (host_os == "mac") {
- extra_values += [ "LD64_EXECUTABLE=ld" ]
+ extra_values += [
+ "CMAKE_OSX_SYSROOT=" + rebase_path(mac_sdk_path, dir),
+ "LD64_EXECUTABLE=ld",
+ ]
} else {
- extra_values += [ "LD64_EXECUTABLE=" ]
+ extra_values += [
+ "CMAKE_OSX_SYSROOT=",
+ "LD64_EXECUTABLE=",
+ ]
}
if (llvm_enable_assertions) {
@@ -150,9 +169,9 @@
}
if (llvm_enable_libxar) {
- extra_values += [ "HAVE_LIBXAR=1" ]
+ extra_values += [ "LLVM_HAVE_LIBXAR=1" ]
} else {
- extra_values += [ "HAVE_LIBXAR=0" ] # Must be 0.
+ extra_values += [ "LLVM_HAVE_LIBXAR=0" ] # Must be 0.
}
if (llvm_enable_dia_sdk) {
@@ -227,7 +246,6 @@
"//llvm/tools/llvm-dis",
"//llvm/tools/llvm-dwarfdump",
"//llvm/tools/llvm-dwp",
- "//llvm/tools/llvm-elfabi",
"//llvm/tools/llvm-exegesis",
"//llvm/tools/llvm-extract",
"//llvm/tools/llvm-gsymutil:llvm-gsymutil",
@@ -247,19 +265,23 @@
"//llvm/tools/llvm-mt",
"//llvm/tools/llvm-nm",
"//llvm/tools/llvm-objcopy:symlinks",
- "//llvm/tools/llvm-objdump",
+ "//llvm/tools/llvm-objdump:symlinks",
"//llvm/tools/llvm-opt-fuzzer",
"//llvm/tools/llvm-opt-report",
"//llvm/tools/llvm-pdbutil",
"//llvm/tools/llvm-profdata",
- "//llvm/tools/llvm-rc",
+ "//llvm/tools/llvm-profgen",
+ "//llvm/tools/llvm-rc:symlinks",
"//llvm/tools/llvm-readobj:symlinks",
"//llvm/tools/llvm-reduce",
"//llvm/tools/llvm-rtdyld",
+ "//llvm/tools/llvm-sim",
"//llvm/tools/llvm-size",
"//llvm/tools/llvm-split",
+ "//llvm/tools/llvm-stress",
"//llvm/tools/llvm-strings",
"//llvm/tools/llvm-symbolizer:symlinks",
+ "//llvm/tools/llvm-tapi-diff",
"//llvm/tools/llvm-undname",
"//llvm/tools/llvm-xray",
"//llvm/tools/lto",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
index f2ead02..1f7580b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/bugpoint-passes/BUILD.gn
@@ -1,8 +1,16 @@
+import("//llvm/utils/gn/build/symbol_exports.gni")
+
assert(host_os != "win", "loadable modules not supported on win")
+symbol_exports("exports") {
+ exports_file = "bugpoint.exports"
+}
+
loadable_module("bugpoint-passes") {
output_name = "BugpointPasses"
deps = [
+ ":exports",
+
# BugpointPasses doesn't want to link in any LLVM code, it just
# needs its headers.
"//llvm/include/llvm/IR:public_tablegen",
@@ -15,6 +23,4 @@
# for loadable_modules for now.
cflags = [ "-fPIC" ]
}
-
- # FIXME: Use bugpoint.exports to remove all exports.
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lli/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lli/BUILD.gn
index 8eede7e..07ce24a 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lli/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lli/BUILD.gn
@@ -21,7 +21,10 @@
"//llvm/lib/Transforms/Instrumentation",
"//llvm/lib/Transforms/Utils",
]
- sources = [ "lli.cpp" ]
+ sources = [
+ "ExecutionUtils.cpp",
+ "lli.cpp",
+ ]
if (host_os != "mac" && host_os != "win") {
# Corresponds to export_executable_symbols() in cmake.
ldflags = [ "-rdynamic" ]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-cxxfilt/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-cxxfilt/BUILD.gn
index 1f419ac..081f77d 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-cxxfilt/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-cxxfilt/BUILD.gn
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("Opts") {
+ visibility = [ ":llvm-cxxfilt" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
if (llvm_install_binutils_symlinks) {
symlink_or_copy("cxxfilt") { # Can't have '+' in target name.
deps = [ ":llvm-cxxfilt" ]
@@ -19,7 +25,9 @@
executable("llvm-cxxfilt") {
deps = [
+ ":Opts",
"//llvm/lib/Demangle",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
]
sources = [ "llvm-cxxfilt.cpp" ]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn
index 110aaaf..4a05980 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-dwp/BUILD.gn
@@ -19,16 +19,12 @@
executable("llvm-dwp") {
deps = [
- "//llvm/lib/CodeGen/AsmPrinter",
+ "//llvm/lib/DWP",
"//llvm/lib/DebugInfo/DWARF",
"//llvm/lib/MC",
"//llvm/lib/Object",
"//llvm/lib/Support",
- "//llvm/lib/Target",
"//llvm/lib/Target:TargetsToBuild",
]
- sources = [
- "DWPError.cpp",
- "llvm-dwp.cpp",
- ]
+ sources = [ "llvm-dwp.cpp" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-elfabi/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-elfabi/BUILD.gn
deleted file mode 100644
index 0b3cb1e..0000000
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-elfabi/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-executable("llvm-elfabi") {
- deps = [
- "//llvm/lib/InterfaceStub",
- "//llvm/lib/Object",
- "//llvm/lib/Support",
- "//llvm/lib/TextAPI",
- ]
- sources = [
- "ErrorCollector.cpp",
- "llvm-elfabi.cpp",
- ]
-}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-ifs/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-ifs/BUILD.gn
index 66d2124..b777122 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-ifs/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-ifs/BUILD.gn
@@ -1,9 +1,13 @@
executable("llvm-ifs") {
deps = [
+ "//llvm/lib/InterfaceStub",
"//llvm/lib/Object",
"//llvm/lib/ObjectYAML",
"//llvm/lib/Support",
"//llvm/lib/TextAPI",
]
- sources = [ "llvm-ifs.cpp" ]
+ sources = [
+ "ErrorCollector.cpp",
+ "llvm-ifs.cpp",
+ ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-jitlink/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-jitlink/BUILD.gn
index ae26bb6..8ac9274 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-jitlink/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-jitlink/BUILD.gn
@@ -15,4 +15,8 @@
"llvm-jitlink-macho.cpp",
"llvm-jitlink.cpp",
]
+ if (host_os != "mac" && host_os != "win") {
+ # Corresponds to export_executable_symbols() in cmake.
+ ldflags = [ "-rdynamic" ]
+ }
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/BUILD.gn
index dcea891..458598b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/BUILD.gn
@@ -1,3 +1,5 @@
+import("//llvm/lib/Target/targets.gni")
+
executable("llvm-mca") {
deps = [
"//llvm/lib/MC",
@@ -30,4 +32,9 @@
"Views/View.cpp",
"llvm-mca.cpp",
]
+ defines = []
+ if (llvm_build_AMDGPU) {
+ deps += [ "//llvm/tools/llvm-mca/lib/AMDGPU" ]
+ defines += [ "HAS_AMDGPU" ]
+ }
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/lib/AMDGPU/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/lib/AMDGPU/BUILD.gn
new file mode 100644
index 0000000..3bde981
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-mca/lib/AMDGPU/BUILD.gn
@@ -0,0 +1,15 @@
+static_library("AMDGPU") {
+ output_name = "LLVMMCACustomBehaviourAMDGPU"
+ deps = [
+ "//llvm/lib/IR",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target/AMDGPU",
+
+ # llvm-mca/libAMDGPU reaches inside the Target/AMDGPU tablegen internals
+ # and must depend on these Target/AMDGPU-internal build targets.
+ "//llvm/lib/Target/AMDGPU/MCTargetDesc",
+ "//llvm/lib/Target/AMDGPU/Utils",
+ ]
+ include_dirs = [ "//llvm/lib/Target/AMDGPU" ]
+ sources = [ "AMDGPUCustomBehaviour.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-nm/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-nm/BUILD.gn
index 85aa339..fd02446 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-nm/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-nm/BUILD.gn
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("Opts") {
+ visibility = [ ":llvm-nm" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
if (llvm_install_binutils_symlinks) {
symlink_or_copy("nm") {
deps = [ ":llvm-nm" ]
@@ -19,10 +25,12 @@
executable("llvm-nm") {
deps = [
+ ":Opts",
"//llvm/lib/Bitcode/Reader",
"//llvm/lib/Demangle",
"//llvm/lib/IR",
"//llvm/lib/Object",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
"//llvm/lib/Target:AllTargetsAsmParsers",
"//llvm/lib/Target:AllTargetsDescs",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objcopy/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objcopy/BUILD.gn
index 079221e..64ea2b5 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objcopy/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objcopy/BUILD.gn
@@ -62,13 +62,11 @@
]
include_dirs = [ "." ]
sources = [
- "Buffer.cpp",
"COFF/COFFObjcopy.cpp",
"COFF/Object.cpp",
"COFF/Reader.cpp",
"COFF/Writer.cpp",
- "CopyConfig.cpp",
- "ELF/ELFConfig.cpp",
+ "ConfigManager.cpp",
"ELF/ELFObjcopy.cpp",
"ELF/Object.cpp",
"MachO/MachOLayoutBuilder.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
index c8ba176..84d3d01 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-objdump/BUILD.gn
@@ -1,24 +1,42 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("ObjdumpOpts") {
+ visibility = [ ":llvm-objdump" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
+tablegen("OtoolOpts") {
+ visibility = [ ":llvm-objdump" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
+symlinks = [ "llvm-otool" ]
if (llvm_install_binutils_symlinks) {
- symlink_or_copy("objdump") {
+ symlinks += [ "objdump" ]
+}
+
+foreach(target, symlinks) {
+ symlink_or_copy(target) {
deps = [ ":llvm-objdump" ]
source = "llvm-objdump"
- output = "$root_out_dir/bin/objdump"
+ output = "$root_out_dir/bin/$target"
}
}
# //:llvm-objdump depends on this symlink target, see comment in //BUILD.gn.
group("symlinks") {
deps = [ ":llvm-objdump" ]
- if (llvm_install_binutils_symlinks) {
- deps += [ ":objdump" ]
+ foreach(target, symlinks) {
+ deps += [ ":$target" ]
}
}
executable("llvm-objdump") {
deps = [
+ ":ObjdumpOpts",
+ ":OtoolOpts",
"//llvm/include/llvm/Config:config",
"//llvm/lib/CodeGen",
"//llvm/lib/DebugInfo/DWARF",
@@ -28,6 +46,7 @@
"//llvm/lib/MC",
"//llvm/lib/MC/MCDisassembler",
"//llvm/lib/Object",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
"//llvm/lib/Target:AllTargetsDescs",
"//llvm/lib/Target:AllTargetsDisassemblers",
@@ -38,6 +57,7 @@
"COFFDump.cpp",
"ELFDump.cpp",
"MachODump.cpp",
+ "SourcePrinter.cpp",
"WasmDump.cpp",
"XCOFFDump.cpp",
"llvm-objdump.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-profgen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-profgen/BUILD.gn
new file mode 100644
index 0000000..e646ef8
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-profgen/BUILD.gn
@@ -0,0 +1,23 @@
+executable("llvm-profgen") {
+ deps = [
+ "//llvm/lib/DebugInfo/Symbolize",
+ "//llvm/lib/IR",
+ "//llvm/lib/MC",
+ "//llvm/lib/MC/MCDisassembler",
+ "//llvm/lib/Object",
+ "//llvm/lib/ProfileData",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target:AllTargetsDescs",
+ "//llvm/lib/Target:AllTargetsDisassemblers",
+ "//llvm/lib/Target:AllTargetsInfos",
+ "//llvm/lib/Transforms/IPO",
+ ]
+ sources = [
+ "CSPreInliner.cpp",
+ "PerfReader.cpp",
+ "ProfileGenerator.cpp",
+ "ProfiledBinary.cpp",
+ "PseudoProbe.cpp",
+ "llvm-profgen.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-rc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-rc/BUILD.gn
index d47148a..f3ddb0f 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-rc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-rc/BUILD.gn
@@ -1,13 +1,43 @@
+import("//llvm/tools/binutils_symlinks.gni")
import("//llvm/utils/TableGen/tablegen.gni")
+import("//llvm/utils/gn/build/symlink_or_copy.gni")
tablegen("Opts") {
visibility = [ ":llvm-rc" ]
args = [ "-gen-opt-parser-defs" ]
}
+tablegen("WindresOpts") {
+ visibility = [ ":llvm-rc" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
+symlinks = [ "llvm-windres" ]
+if (llvm_install_binutils_symlinks) {
+ symlinks += [ "windres" ]
+}
+
+foreach(target, symlinks) {
+ symlink_or_copy(target) {
+ deps = [ ":llvm-rc" ]
+ source = "llvm-rc"
+ output = "$root_out_dir/bin/$target"
+ }
+}
+
+# //:llvm-rc depends on this symlink target, see comment in //BUILD.gn.
+group("symlinks") {
+ deps = [ ":llvm-rc" ]
+ foreach(target, symlinks) {
+ deps += [ ":$target" ]
+ }
+}
+
executable("llvm-rc") {
deps = [
":Opts",
+ ":WindresOpts",
+ "//llvm/lib/Object",
"//llvm/lib/Option",
"//llvm/lib/Support",
]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-readobj/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-readobj/BUILD.gn
index a257275..ca6e71b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-readobj/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-readobj/BUILD.gn
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("Opts") {
+ visibility = [ ":llvm-readobj" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
symlinks = [ "llvm-readelf" ]
if (llvm_install_binutils_symlinks) {
symlinks += [ "readelf" ]
@@ -23,12 +29,14 @@
executable("llvm-readobj") {
deps = [
+ ":Opts",
"//llvm/lib/BinaryFormat",
"//llvm/lib/DebugInfo/CodeView",
"//llvm/lib/DebugInfo/DWARF",
"//llvm/lib/DebugInfo/MSF",
"//llvm/lib/DebugInfo/PDB",
"//llvm/lib/Object",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
]
sources = [
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn
index 7bdae5e..018d2ac 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn
@@ -9,6 +9,7 @@
]
include_dirs = [ "." ]
sources = [
+ "DeltaManager.cpp",
"TestRunner.cpp",
"deltas/Delta.cpp",
"deltas/ReduceAliases.cpp",
@@ -17,10 +18,12 @@
"deltas/ReduceBasicBlocks.cpp",
"deltas/ReduceFunctionBodies.cpp",
"deltas/ReduceFunctions.cpp",
+ "deltas/ReduceGlobalValues.cpp",
"deltas/ReduceGlobalVarInitializers.cpp",
"deltas/ReduceGlobalVars.cpp",
"deltas/ReduceInstructions.cpp",
"deltas/ReduceMetadata.cpp",
+ "deltas/ReduceModuleInlineAsm.cpp",
"deltas/ReduceOperandBundles.cpp",
"deltas/ReduceSpecialGlobals.cpp",
"llvm-reduce.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn
new file mode 100644
index 0000000..a391c0e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn
@@ -0,0 +1,8 @@
+executable("llvm-sim") {
+ deps = [
+ "//llvm/lib/Analysis",
+ "//llvm/lib/IRReader",
+ "//llvm/lib/Support",
+ ]
+ sources = [ "llvm-sim.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-size/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-size/BUILD.gn
index c3e2f30..e41f765 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-size/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-size/BUILD.gn
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("Opts") {
+ visibility = [ ":llvm-size" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
if (llvm_install_binutils_symlinks) {
symlink_or_copy("size") {
deps = [ ":llvm-size" ]
@@ -19,7 +25,9 @@
executable("llvm-size") {
deps = [
+ ":Opts",
"//llvm/lib/Object",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
]
sources = [ "llvm-size.cpp" ]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-stress/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-stress/BUILD.gn
new file mode 100644
index 0000000..47cc1ed
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-stress/BUILD.gn
@@ -0,0 +1,8 @@
+executable("llvm-stress") {
+ deps = [
+ "//llvm/lib/Analysis",
+ "//llvm/lib/IR",
+ "//llvm/lib/Support",
+ ]
+ sources = [ "llvm-stress.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-strings/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-strings/BUILD.gn
index c88c729..0e8ed93 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-strings/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-strings/BUILD.gn
@@ -1,6 +1,12 @@
import("//llvm/tools/binutils_symlinks.gni")
+import("//llvm/utils/TableGen/tablegen.gni")
import("//llvm/utils/gn/build/symlink_or_copy.gni")
+tablegen("Opts") {
+ visibility = [ ":llvm-strings" ]
+ args = [ "-gen-opt-parser-defs" ]
+}
+
if (llvm_install_binutils_symlinks) {
symlink_or_copy("strings") {
deps = [ ":llvm-strings" ]
@@ -19,8 +25,10 @@
executable("llvm-strings") {
deps = [
+ ":Opts",
"//llvm/lib/IR",
"//llvm/lib/Object",
+ "//llvm/lib/Option",
"//llvm/lib/Support",
]
sources = [ "llvm-strings.cpp" ]
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-tapi-diff/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-tapi-diff/BUILD.gn
new file mode 100644
index 0000000..ffdccf5
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/llvm-tapi-diff/BUILD.gn
@@ -0,0 +1,11 @@
+executable("llvm-tapi-diff") {
+ deps = [
+ "//llvm/lib/Object",
+ "//llvm/lib/Support",
+ "//llvm/lib/TextAPI",
+ ]
+ sources = [
+ "DiffEngine.cpp",
+ "llvm-tapi-diff.cpp",
+ ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn
index 135b952..418bdeb 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/tools/lto/BUILD.gn
@@ -1,3 +1,4 @@
+import("//llvm/utils/gn/build/symbol_exports.gni")
import("//llvm/version.gni")
lto_target_type = "shared_library"
@@ -7,6 +8,10 @@
lto_target_type = "static_library"
}
+symbol_exports("exports") {
+ exports_file = "lto.exports"
+}
+
target(lto_target_type, "lto") {
output_name = "LTO"
deps = [
@@ -24,6 +29,10 @@
"lto.cpp",
]
+ if (lto_target_type == "shared_library") {
+ deps += [ ":exports" ]
+ }
+
if (host_os == "mac") {
ldflags = [
"-Wl,-compatibility_version,1",
@@ -34,6 +43,4 @@
"-Wl,-rpath,@loader_path/../lib",
]
}
-
- # FIXME: Use lto.exports
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn
index c97c22c..8755f1e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ADT/BUILD.gn
@@ -62,6 +62,7 @@
"RangeAdapterTest.cpp",
"SCCIteratorTest.cpp",
"STLExtrasTest.cpp",
+ "STLForwardCompatTest.cpp",
"ScopeExitTest.cpp",
"SequenceTest.cpp",
"SetVectorTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
index 50c02aa..f83243e 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
@@ -27,6 +27,7 @@
"GlobalsModRefTest.cpp",
"IRSimilarityIdentifierTest.cpp",
"IVDescriptorsTest.cpp",
+ "InlineCostTest.cpp",
"LazyCallGraphTest.cpp",
"LoadsTest.cpp",
"LoopInfoTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/BUILD.gn
index ae233fd..ff2568b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/BUILD.gn
@@ -29,9 +29,11 @@
"Linker:LinkerTests",
"MC:MCTests",
"MI:MITests",
+ "MIR:MIRTests",
"Object:ObjectTests",
"ObjectYAML:ObjectYAMLTests",
"Option:OptionTests",
+ "Passes:PassesBindingsTests",
"Passes:PluginsTests",
"ProfileData:ProfileDataTests",
"Remarks:RemarksTests",
@@ -46,6 +48,7 @@
"XRay:XRayTests",
"tools/llvm-cfi-verify:CFIVerifyTests",
"tools/llvm-exegesis:LLVMExegesisTests",
+ "tools/llvm-profgen:LLVMProfgenTests",
]
# Target-dependent unit tests.
@@ -79,6 +82,9 @@
"tools/llvm-exegesis/PowerPC:LLVMExegesisPowerPCTests",
]
}
+ if (llvm_build_SystemZ) {
+ deps += [ "MC/SystemZ:SystemZAsmLexerTests" ]
+ }
if (llvm_build_WebAssembly) {
deps += [ "Target/WebAssembly:WebAssemblyTests" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn
index 2392153..8a286be 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/BUILD.gn
@@ -7,6 +7,7 @@
"//llvm/lib/CodeGen",
"//llvm/lib/CodeGen/AsmPrinter",
"//llvm/lib/CodeGen/SelectionDAG",
+ "//llvm/lib/FileCheck",
"//llvm/lib/IR",
"//llvm/lib/MC",
"//llvm/lib/Passes",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/GlobalISel/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/GlobalISel/BUILD.gn
index 7933f8c..8c59279 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/GlobalISel/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/CodeGen/GlobalISel/BUILD.gn
@@ -18,6 +18,7 @@
"GISelMITest.cpp",
"GISelUtilsTest.cpp",
"KnownBitsTest.cpp",
+ "KnownBitsVectorTest.cpp",
"LegalizerHelperTest.cpp",
"LegalizerInfoTest.cpp",
"LegalizerTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/CodeView/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/CodeView/BUILD.gn
index 913de50..db28b4b 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/CodeView/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/CodeView/BUILD.gn
@@ -6,6 +6,7 @@
"//llvm/lib/Testing/Support",
]
sources = [
+ "GUIDFormatTest.cpp",
"RandomAccessVisitorTest.cpp",
"TypeHashingTest.cpp",
"TypeIndexDiscoveryTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/DWARF/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/DWARF/BUILD.gn
index 2c62be5..38ec526 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/DWARF/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/DebugInfo/DWARF/BUILD.gn
@@ -18,6 +18,7 @@
"DWARFDebugFrameTest.cpp",
"DWARFDebugInfoTest.cpp",
"DWARFDebugLineTest.cpp",
+ "DWARFDieManualExtractTest.cpp",
"DWARFDieTest.cpp",
"DWARFExpressionCompactPrinterTest.cpp",
"DWARFFormValueTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn
index bfbffbb..1c73981 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Demangle/BUILD.gn
@@ -6,5 +6,7 @@
"DemangleTest.cpp",
"ItaniumDemangleTest.cpp",
"PartialDemangleTest.cpp",
+ "RustDemangleTest.cpp",
+ "StringViewTest.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn
index d4dbec4..9704ab5 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/ExecutionEngine/Orc/BUILD.gn
@@ -14,15 +14,20 @@
]
sources = [
"CoreAPIsTest.cpp",
+ "ExecutionSessionWrapperFunctionCallsTest.cpp",
"IndirectionUtilsTest.cpp",
"JITTargetMachineBuilderTest.cpp",
"LazyCallThroughAndReexportsTest.cpp",
+ "ObjectLinkingLayerTest.cpp",
+ "OrcCAPITest.cpp",
"OrcTestCommon.cpp",
"QueueChannel.cpp",
"RPCUtilsTest.cpp",
"RTDyldObjectLinkingLayerTest.cpp",
"ResourceTrackerTest.cpp",
+ "SimplePackedSerializationTest.cpp",
"SymbolStringPoolTest.cpp",
"ThreadSafeModuleTest.cpp",
+ "WrapperFunctionUtilsTest.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/MC/SystemZ/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/MC/SystemZ/BUILD.gn
new file mode 100644
index 0000000..637fc34
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/MC/SystemZ/BUILD.gn
@@ -0,0 +1,11 @@
+import("//llvm/utils/unittest/unittest.gni")
+
+unittest("SystemZAsmLexerTests") {
+ deps = [
+ "//llvm/lib/MC",
+ "//llvm/lib/MC/MCParser",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target/SystemZ",
+ ]
+ sources = [ "SystemZAsmLexerTest.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/MIR/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/MIR/BUILD.gn
new file mode 100644
index 0000000..c6dd5ae
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/MIR/BUILD.gn
@@ -0,0 +1,16 @@
+import("//llvm/utils/unittest/unittest.gni")
+
+unittest("MIRTests") {
+ deps = [
+ "//llvm/lib/CodeGen",
+ "//llvm/lib/CodeGen/MIRParser",
+ "//llvm/lib/FileCheck",
+ "//llvm/lib/IR",
+ "//llvm/lib/MC",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target",
+ "//llvm/lib/Target:TargetsToBuild",
+ "//llvm/lib/Testing/Support",
+ ]
+ sources = [ "MachineMetadata.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Passes/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Passes/BUILD.gn
index fd308a9..29e4183 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Passes/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Passes/BUILD.gn
@@ -3,23 +3,29 @@
# Keyed off LLVM_ENABLE_PLUGINS in the CMake build, which is usually false
# on Windows and true elsewhere.
if (host_os != "win") {
- loadable_module("TestPlugin") {
- # Put plugin next to the unit test executable.
- output_dir = target_out_dir
+ foreach(plugin,
+ [
+ "TestPlugin",
+ "DoublerPlugin",
+ ]) {
+ loadable_module(plugin) {
+ # Put plugin next to the unit test executable.
+ output_dir = target_out_dir
- sources = [ "TestPlugin.cpp" ]
+ sources = [ "$plugin.cpp" ]
- deps = [
- # TestPlugin doesn't want to link in any LLVM code, it just needs its
- # headers.
- "//llvm/include/llvm/IR:public_tablegen",
- ]
+ deps = [
+ # TestPlugin doesn't want to link in any LLVM code, it just needs its
+ # headers.
+ "//llvm/include/llvm/IR:public_tablegen",
+ ]
- if (host_os != "mac" && host_os != "win") {
- # The GN build currently doesn't globally pass -fPIC, but that's
- # needed for building .so files on ELF. Just pass it manually
- # for loadable_modules for now.
- cflags = [ "-fPIC" ]
+ if (host_os != "mac" && host_os != "win") {
+ # The GN build currently doesn't globally pass -fPIC, but that's
+ # needed for building .so files on ELF. Just pass it manually
+ # for loadable_modules for now.
+ cflags = [ "-fPIC" ]
+ }
}
}
}
@@ -38,7 +44,10 @@
# Otherwise, reconfiguring with plugins disabled will leave behind a stale
# executable.
if (host_os != "win") {
- deps += [ ":TestPlugin" ]
+ deps += [
+ ":DoublerPlugin",
+ ":TestPlugin",
+ ]
defines = [ "LLVM_ENABLE_PLUGINS" ]
}
@@ -47,3 +56,15 @@
ldflags = [ "-rdynamic" ]
}
}
+
+unittest("PassesBindingsTests") {
+ deps = [
+ "//llvm/include/llvm/Config:config",
+ "//llvm/lib/IR",
+ "//llvm/lib/Passes",
+ "//llvm/lib/Support",
+ "//llvm/lib/Target:TargetsToBuild",
+ "//llvm/lib/Testing/Support",
+ ]
+ sources = [ "PassBuilderBindingsTest.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
index 4f6f40b..0ba61aa 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn
@@ -69,6 +69,7 @@
"RegexTest.cpp",
"ReplaceFileTest.cpp",
"ReverseIterationTest.cpp",
+ "SHA256.cpp",
"ScaledNumberTest.cpp",
"SourceMgrTest.cpp",
"SpecialCaseListTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn
index 25a2bb0..b9519cb 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Target/AArch64/BUILD.gn
@@ -17,5 +17,6 @@
sources = [
"DecomposeStackOffsetTest.cpp",
"InstSizes.cpp",
+ "MatrixRegisterAliasing.cpp",
]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn
index c3d139e..3d833cb 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/Transforms/Utils/BUILD.gn
@@ -4,6 +4,7 @@
deps = [
"//llvm/lib/Analysis",
"//llvm/lib/AsmParser",
+ "//llvm/lib/Bitcode/Writer",
"//llvm/lib/IR",
"//llvm/lib/Support",
"//llvm/lib/Transforms/Utils",
@@ -15,11 +16,13 @@
"CloningTest.cpp",
"CodeExtractorTest.cpp",
"CodeMoverUtilsTest.cpp",
+ "DebugifyTest.cpp",
"FunctionComparatorTest.cpp",
"IntegerDivisionTest.cpp",
"LocalTest.cpp",
"LoopRotationUtilsTest.cpp",
"LoopUtilsTest.cpp",
+ "ModuleUtilsTest.cpp",
"SSAUpdaterBulkTest.cpp",
"ScalarEvolutionExpanderTest.cpp",
"SizeOptsTest.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/tools/llvm-profgen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/tools/llvm-profgen/BUILD.gn
new file mode 100644
index 0000000..835bc7c
--- /dev/null
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/unittests/tools/llvm-profgen/BUILD.gn
@@ -0,0 +1,9 @@
+import("//llvm/utils/unittest/unittest.gni")
+
+unittest("LLVMProfgenTests") {
+ deps = [
+ "//llvm/include/llvm/IR:public_tablegen",
+ "//llvm/lib/Testing/Support",
+ ]
+ sources = [ "ContextCompressionTest.cpp" ]
+}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
index bd1382d..4d3de97 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/TableGen/BUILD.gn
@@ -12,6 +12,7 @@
"Attributes.cpp",
"CTagsEmitter.cpp",
"CallingConvEmitter.cpp",
+ "CodeBeadsGen.cpp",
"CodeEmitterGen.cpp",
"CodeGenDAGPatterns.cpp",
"CodeGenHwModes.cpp",
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/unittest/BUILD.gn b/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/unittest/BUILD.gn
index cc92478..ccdb401 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/unittest/BUILD.gn
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/utils/unittest/BUILD.gn
@@ -9,10 +9,7 @@
# LLVM requires C++11 but gtest doesn't correctly detect the availability
# of C++11 on MSVC, so we force it on.
- defines = [
- "GTEST_LANG_CXX11",
- "GTEST_HAS_TR1_TUPLE=0",
- ]
+ defines = [ "GTEST_LANG_CXX11" ]
if (host_os == "win") {
defines += [ "GTEST_OS_WINDOWS" ]
}
diff --git a/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni b/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni
index 942974f..39c995f 100644
--- a/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni
+++ b/src/llvm-project/llvm/utils/gn/secondary/llvm/version.gni
@@ -1,4 +1,4 @@
-llvm_version_major = 12
+llvm_version_major = 13
llvm_version_minor = 0
-llvm_version_patch = 1
+llvm_version_patch = 0
llvm_version = "$llvm_version_major.$llvm_version_minor.$llvm_version_patch"
diff --git a/src/llvm-project/llvm/utils/kate/llvm.xml b/src/llvm-project/llvm/utils/kate/llvm.xml
index 5132aaf..9f7ec77 100644
--- a/src/llvm-project/llvm/utils/kate/llvm.xml
+++ b/src/llvm-project/llvm/utils/kate/llvm.xml
@@ -77,35 +77,71 @@
</list>
<list name="function-attributes">
<item> alignstack </item>
+ <item> allocsize </item>
<item> alwaysinline </item>
<item> argmemonly </item>
+ <item> arm_aapcscc </item>
+ <item> catch </item>
+ <item> cold </item>
<item> convergent </item>
+ <item> dereferenceable_or_null </item>
+ <item> extern_weak </item>
+ <item> hhvmcc </item>
+ <item> hot </item>
+ <item> inaccessiblemem_or_argmemonly </item>
+ <item> inaccessiblememonly </item>
+ <item> inalloca </item>
<item> inlinehint </item>
+ <item> inteldialect </item>
+ <item> jumptable </item>
+ <item> local_unnamed_addr </item>
<item> mustprogress </item>
<item> naked </item>
<item> nobuiltin </item>
+ <item> nocallback </item>
+ <item> nocf_check </item>
+ <item> noduplicate </item>
+ <item> nofree </item>
<item> noimplicitfloat </item>
<item> noinline </item>
+ <item> nomerge </item>
+ <item> noprofile </item>
<item> noredzone </item>
<item> noreturn </item>
+ <item> nosync </item>
<item> nounwind </item>
+ <item> null_pointer_is_valid </item>
+ <item> optforfuzzing </item>
<item> optnone </item>
<item> optsize </item>
+ <item> preallocated </item>
<item> readnone </item>
<item> readonly </item>
+ <item> safestack </item>
+ <item> sanitize_hwaddress </item>
+ <item> sanitize_memtag </item>
+ <item> shadowcallstack </item>
+ <item> speculative_load_hardening </item>
<item> ssp </item>
<item> sspreq </item>
<item> sspstrong </item>
+ <item> swifterror </item>
+ <item> syncscope </item>
+ <item> tailcc </item>
+ <item> willreturn </item>
+ <item> willreturn </item>
</list>
<list name="types">
<item> addrspace </item>
<item> half </item>
+ <item> bfloat </item>
<item> float </item>
<item> double </item>
<item> fp128 </item>
<item> x86_fp80 </item>
<item> ppc_fp128 </item>
- <item> x86mmx </item>
+ <item> x86_mmx </item>
+ <item> x86_amx </item>
<item> void </item>
<item> label </item>
<item> metadata </item>
diff --git a/src/llvm-project/llvm/utils/lit/lit/BooleanExpression.py b/src/llvm-project/llvm/utils/lit/lit/BooleanExpression.py
index 34e07fc..ff53527 100644
--- a/src/llvm-project/llvm/utils/lit/lit/BooleanExpression.py
+++ b/src/llvm-project/llvm/utils/lit/lit/BooleanExpression.py
@@ -4,18 +4,24 @@
# A simple evaluator of boolean expressions.
#
# Grammar:
- # expr :: or_expr
- # or_expr :: and_expr ('||' and_expr)*
- # and_expr :: not_expr ('&&' not_expr)*
- # not_expr :: '!' not_expr
- # '(' or_expr ')'
- # identifier
- # identifier :: [-+=._a-zA-Z0-9]+
+ # expr :: or_expr
+ # or_expr :: and_expr ('||' and_expr)*
+ # and_expr :: not_expr ('&&' not_expr)*
+ # not_expr :: '!' not_expr
+ # '(' or_expr ')'
+ # match_expr
+ # match_expr :: braced_regex
+ # identifier
+ # braced_regex match_expr
+ # identifier match_expr
+ # identifier :: [-+=._a-zA-Z0-9]+
+ # braced_regex :: '{{' python_regex '}}'
# Evaluates `string` as a boolean expression.
# Returns True or False. Throws a ValueError on syntax error.
#
# Variables in `variables` are true.
+ # Regexes that match any variable in `variables` are true.
# Substrings of `triple` are true.
# 'true' is true.
# All other identifiers are false.
@@ -41,7 +47,7 @@
END = object()
# Tokenization pattern.
- Pattern = re.compile(r'\A\s*([()]|[-+=._a-zA-Z0-9]+|&&|\|\||!)\s*(.*)\Z')
+ Pattern = re.compile(r'\A\s*([()]|&&|\|\||!|(?:[-+=._a-zA-Z0-9]+|\{\{.+?\}\})+)\s*(.*)\Z')
@staticmethod
def tokenize(string):
@@ -80,12 +86,24 @@
(self.quote(t), self.quote(self.token)))
@staticmethod
- def isIdentifier(token):
+ def isMatchExpression(token):
if (token is BooleanExpression.END or token == '&&' or token == '||' or
token == '!' or token == '(' or token == ')'):
return False
return True
+ def parseMATCH(self):
+ regex = ''
+ for part in filter(None, re.split(r'(\{\{.+?\}\})', self.token)):
+ if part.startswith('{{'):
+ assert part.endswith('}}')
+ regex += '(?:{})'.format(part[2:-2])
+ else:
+ regex += re.escape(part)
+ regex = re.compile(regex)
+ self.value = self.token in self.triple or any(regex.fullmatch(var) for var in self.variables)
+ self.token = next(self.tokens)
+
def parseNOT(self):
if self.accept('!'):
self.parseNOT()
@@ -93,13 +111,11 @@
elif self.accept('('):
self.parseOR()
self.expect(')')
- elif not BooleanExpression.isIdentifier(self.token):
- raise ValueError("expected: '!' or '(' or identifier\nhave: %s" %
+ elif not BooleanExpression.isMatchExpression(self.token):
+ raise ValueError("expected: '!', '(', '{{', or identifier\nhave: %s" %
self.quote(self.token))
else:
- self.value = (self.token in self.variables or
- self.token in self.triple)
- self.token = next(self.tokens)
+ self.parseMATCH()
def parseAND(self):
self.parseNOT()
@@ -143,12 +159,20 @@
self.assertTrue(BooleanExpression.evaluate('under_score', variables))
self.assertTrue(BooleanExpression.evaluate('e=quals', variables))
self.assertTrue(BooleanExpression.evaluate('d1g1ts', variables))
+ self.assertTrue(BooleanExpression.evaluate('{{its.+}}', variables))
+ self.assertTrue(BooleanExpression.evaluate('{{false-[lo]+-true}}', variables))
+ self.assertTrue(BooleanExpression.evaluate('{{(true|false)-lol-(true|false)}}', variables))
+ self.assertTrue(BooleanExpression.evaluate('d1g{{[0-9]}}ts', variables))
+ self.assertTrue(BooleanExpression.evaluate('d1g{{[0-9]}}t{{[a-z]}}', variables))
+ self.assertTrue(BooleanExpression.evaluate('{{d}}1g{{[0-9]}}t{{[a-z]}}', variables))
+ self.assertTrue(BooleanExpression.evaluate('d1{{(g|1)+}}ts', variables))
self.assertFalse(BooleanExpression.evaluate('false', variables))
self.assertFalse(BooleanExpression.evaluate('True', variables))
self.assertFalse(BooleanExpression.evaluate('true-ish', variables))
self.assertFalse(BooleanExpression.evaluate('not_true', variables))
self.assertFalse(BooleanExpression.evaluate('tru', variables))
+ self.assertFalse(BooleanExpression.evaluate('{{its-true.+}}', variables))
def test_triple(self):
triple = 'arch-vendor-os'
@@ -159,6 +183,21 @@
self.assertTrue(BooleanExpression.evaluate('-os', {}, triple))
self.assertFalse(BooleanExpression.evaluate('arch-os', {}, triple))
+ # When matching against the triple, a regex is treated as an identifier and checked
+ # for a literal match. This preserves existing behavior before regexes were introduced.
+ self.assertFalse(BooleanExpression.evaluate('arch-{{vendor}}-os', {}, triple))
+ self.assertTrue(BooleanExpression.evaluate('arch-{{vendor}}-os', {}, 'arch-{{vendor}}-os'))
+
+ def test_matching(self):
+ expr1 = 'linux && (target={{aarch64-.+}} || target={{x86_64-.+}})'
+ self.assertTrue(BooleanExpression.evaluate(expr1, {'linux', 'target=x86_64-unknown-linux-gnu'}))
+ self.assertFalse(BooleanExpression.evaluate(expr1, {'linux', 'target=i386-unknown-linux-gnu'}))
+
+ expr2 = 'use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11|12}} && !no-exceptions'
+ self.assertTrue(BooleanExpression.evaluate(expr2, {'use_system_cxx_lib', 'target=arm64-apple-macosx10.12'}))
+ self.assertFalse(BooleanExpression.evaluate(expr2, {'use_system_cxx_lib', 'target=arm64-apple-macosx10.12', 'no-exceptions'}))
+ self.assertFalse(BooleanExpression.evaluate(expr2, {'use_system_cxx_lib', 'target=arm64-apple-macosx10.15'}))
+
def test_operators(self):
self.assertTrue(BooleanExpression.evaluate('true || true', {}))
self.assertTrue(BooleanExpression.evaluate('true || false', {}))
@@ -206,17 +245,17 @@
"in expression: 'true and true'")
self.checkException("|| true",
- "expected: '!' or '(' or identifier\n" +
+ "expected: '!', '(', '{{', or identifier\n" +
"have: '||'\n" +
"in expression: '|| true'")
self.checkException("true &&",
- "expected: '!' or '(' or identifier\n" +
+ "expected: '!', '(', '{{', or identifier\n" +
"have: <end of expression>\n" +
"in expression: 'true &&'")
self.checkException("",
- "expected: '!' or '(' or identifier\n" +
+ "expected: '!', '(', '{{', or identifier\n" +
"have: <end of expression>\n" +
"in expression: ''")
@@ -244,9 +283,18 @@
"in expression: 'true (true)'")
self.checkException("( )",
- "expected: '!' or '(' or identifier\n" +
+ "expected: '!', '(', '{{', or identifier\n" +
"have: ')'\n" +
"in expression: '( )'")
+ self.checkException("abc{{def",
+ "couldn't parse text: '{{def'\n" +
+ "in expression: 'abc{{def'")
+
+ self.checkException("{{}}",
+ "couldn't parse text: '{{}}'\n" +
+ "in expression: '{{}}'")
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/src/llvm-project/llvm/utils/lit/lit/ProgressBar.py b/src/llvm-project/llvm/utils/lit/lit/ProgressBar.py
index 4f8bd3c..fd721db 100644
--- a/src/llvm-project/llvm/utils/lit/lit/ProgressBar.py
+++ b/src/llvm-project/llvm/utils/lit/lit/ProgressBar.py
@@ -253,7 +253,7 @@
elapsed = time.time() - self.startTime
if percent > .0001 and elapsed > 1:
total = elapsed / percent
- eta = int(total - elapsed)
+ eta = total - elapsed
h = eta//3600.
m = (eta//60) % 60
s = eta % 60
diff --git a/src/llvm-project/llvm/utils/lit/lit/Test.py b/src/llvm-project/llvm/utils/lit/lit/Test.py
index 59fefbc..77b9c23 100644
--- a/src/llvm-project/llvm/utils/lit/lit/Test.py
+++ b/src/llvm-project/llvm/utils/lit/lit/Test.py
@@ -3,6 +3,7 @@
from json import JSONEncoder
from lit.BooleanExpression import BooleanExpression
+from lit.TestTimes import read_test_times
# Test result codes.
@@ -207,6 +208,8 @@
# The test suite configuration.
self.config = config
+ self.test_times = read_test_times(self)
+
def getSourcePath(self, components):
return os.path.join(self.source_root, *components)
@@ -228,6 +231,9 @@
# handlers, and will be honored when the test result is supplied.
self.xfails = []
+ # If true, ignore all items in self.xfails.
+ self.xfail_not = False
+
# A list of conditions that must be satisfied before running the test.
# Each condition is a boolean expression of features. All of them
# must be True for the test to run.
@@ -246,6 +252,18 @@
# The test result, once complete.
self.result = None
+ # The previous test failure state, if applicable.
+ self.previous_failure = False
+
+ # The previous test elapsed time, if applicable.
+ self.previous_elapsed = 0.0
+
+ if '/'.join(path_in_suite) in suite.test_times:
+ time = suite.test_times['/'.join(path_in_suite)]
+ self.previous_elapsed = abs(time)
+ self.previous_failure = time < 0
+
+
def setResult(self, result):
assert self.result is None, "result already set"
assert isinstance(result, Result), "unexpected result type"
@@ -294,6 +312,9 @@
Throws ValueError if an XFAIL line has a syntax error.
"""
+ if self.xfail_not:
+ return False
+
features = self.config.available_features
triple = getattr(self.suite.config, 'target_triple', "")
@@ -393,15 +414,5 @@
BooleanExpression.tokenize(expr) for expr in
boolean_expressions if expr != '*'
)
- identifiers = set(filter(BooleanExpression.isIdentifier, tokens))
- return identifiers
-
- def isEarlyTest(self):
- """
- isEarlyTest() -> bool
-
- Check whether this test should be executed early in a particular run.
- This can be used for test suites with long running tests to maximize
- parallelism or where it is desirable to surface their failures early.
- """
- return self.suite.config.is_early
+ matchExpressions = set(filter(BooleanExpression.isMatchExpression, tokens))
+ return matchExpressions
diff --git a/src/llvm-project/llvm/utils/lit/lit/TestRunner.py b/src/llvm-project/llvm/utils/lit/lit/TestRunner.py
index f826bc9..35afa03 100644
--- a/src/llvm-project/llvm/utils/lit/lit/TestRunner.py
+++ b/src/llvm-project/llvm/utils/lit/lit/TestRunner.py
@@ -191,7 +191,13 @@
We use the same algorithm from MSDN as CPython
(http://msdn.microsoft.com/en-us/library/17w5ykft.aspx), but we treat more
- characters as needing quoting, such as double quotes themselves.
+ characters as needing quoting, such as double quotes themselves, and square
+ brackets.
+
+ For MSys based tools, this is very brittle though, because quoting an
+ argument makes the MSys based tool unescape backslashes where it shouldn't
+ (e.g. "a\b\\c\\\\d" becomes "a\b\c\\d" where it should stay as it was,
+ according to regular win32 command line parsing rules).
"""
result = []
needquote = False
@@ -203,7 +209,7 @@
result.append(' ')
# This logic differs from upstream list2cmdline.
- needquote = (" " in arg) or ("\t" in arg) or ("\"" in arg) or not arg
+ needquote = (" " in arg) or ("\t" in arg) or ("\"" in arg) or ("[" in arg) or (";" in arg) or not arg
if needquote:
result.append('"')
@@ -608,6 +614,7 @@
assert isinstance(cmd, ShUtil.Pipeline)
procs = []
+ proc_not_counts = []
default_stdin = subprocess.PIPE
stderrTempFiles = []
opened_files = []
@@ -653,6 +660,12 @@
if not args:
raise InternalShellError(j, "Error: 'not' requires a"
" subcommand")
+ elif args[0] == '!':
+ not_args.append(args.pop(0))
+ not_count += 1
+ if not args:
+ raise InternalShellError(j, "Error: '!' requires a"
+ " subcommand")
else:
break
@@ -699,7 +712,15 @@
# the assumptions that (1) environment variables are not intended to be
# relevant to 'not' commands and (2) the 'env' command should always
# blindly pass along the status it receives from any command it calls.
- args = not_args + args
+
+ # For plain negations, either 'not' without '--crash', or the shell
+ # operator '!', leave them out from the command to execute and
+ # invert the result code afterwards.
+ if not_crash:
+ args = not_args + args
+ not_count = 0
+ else:
+ not_args = []
stdin, stdout, stderr = processRedirects(j, default_stdin, cmd_shenv,
opened_files)
@@ -763,6 +784,7 @@
stderr = stderr,
env = cmd_shenv.env,
close_fds = kUseCloseFDs))
+ proc_not_counts.append(not_count)
# Let the helper know about this process
timeoutHelper.addProcess(procs[-1])
except OSError as e:
@@ -815,6 +837,10 @@
# Detect Ctrl-C in subprocess.
if res == -signal.SIGINT:
raise KeyboardInterrupt
+ if proc_not_counts[i] % 2:
+ res = not res
+ elif proc_not_counts[i] > 1:
+ res = 1 if res != 0 else 0
# Ensure the resulting output is always of string type.
try:
diff --git a/src/llvm-project/llvm/utils/lit/lit/TestTimes.py b/src/llvm-project/llvm/utils/lit/lit/TestTimes.py
new file mode 100644
index 0000000..621343f
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/lit/TestTimes.py
@@ -0,0 +1,41 @@
+import os
+
+
+def read_test_times(suite):
+ test_times = {}
+ test_times_file = os.path.join(suite.exec_root, '.lit_test_times.txt')
+ if not os.path.exists(test_times_file):
+ test_times_file = os.path.join(
+ suite.source_root, '.lit_test_times.txt')
+ if os.path.exists(test_times_file):
+ with open(test_times_file, 'r') as time_file:
+ for line in time_file:
+ time, path = line.split(maxsplit=1)
+ test_times[path.strip('\n')] = float(time)
+ return test_times
+
+
+def record_test_times(tests, lit_config):
+ times_by_suite = {}
+ for t in tests:
+ assert t.suite.test_times is None
+ if not t.result.elapsed:
+ continue
+ if not t.suite.exec_root in times_by_suite:
+ times_by_suite[t.suite.exec_root] = read_test_times(t.suite)
+ time = -t.result.elapsed if t.isFailure() else t.result.elapsed
+ # The "path" here is only used as a key into a dictionary. It is never
+ # used as an actual path to a filesystem API, therefore we use '/' as
+ # the canonical separator so that Unix and Windows machines can share
+ # timing data.
+ times_by_suite[t.suite.exec_root]['/'.join(t.path_in_suite)] = t.result.elapsed
+
+ for s, value in times_by_suite.items():
+ try:
+ path = os.path.join(s, '.lit_test_times.txt')
+ with open(path, 'w') as time_file:
+ for name, time in value.items():
+ time_file.write(("%e" % time) + ' ' + name + '\n')
+ except:
+ lit_config.warning('Could not save test time: ' + path)
+ continue
diff --git a/src/llvm-project/llvm/utils/lit/lit/TestingConfig.py b/src/llvm-project/llvm/utils/lit/lit/TestingConfig.py
index e6c1b93..d534d89 100644
--- a/src/llvm-project/llvm/utils/lit/lit/TestingConfig.py
+++ b/src/llvm-project/llvm/utils/lit/lit/TestingConfig.py
@@ -22,12 +22,13 @@
}
pass_vars = ['LIBRARY_PATH', 'LD_LIBRARY_PATH', 'SYSTEMROOT', 'TERM',
- 'CLANG', 'LD_PRELOAD', 'ASAN_OPTIONS', 'UBSAN_OPTIONS',
- 'LSAN_OPTIONS', 'ADB', 'ANDROID_SERIAL', 'SSH_AUTH_SOCK',
- 'SANITIZER_IGNORE_CVE_2016_2143', 'TMPDIR', 'TMP', 'TEMP',
- 'TEMPDIR', 'AVRLIT_BOARD', 'AVRLIT_PORT',
- 'FILECHECK_OPTS', 'VCINSTALLDIR', 'VCToolsinstallDir',
- 'VSINSTALLDIR', 'WindowsSdkDir', 'WindowsSDKLibVersion']
+ 'CLANG', 'LLDB', 'LD_PRELOAD', 'ASAN_OPTIONS',
+ 'UBSAN_OPTIONS', 'LSAN_OPTIONS', 'ADB', 'ANDROID_SERIAL',
+ 'SSH_AUTH_SOCK', 'SANITIZER_IGNORE_CVE_2016_2143',
+ 'TMPDIR', 'TMP', 'TEMP', 'TEMPDIR', 'AVRLIT_BOARD',
+ 'AVRLIT_PORT', 'FILECHECK_OPTS', 'VCINSTALLDIR',
+ 'VCToolsinstallDir', 'VSINSTALLDIR', 'WindowsSdkDir',
+ 'WindowsSDKLibVersion']
if sys.platform == 'win32':
pass_vars.append('INCLUDE')
@@ -61,7 +62,8 @@
test_source_root = None,
excludes = [],
available_features = available_features,
- pipefail = True)
+ pipefail = True,
+ standalone_tests = False)
def load_from_path(self, path, litConfig):
"""
@@ -106,7 +108,8 @@
environment, substitutions, unsupported,
test_exec_root, test_source_root, excludes,
available_features, pipefail, limit_to_features = [],
- is_early = False, parallelism_group = None):
+ is_early = False, parallelism_group = None,
+ standalone_tests = False):
self.parent = parent
self.name = str(name)
self.suffixes = set(suffixes)
@@ -119,12 +122,11 @@
self.excludes = set(excludes)
self.available_features = set(available_features)
self.pipefail = pipefail
+ self.standalone_tests = standalone_tests
# This list is used by TestRunner.py to restrict running only tests that
# require one of the features in this list if this list is non-empty.
# Configurations can set this list to restrict the set of tests to run.
self.limit_to_features = set(limit_to_features)
- # Whether the suite should be tested early in a given run.
- self.is_early = bool(is_early)
self.parallelism_group = parallelism_group
self._recursiveExpansionLimit = None
diff --git a/src/llvm-project/llvm/utils/lit/lit/__init__.py b/src/llvm-project/llvm/utils/lit/lit/__init__.py
index c281391..c7d1fe9 100644
--- a/src/llvm-project/llvm/utils/lit/lit/__init__.py
+++ b/src/llvm-project/llvm/utils/lit/lit/__init__.py
@@ -2,7 +2,7 @@
__author__ = 'Daniel Dunbar'
__email__ = '[email protected]'
-__versioninfo__ = (12, 0, 1)
+__versioninfo__ = (13, 0, 0)
__version__ = '.'.join(str(v) for v in __versioninfo__) + 'dev'
__all__ = []
diff --git a/src/llvm-project/llvm/utils/lit/lit/cl_arguments.py b/src/llvm-project/llvm/utils/lit/lit/cl_arguments.py
index ddb4d25..70e0c8d 100644
--- a/src/llvm-project/llvm/utils/lit/lit/cl_arguments.py
+++ b/src/llvm-project/llvm/utils/lit/lit/cl_arguments.py
@@ -1,4 +1,5 @@
import argparse
+import enum
import os
import shlex
import sys
@@ -7,6 +8,11 @@
import lit.util
+class TestOrder(enum.Enum):
+ DEFAULT = enum.auto()
+ RANDOM = enum.auto()
+
+
def parse_args():
parser = argparse.ArgumentParser(prog='lit')
parser.add_argument('test_paths',
@@ -123,6 +129,10 @@
execution_group.add_argument("--allow-empty-runs",
help="Do not fail the run if all tests are filtered out",
action="store_true")
+ execution_group.add_argument("--ignore-fail",
+ dest="ignoreFail",
+ action="store_true",
+ help="Exit with status zero even if some tests fail")
execution_group.add_argument("--no-indirectly-run-check",
dest="indirectlyRunCheck",
help="Do not error if a test would not be run if the user had "
@@ -144,13 +154,28 @@
help="Run tests in random order",
action="store_true")
selection_group.add_argument("-i", "--incremental",
- help="Run modified and failing tests first (updates mtimes)",
+ help="Run failed tests first (DEPRECATED: now always enabled)",
action="store_true")
selection_group.add_argument("--filter",
metavar="REGEX",
type=_case_insensitive_regex,
help="Only run tests with paths matching the given regular expression",
default=os.environ.get("LIT_FILTER", ".*"))
+ selection_group.add_argument("--filter-out",
+ metavar="REGEX",
+ type=_case_insensitive_regex,
+ help="Filter out tests with paths matching the given regular expression",
+ default=os.environ.get("LIT_FILTER_OUT", "^$"))
+ selection_group.add_argument("--xfail",
+ metavar="LIST",
+ type=_semicolon_list,
+ help="XFAIL tests with paths in the semicolon separated list",
+ default=os.environ.get("LIT_XFAIL", ""))
+ selection_group.add_argument("--xfail-not",
+ metavar="LIST",
+ type=_semicolon_list,
+ help="do not XFAIL tests with paths in the semicolon separated list",
+ default=os.environ.get("LIT_XFAIL_NOT", ""))
selection_group.add_argument("--num-shards",
dest="numShards",
metavar="M",
@@ -187,13 +212,13 @@
if opts.echoAllCommands:
opts.showOutput = True
- # TODO(python3): Could be enum
+ if opts.incremental:
+ print('WARNING: --incremental is deprecated. Failing tests now always run first.')
+
if opts.shuffle:
- opts.order = 'random'
- elif opts.incremental:
- opts.order = 'failing-first'
+ opts.order = TestOrder.RANDOM
else:
- opts.order = 'default'
+ opts.order = TestOrder.DEFAULT
if opts.numShards or opts.runShard:
if not opts.numShards or not opts.runShard:
@@ -236,6 +261,10 @@
raise _error("invalid regular expression: '{}', {}", arg, reason)
+def _semicolon_list(arg):
+ return arg.split(';')
+
+
def _error(desc, *args):
msg = desc.format(*args)
return argparse.ArgumentTypeError(msg)
diff --git a/src/llvm-project/llvm/utils/lit/lit/discovery.py b/src/llvm-project/llvm/utils/lit/lit/discovery.py
index 2f027a5..bb77aa3 100644
--- a/src/llvm-project/llvm/utils/lit/lit/discovery.py
+++ b/src/llvm-project/llvm/utils/lit/lit/discovery.py
@@ -53,8 +53,7 @@
config_map = litConfig.params.get('config_map')
if config_map:
cfgpath = os.path.realpath(cfgpath)
- cfgpath = os.path.normcase(cfgpath)
- target = config_map.get(cfgpath)
+ target = config_map.get(os.path.normcase(cfgpath))
if target:
cfgpath = target
@@ -160,8 +159,13 @@
# tests which are not executed. The check adds some performance
# overhead which might be important if a large number of tests
# are being run directly.
- # --no-indirectly-run-check: skips this check.
- if indirectlyRunCheck and lc.test_format is not None:
+ # This check can be disabled by using --no-indirectly-run-check or
+ # setting the standalone_tests variable in the suite's configuration.
+ if (
+ indirectlyRunCheck
+ and lc.test_format is not None
+ and not lc.standalone_tests
+ ):
found = False
for res in lc.test_format.getTestsInDirectory(ts, test_dir_in_suite,
litConfig, lc):
@@ -171,6 +175,7 @@
if not found:
litConfig.error(
'%r would not be run indirectly: change name or LIT config'
+ '(e.g. suffixes or standalone_tests variables)'
% test.getFullName())
yield test
@@ -180,6 +185,15 @@
# local configuration.
lc = getLocalConfig(ts, path_in_suite, litConfig, localConfigCache)
+ # Directory contains tests to be run standalone. Do not try to discover.
+ if lc.standalone_tests:
+ if lc.suffixes or lc.excludes:
+ litConfig.warning(
+ 'standalone_tests set in LIT config but suffixes or excludes'
+ ' are also set'
+ )
+ return
+
# Search for tests.
if lc.test_format is not None:
for res in lc.test_format.getTestsInDirectory(ts, path_in_suite,
@@ -266,6 +280,12 @@
if prev == len(tests):
lit_config.warning('input %r contained no tests' % input)
+ # This data is no longer needed but keeping it around causes awful
+ # performance problems while the test suites run.
+ for k, suite in test_suite_cache.items():
+ if suite[0]:
+ suite[0].test_times = None
+
# If there were any errors during test discovery, exit now.
if lit_config.numErrors:
sys.stderr.write('%d errors, exiting.\n' % lit_config.numErrors)
diff --git a/src/llvm-project/llvm/utils/lit/lit/display.py b/src/llvm-project/llvm/utils/lit/lit/display.py
index 3543b28..51a05e8 100644
--- a/src/llvm-project/llvm/utils/lit/lit/display.py
+++ b/src/llvm-project/llvm/utils/lit/lit/display.py
@@ -5,8 +5,10 @@
if opts.quiet:
return NopDisplay()
- of_total = (' of %d' % total_tests) if (tests != total_tests) else ''
- header = '-- Testing: %d%s tests, %d workers --' % (tests, of_total, workers)
+ num_tests = len(tests)
+ of_total = (' of %d' % total_tests) if (num_tests != total_tests) else ''
+ header = '-- Testing: %d%s tests, %d workers --' % (
+ num_tests, of_total, workers)
progress_bar = None
if opts.succinct and opts.useProgressBar:
@@ -21,6 +23,44 @@
return Display(opts, tests, header, progress_bar)
+class ProgressPredictor(object):
+ def __init__(self, tests):
+ self.completed = 0
+ self.time_elapsed = 0.0
+ self.predictable_tests_remaining = 0
+ self.predictable_time_remaining = 0.0
+ self.unpredictable_tests_remaining = 0
+
+ for test in tests:
+ if test.previous_elapsed:
+ self.predictable_tests_remaining += 1
+ self.predictable_time_remaining += test.previous_elapsed
+ else:
+ self.unpredictable_tests_remaining += 1
+
+ def update(self, test):
+ self.completed += 1
+ self.time_elapsed += test.result.elapsed
+
+ if test.previous_elapsed:
+ self.predictable_tests_remaining -= 1
+ self.predictable_time_remaining -= test.previous_elapsed
+ else:
+ self.unpredictable_tests_remaining -= 1
+
+ # NOTE: median would be more precise, but might be too slow.
+ average_test_time = (self.time_elapsed + self.predictable_time_remaining) / \
+ (self.completed + self.predictable_tests_remaining)
+ unpredictable_time_remaining = average_test_time * \
+ self.unpredictable_tests_remaining
+ total_time_remaining = self.predictable_time_remaining + unpredictable_time_remaining
+ total_time = self.time_elapsed + total_time_remaining
+
+ if total_time > 0:
+ return self.time_elapsed / total_time
+ return 0
+
+
class NopDisplay(object):
def print_header(self): pass
def update(self, test): pass
@@ -30,8 +70,10 @@
class Display(object):
def __init__(self, opts, tests, header, progress_bar):
self.opts = opts
- self.tests = tests
+ self.num_tests = len(tests)
self.header = header
+ self.progress_predictor = ProgressPredictor(
+ tests) if progress_bar else None
self.progress_bar = progress_bar
self.completed = 0
@@ -55,7 +97,7 @@
if self.progress_bar:
if test.isFailure():
self.progress_bar.barColor = 'RED'
- percent = float(self.completed) / self.tests
+ percent = self.progress_predictor.update(test)
self.progress_bar.update(percent, test.getFullName())
def clear(self, interrupted):
@@ -66,7 +108,7 @@
# Show the test result line.
test_name = test.getFullName()
print('%s: %s (%d of %d)' % (test.result.code.name, test_name,
- self.completed, self.tests))
+ self.completed, self.num_tests))
# Show the test failure output, if requested.
if (test.isFailure() and self.opts.showOutput) or \
diff --git a/src/llvm-project/llvm/utils/lit/lit/formats/googletest.py b/src/llvm-project/llvm/utils/lit/lit/formats/googletest.py
index 059eb99..d8f3d35 100644
--- a/src/llvm-project/llvm/utils/lit/lit/formats/googletest.py
+++ b/src/llvm-project/llvm/utils/lit/lit/formats/googletest.py
@@ -1,5 +1,6 @@
from __future__ import absolute_import
import os
+import shlex
import subprocess
import sys
@@ -11,7 +12,7 @@
kIsWindows = sys.platform in ['win32', 'cygwin']
class GoogleTest(TestFormat):
- def __init__(self, test_sub_dirs, test_suffix):
+ def __init__(self, test_sub_dirs, test_suffix, run_under = []):
self.test_sub_dirs = str(test_sub_dirs).split(';')
# On Windows, assume tests will also end in '.exe'.
@@ -21,6 +22,7 @@
# Also check for .py files for testing purposes.
self.test_suffixes = {exe_suffix, test_suffix + '.py'}
+ self.run_under = run_under
def getGTestTests(self, path, litConfig, localConfig):
"""getGTestTests(path) - [name]
@@ -32,7 +34,7 @@
litConfig: LitConfig instance
localConfig: TestingConfig instance"""
- list_test_cmd = self.maybeAddPythonToCmd([path, '--gtest_list_tests'])
+ list_test_cmd = self.prepareCmd([path, '--gtest_list_tests'])
try:
output = subprocess.check_output(list_test_cmd,
@@ -113,41 +115,52 @@
testName = namePrefix + '/' + testName
cmd = [testPath, '--gtest_filter=' + testName]
- cmd = self.maybeAddPythonToCmd(cmd)
+ cmd = self.prepareCmd(cmd)
if litConfig.useValgrind:
cmd = litConfig.valgrindArgs + cmd
if litConfig.noExecute:
return lit.Test.PASS, ''
+ header = f"Script:\n--\n{' '.join(cmd)}\n--\n"
+
try:
out, err, exitCode = lit.util.executeCommand(
cmd, env=test.config.environment,
timeout=litConfig.maxIndividualTestTime)
except lit.util.ExecuteCommandTimeoutException:
return (lit.Test.TIMEOUT,
- 'Reached timeout of {} seconds'.format(
- litConfig.maxIndividualTestTime)
- )
+ f'{header}Reached timeout of '
+ f'{litConfig.maxIndividualTestTime} seconds')
if exitCode:
- return lit.Test.FAIL, out + err
+ return lit.Test.FAIL, header + out + err
+
+ if '[ SKIPPED ] 1 test,' in out:
+ return lit.Test.SKIPPED, ''
passing_test_line = '[ PASSED ] 1 test.'
if passing_test_line not in out:
- msg = ('Unable to find %r in gtest output:\n\n%s%s' %
- (passing_test_line, out, err))
- return lit.Test.UNRESOLVED, msg
+ return (lit.Test.UNRESOLVED,
+ f'{header}Unable to find {passing_test_line} '
+ f'in gtest output:\n\n{out}{err}')
return lit.Test.PASS,''
- def maybeAddPythonToCmd(self, cmd):
- """Insert the python exe into the command if cmd[0] ends in .py
+ def prepareCmd(self, cmd):
+ """Insert interpreter if needed.
+ It inserts the python exe into the command if cmd[0] ends in .py or caller
+ specified run_under.
We cannot rely on the system to interpret shebang lines for us on
Windows, so add the python executable to the command if this is a .py
script.
"""
if cmd[0].endswith('.py'):
- return [sys.executable] + cmd
+ cmd = [sys.executable] + cmd
+ if self.run_under:
+ if isinstance(self.run_under, list):
+ cmd = self.run_under + cmd
+ else:
+ cmd = shlex.split(self.run_under) + cmd
return cmd
diff --git a/src/llvm-project/llvm/utils/lit/lit/llvm/config.py b/src/llvm-project/llvm/utils/lit/lit/llvm/config.py
index 949c5e6..7bc4b44 100644
--- a/src/llvm-project/llvm/utils/lit/lit/llvm/config.py
+++ b/src/llvm-project/llvm/utils/lit/lit/llvm/config.py
@@ -4,6 +4,7 @@
import re
import subprocess
import sys
+import errno
import lit.util
from lit.llvm.subst import FindTool
@@ -25,7 +26,8 @@
# Seek necessary tools in directories and set to $PATH.
path = None
lit_tools_dir = getattr(config, 'lit_tools_dir', None)
- required_tools = ['cmp.exe', 'grep.exe', 'sed.exe', 'diff.exe', 'echo.exe']
+ required_tools = [
+ 'cmp.exe', 'grep.exe', 'sed.exe', 'diff.exe', 'echo.exe']
path = self.lit_config.getToolsPath(lit_tools_dir,
config.environment['PATH'],
required_tools)
@@ -33,8 +35,10 @@
path = self._find_git_windows_unix_tools(required_tools)
if path is not None:
self.with_environment('PATH', path, append_path=True)
- # Many tools behave strangely if these environment variables aren't set.
- self.with_system_environment(['SystemDrive', 'SystemRoot', 'TEMP', 'TMP'])
+ # Many tools behave strangely if these environment variables aren't
+ # set.
+ self.with_system_environment(
+ ['SystemDrive', 'SystemRoot', 'TEMP', 'TMP'])
self.use_lit_shell = True
global lit_path_displayed
@@ -42,8 +46,9 @@
self.lit_config.note("using lit tools: {}".format(path))
lit_path_displayed = True
- # Choose between lit's internal shell pipeline runner and a real shell. If
- # LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
+ # Choose between lit's internal shell pipeline runner and a real shell.
+ # If LIT_USE_INTERNAL_SHELL is in the environment, we use that as an
+ # override.
lit_shell_env = os.environ.get('LIT_USE_INTERNAL_SHELL')
if lit_shell_env:
self.use_lit_shell = lit.util.pythonize_bool(lit_shell_env)
@@ -102,7 +107,8 @@
if re.match(r'^x86_64.*-apple', target_triple):
features.add('x86_64-apple')
host_cxx = getattr(config, 'host_cxx', None)
- if 'address' in sanitizers and self.get_clang_has_lsan(host_cxx, target_triple):
+ if ('address' in sanitizers and
+ self.get_clang_has_lsan(host_cxx, target_triple)):
self.with_environment(
'ASAN_OPTIONS', 'detect_leaks=1', append_path=True)
if re.match(r'^x86_64.*-linux', target_triple):
@@ -120,8 +126,8 @@
if lit.util.pythonize_bool(use_gmalloc):
# Allow use of an explicit path for gmalloc library.
# Will default to '/usr/lib/libgmalloc.dylib' if not set.
- gmalloc_path_str = lit_config.params.get('gmalloc_path',
- '/usr/lib/libgmalloc.dylib')
+ gmalloc_path_str = lit_config.params.get(
+ 'gmalloc_path', '/usr/lib/libgmalloc.dylib')
if gmalloc_path_str is not None:
self.with_environment(
'DYLD_INSERT_LIBRARIES', gmalloc_path_str)
@@ -145,7 +151,8 @@
if not install_root:
continue
candidate_path = os.path.join(install_root, 'usr', 'bin')
- if not lit.util.checkToolsPath(candidate_path, tools_needed):
+ if not lit.util.checkToolsPath(
+ candidate_path, tools_needed):
continue
# We found it, stop enumerating.
@@ -157,8 +164,8 @@
def with_environment(self, variable, value, append_path=False):
if append_path:
- # For paths, we should be able to take a list of them and process all
- # of them.
+ # For paths, we should be able to take a list of them and process
+ # all of them.
paths_to_add = value
if lit.util.is_string(paths_to_add):
paths_to_add = [paths_to_add]
@@ -177,8 +184,8 @@
# and adding each to the beginning would result in c b a. So we
# need to iterate in reverse to end up with the original ordering.
for p in reversed(paths_to_add):
- # Move it to the front if it already exists, otherwise insert it at the
- # beginning.
+ # Move it to the front if it already exists, otherwise insert
+ # it at the beginning.
p = norm(p)
try:
paths.remove(p)
@@ -233,16 +240,17 @@
if re.search(re_pattern, feature_line):
self.config.available_features.add(feature)
- # Note that when substituting %clang_cc1 also fill in the include directory of
- # the builtin headers. Those are part of even a freestanding environment, but
- # Clang relies on the driver to locate them.
+ # Note that when substituting %clang_cc1 also fill in the include directory
+ # of the builtin headers. Those are part of even a freestanding
+ # environment, but Clang relies on the driver to locate them.
def get_clang_builtin_include_dir(self, clang):
- # FIXME: Rather than just getting the version, we should have clang print
- # out its resource dir here in an easy to scrape form.
+ # FIXME: Rather than just getting the version, we should have clang
+ # print out its resource dir here in an easy to scrape form.
clang_dir, _ = self.get_process_output(
[clang, '-print-file-name=include'])
if not clang_dir:
+ print(clang)
self.lit_config.fatal(
"Couldn't find the include dir for Clang ('%s')" % clang)
@@ -257,7 +265,8 @@
def get_clang_has_lsan(self, clang, triple):
if not clang:
self.lit_config.warning(
- 'config.host_cxx is unset but test suite is configured to use sanitizers.')
+ 'config.host_cxx is unset but test suite is configured '
+ 'to use sanitizers.')
return False
clang_binary = clang.split()[0]
@@ -273,15 +282,16 @@
return True
if re.match(r'^x86_64.*-apple', triple):
- version_regex = re.search(r'version ([0-9]+)\.([0-9]+).([0-9]+)', version_string)
+ version_regex = re.search(r'version ([0-9]+)\.([0-9]+).([0-9]+)',
+ version_string)
major_version_number = int(version_regex.group(1))
minor_version_number = int(version_regex.group(2))
patch_version_number = int(version_regex.group(3))
- if ('Apple LLVM' in version_string) or ('Apple clang' in version_string):
+ if ('Apple LLVM' in version_string or
+ 'Apple clang' in version_string):
# Apple clang doesn't yet support LSan
return False
- else:
- return major_version_number >= 5
+ return major_version_number >= 5
return False
@@ -345,32 +355,73 @@
self.config.substitutions.extend(substitutions)
return True
+ def add_err_msg_substitutions(self):
+ # Python's strerror may not supply the same message
+ # as C++ std::error_code. One example of such a platform is
+ # Visual Studio. errc_messages may be supplied which contains the error
+ # messages for ENOENT, EISDIR, EINVAL and EACCES as a semi colon
+ # separated string. LLVM testsuites can use get_errc_messages in cmake
+ # to automatically get the messages and pass them into lit.
+ errc_messages = getattr(self.config, 'errc_messages', '')
+ if len(errc_messages) != 0:
+ (errc_enoent, errc_eisdir,
+ errc_einval, errc_eacces) = errc_messages.split(';')
+ self.config.substitutions.append(
+ ('%errc_ENOENT', '\'' + errc_enoent + '\''))
+ self.config.substitutions.append(
+ ('%errc_EISDIR', '\'' + errc_eisdir + '\''))
+ self.config.substitutions.append(
+ ('%errc_EINVAL', '\'' + errc_einval + '\''))
+ self.config.substitutions.append(
+ ('%errc_EACCES', '\'' + errc_eacces + '\''))
+ else:
+ self.config.substitutions.append(
+ ('%errc_ENOENT', '\'' + os.strerror(errno.ENOENT) + '\''))
+ self.config.substitutions.append(
+ ('%errc_EISDIR', '\'' + os.strerror(errno.EISDIR) + '\''))
+ self.config.substitutions.append(
+ ('%errc_EINVAL', '\'' + os.strerror(errno.EINVAL) + '\''))
+ self.config.substitutions.append(
+ ('%errc_EACCES', '\'' + os.strerror(errno.EACCES) + '\''))
+
def use_default_substitutions(self):
tool_patterns = [
ToolSubst('FileCheck', unresolved='fatal'),
- # Handle these specially as they are strings searched for during testing.
- ToolSubst(r'\| \bcount\b', command=FindTool(
- 'count'), verbatim=True, unresolved='fatal'),
- ToolSubst(r'\| \bnot\b', command=FindTool('not'), verbatim=True, unresolved='fatal')]
+ # Handle these specially as they are strings searched for during
+ # testing.
+ ToolSubst(r'\| \bcount\b', command=FindTool('count'),
+ verbatim=True, unresolved='fatal'),
+ ToolSubst(r'\| \bnot\b', command=FindTool('not'),
+ verbatim=True, unresolved='fatal')]
self.config.substitutions.append(('%python', '"%s"' % (sys.executable)))
self.add_tool_substitutions(
tool_patterns, [self.config.llvm_tools_dir])
- def use_llvm_tool(self, name, search_env=None, required=False, quiet=False):
+ self.add_err_msg_substitutions()
+
+ def use_llvm_tool(self, name, search_env=None, required=False, quiet=False,
+ search_paths=None, use_installed=False):
"""Find the executable program 'name', optionally using the specified
- environment variable as an override before searching the
- configuration's PATH."""
+ environment variable as an override before searching the build directory
+ and then optionally the configuration's PATH."""
# If the override is specified in the environment, use it without
# validation.
+ tool = None
if search_env:
tool = self.config.environment.get(search_env)
- if tool:
- return tool
- # Otherwise look in the path.
- tool = lit.util.which(name, self.config.environment['PATH'])
+ if not tool:
+ if search_paths is None:
+ search_paths = [self.config.llvm_tools_dir]
+ # Use the specified search paths.
+ path = os.pathsep.join(search_paths)
+ tool = lit.util.which(name, path)
+
+ if not tool and use_installed:
+ # Otherwise look in the path, if enabled.
+ tool = lit.util.which(name, self.config.environment['PATH'])
if required and not tool:
message = "couldn't find '{}' program".format(name)
@@ -385,11 +436,12 @@
self.lit_config.note('using {}: {}'.format(name, tool))
return tool
- def use_clang(self, additional_tool_dirs=[], additional_flags=[], required=True):
+ def use_clang(self, additional_tool_dirs=[], additional_flags=[],
+ required=True, use_installed=False):
"""Configure the test suite to be able to invoke clang.
Sets up some environment variables important to clang, locates a
- just-built or installed clang, and add a set of standard
+ just-built or optionally an installed clang, and add a set of standard
substitutions useful to any test suite that makes use of clang.
"""
@@ -401,19 +453,22 @@
#
# FIXME: Should we have a tool that enforces this?
- # safe_env_vars = ('TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD',
- # 'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET',
- # 'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS',
- # 'VC80COMNTOOLS')
- possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS',
- 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
- 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
- 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
- 'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING',
- 'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX',
- 'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS',
- 'LIBCLANG_RESOURCE_USAGE',
- 'LIBCLANG_CODE_COMPLETION_LOGGING']
+ # safe_env_vars = (
+ # 'TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD',
+ # 'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET',
+ # 'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS',
+ # 'VC80COMNTOOLS')
+ possibly_dangerous_env_vars = [
+ 'COMPILER_PATH', 'RC_DEBUG_OPTIONS',
+ 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
+ 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
+ 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
+ 'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING',
+ 'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX',
+ 'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS',
+ 'LIBCLANG_RESOURCE_USAGE',
+ 'LIBCLANG_CODE_COMPLETION_LOGGING',
+ ]
# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it.
if platform.system() != 'Windows':
possibly_dangerous_env_vars.append('INCLUDE')
@@ -421,18 +476,25 @@
self.clear_environment(possibly_dangerous_env_vars)
# Tweak the PATH to include the tools dir and the scripts dir.
- # Put Clang first to avoid LLVM from overriding out-of-tree clang builds.
- exe_dir_props = [self.config.name.lower() + '_tools_dir', 'clang_tools_dir', 'llvm_tools_dir']
+ # Put Clang first to avoid LLVM from overriding out-of-tree clang
+ # builds.
+ exe_dir_props = [self.config.name.lower() + '_tools_dir',
+ 'clang_tools_dir', 'llvm_tools_dir']
paths = [getattr(self.config, pp) for pp in exe_dir_props
if getattr(self.config, pp, None)]
paths = additional_tool_dirs + paths
self.with_environment('PATH', paths, append_path=True)
- lib_dir_props = [self.config.name.lower() + '_libs_dir', 'clang_libs_dir', 'llvm_shlib_dir', 'llvm_libs_dir']
- paths = [getattr(self.config, pp) for pp in lib_dir_props
- if getattr(self.config, pp, None)]
+ lib_dir_props = [
+ self.config.name.lower() + '_libs_dir',
+ 'clang_libs_dir',
+ 'llvm_shlib_dir',
+ 'llvm_libs_dir',
+ ]
+ lib_paths = [getattr(self.config, pp) for pp in lib_dir_props
+ if getattr(self.config, pp, None)]
- self.with_environment('LD_LIBRARY_PATH', paths, append_path=True)
+ self.with_environment('LD_LIBRARY_PATH', lib_paths, append_path=True)
shl = getattr(self.config, 'llvm_shlib_dir', None)
pext = getattr(self.config, 'llvm_plugin_ext', None)
@@ -443,101 +505,133 @@
# Discover the 'clang' and 'clangcc' to use.
self.config.clang = self.use_llvm_tool(
- 'clang', search_env='CLANG', required=required)
+ 'clang', search_env='CLANG', required=required,
+ search_paths=paths, use_installed=use_installed)
if self.config.clang:
self.config.available_features.add('clang')
- builtin_include_dir = self.get_clang_builtin_include_dir(self.config.clang)
+ builtin_include_dir = self.get_clang_builtin_include_dir(
+ self.config.clang)
tool_substitutions = [
- ToolSubst('%clang', command=self.config.clang, extra_args=additional_flags),
- ToolSubst('%clang_analyze_cc1', command='%clang_cc1', extra_args=['-analyze', '%analyze', '-setup-static-analyzer']+additional_flags),
- ToolSubst('%clang_cc1', command=self.config.clang, extra_args=['-cc1', '-internal-isystem', builtin_include_dir, '-nostdsysteminc']+additional_flags),
- ToolSubst('%clang_cpp', command=self.config.clang, extra_args=['--driver-mode=cpp']+additional_flags),
- ToolSubst('%clang_cl', command=self.config.clang, extra_args=['--driver-mode=cl']+additional_flags),
- ToolSubst('%clangxx', command=self.config.clang, extra_args=['--driver-mode=g++']+additional_flags),
+ ToolSubst('%clang', command=self.config.clang,
+ extra_args=additional_flags),
+ ToolSubst('%clang_analyze_cc1', command='%clang_cc1',
+ extra_args=['-analyze', '%analyze',
+ '-setup-static-analyzer']+additional_flags),
+ ToolSubst('%clang_cc1', command=self.config.clang,
+ extra_args=['-cc1', '-internal-isystem',
+ builtin_include_dir, '-nostdsysteminc'] +
+ additional_flags),
+ ToolSubst('%clang_cpp', command=self.config.clang,
+ extra_args=['--driver-mode=cpp']+additional_flags),
+ ToolSubst('%clang_cl', command=self.config.clang,
+ extra_args=['--driver-mode=cl']+additional_flags),
+ ToolSubst('%clangxx', command=self.config.clang,
+ extra_args=['--driver-mode=g++']+additional_flags),
]
self.add_tool_substitutions(tool_substitutions)
self.config.substitutions.append(
('%resource_dir', builtin_include_dir))
- self.config.substitutions.append(('%itanium_abi_triple',
- self.make_itanium_abi_triple(self.config.target_triple)))
- self.config.substitutions.append(('%ms_abi_triple',
- self.make_msabi_triple(self.config.target_triple)))
+ self.config.substitutions.append(
+ ('%itanium_abi_triple',
+ self.make_itanium_abi_triple(self.config.target_triple)))
+ self.config.substitutions.append(
+ ('%ms_abi_triple',
+ self.make_msabi_triple(self.config.target_triple)))
- # The host triple might not be set, at least if we're compiling clang from
- # an already installed llvm.
- if self.config.host_triple and self.config.host_triple != '@LLVM_HOST_TRIPLE@':
- self.config.substitutions.append(('%target_itanium_abi_host_triple',
- '--target=%s' % self.make_itanium_abi_triple(self.config.host_triple)))
+ # The host triple might not be set, at least if we're compiling clang
+ # from an already installed llvm.
+ if (self.config.host_triple and
+ self.config.host_triple != '@LLVM_HOST_TRIPLE@'):
+ self.config.substitutions.append(
+ ('%target_itanium_abi_host_triple',
+ '--target=' + self.make_itanium_abi_triple(
+ self.config.host_triple)))
else:
self.config.substitutions.append(
('%target_itanium_abi_host_triple', ''))
# FIXME: Find nicer way to prohibit this.
+ def prefer(this, to):
+ return '''\"*** Do not use '%s' in tests, use '%s'. ***\"''' % (
+ to, this)
self.config.substitutions.append(
- (' clang ', """\"*** Do not use 'clang' in tests, use '%clang'. ***\""""))
+ (' clang ', prefer('%clang', 'clang')))
self.config.substitutions.append(
- (r' clang\+\+ ', """\"*** Do not use 'clang++' in tests, use '%clangxx'. ***\""""))
+ (r' clang\+\+ ', prefer('%clangxx', 'clang++')))
self.config.substitutions.append(
- (' clang-cc ',
- """\"*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***\""""))
+ (' clang-cc ', prefer('%clang_cc1', 'clang-cc')))
self.config.substitutions.append(
- (' clang-cl ',
- """\"*** Do not use 'clang-cl' in tests, use '%clang_cl'. ***\""""))
+ (' clang-cl ', prefer('%clang_cl', 'clang-cl')))
self.config.substitutions.append(
(' clang -cc1 -analyze ',
- """\"*** Do not use 'clang -cc1 -analyze' in tests, use '%clang_analyze_cc1'. ***\""""))
+ prefer('%clang_analyze_cc1', 'clang -cc1 -analyze')))
self.config.substitutions.append(
- (' clang -cc1 ',
- """\"*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***\""""))
+ (' clang -cc1 ', prefer('%clang_cc1', 'clang -cc1')))
self.config.substitutions.append(
(' %clang-cc1 ',
- """\"*** invalid substitution, use '%clang_cc1'. ***\""""))
+ '''\"*** invalid substitution, use '%clang_cc1'. ***\"'''))
self.config.substitutions.append(
(' %clang-cpp ',
- """\"*** invalid substitution, use '%clang_cpp'. ***\""""))
+ '''\"*** invalid substitution, use '%clang_cpp'. ***\"'''))
self.config.substitutions.append(
(' %clang-cl ',
- """\"*** invalid substitution, use '%clang_cl'. ***\""""))
+ '''\"*** invalid substitution, use '%clang_cl'. ***\"'''))
- def use_lld(self, additional_tool_dirs=[], required=True):
+ def use_lld(self, additional_tool_dirs=[], required=True,
+ use_installed=False):
"""Configure the test suite to be able to invoke lld.
Sets up some environment variables important to lld, locates a
- just-built or installed lld, and add a set of standard
+ just-built or optionally an installed lld, and add a set of standard
substitutions useful to any test suite that makes use of lld.
"""
# Tweak the PATH to include the tools dir and the scripts dir.
- exe_dir_props = [self.config.name.lower() + '_tools_dir', 'lld_tools_dir', 'llvm_tools_dir']
+ exe_dir_props = [self.config.name.lower() + '_tools_dir',
+ 'lld_tools_dir', 'llvm_tools_dir']
paths = [getattr(self.config, pp) for pp in exe_dir_props
if getattr(self.config, pp, None)]
paths = additional_tool_dirs + paths
self.with_environment('PATH', paths, append_path=True)
- lib_dir_props = [self.config.name.lower() + '_libs_dir', 'lld_libs_dir', 'llvm_libs_dir']
- paths = [getattr(self.config, pp) for pp in lib_dir_props
- if getattr(self.config, pp, None)]
+ lib_dir_props = [self.config.name.lower() + '_libs_dir',
+ 'lld_libs_dir', 'llvm_libs_dir']
+ lib_paths = [getattr(self.config, pp) for pp in lib_dir_props
+ if getattr(self.config, pp, None)]
- self.with_environment('LD_LIBRARY_PATH', paths, append_path=True)
+ self.with_environment('LD_LIBRARY_PATH', lib_paths, append_path=True)
- # Discover the 'clang' and 'clangcc' to use.
+ # Discover the LLD executables to use.
- ld_lld = self.use_llvm_tool('ld.lld', required=required)
- lld_link = self.use_llvm_tool('lld-link', required=required)
- ld64_lld = self.use_llvm_tool('ld64.lld', required=required)
- wasm_ld = self.use_llvm_tool('wasm-ld', required=required)
+ ld_lld = self.use_llvm_tool('ld.lld', required=required,
+ search_paths=paths,
+ use_installed=use_installed)
+ lld_link = self.use_llvm_tool('lld-link', required=required,
+ search_paths=paths,
+ use_installed=use_installed)
+ ld64_lld = self.use_llvm_tool('ld64.lld', required=required,
+ search_paths=paths,
+ use_installed=use_installed)
+ wasm_ld = self.use_llvm_tool('wasm-ld', required=required,
+ search_paths=paths,
+ use_installed=use_installed)
was_found = ld_lld and lld_link and ld64_lld and wasm_ld
tool_substitutions = []
if ld_lld:
tool_substitutions.append(ToolSubst(r'ld\.lld', command=ld_lld))
+ self.config.available_features.add('ld.lld')
if lld_link:
tool_substitutions.append(ToolSubst('lld-link', command=lld_link))
+ self.config.available_features.add('lld-link')
if ld64_lld:
tool_substitutions.append(ToolSubst(r'ld64\.lld', command=ld64_lld))
+ self.config.available_features.add('ld64.lld')
if wasm_ld:
tool_substitutions.append(ToolSubst('wasm-ld', command=wasm_ld))
+ self.config.available_features.add('wasm-ld')
self.add_tool_substitutions(tool_substitutions)
+
return was_found
diff --git a/src/llvm-project/llvm/utils/lit/lit/main.py b/src/llvm-project/llvm/utils/lit/lit/main.py
index 3d4f670..6924aee 100755
--- a/src/llvm-project/llvm/utils/lit/lit/main.py
+++ b/src/llvm-project/llvm/utils/lit/lit/main.py
@@ -18,6 +18,7 @@
import lit.run
import lit.Test
import lit.util
+from lit.TestTimes import record_test_times
def main(builtin_params={}):
@@ -68,7 +69,9 @@
determine_order(discovered_tests, opts.order)
selected_tests = [t for t in discovered_tests if
- opts.filter.search(t.getFullName())]
+ opts.filter.search(t.getFullName()) and not
+ opts.filter_out.search(t.getFullName())]
+
if not selected_tests:
sys.stderr.write('error: filter did not match any tests '
'(of %d discovered). ' % len(discovered_tests))
@@ -95,12 +98,16 @@
selected_tests = selected_tests[:opts.max_tests]
+ mark_xfail(discovered_tests, opts)
+
mark_excluded(discovered_tests, selected_tests)
start = time.time()
run_tests(selected_tests, lit_config, opts, len(discovered_tests))
elapsed = time.time() - start
+ record_test_times(selected_tests, lit_config)
+
if opts.time_tests:
print_histogram(discovered_tests)
@@ -118,8 +125,11 @@
has_failure = any(t.isFailure() for t in discovered_tests)
if has_failure:
- sys.exit(1)
-
+ if opts.ignoreFail:
+ sys.stderr.write("\nExiting with status 0 instead of 1 because "
+ "'--ignore-fail' was specified.\n")
+ else:
+ sys.exit(1)
def create_params(builtin_params, user_params):
def parse(p):
@@ -155,21 +165,13 @@
def determine_order(tests, order):
- assert order in ['default', 'random', 'failing-first']
- if order == 'default':
- tests.sort(key=lambda t: (not t.isEarlyTest(), t.getFullName()))
- elif order == 'random':
+ from lit.cl_arguments import TestOrder
+ if order == TestOrder.RANDOM:
import random
random.shuffle(tests)
else:
- def by_mtime(test):
- return os.path.getmtime(test.getFilePath())
- tests.sort(key=by_mtime, reverse=True)
-
-
-def touch_file(test):
- if test.isFailure():
- os.utime(test.getFilePath(), None)
+ assert order == TestOrder.DEFAULT, 'Unknown TestOrder value'
+ tests.sort(key=lambda t: (not t.previous_failure, -t.previous_elapsed, t.getFullName()))
def filter_by_shard(tests, run, shards, lit_config):
@@ -189,6 +191,15 @@
return selected_tests
+def mark_xfail(selected_tests, opts):
+ for t in selected_tests:
+ test_file = os.sep.join(t.path_in_suite)
+ test_full_name = t.getFullName()
+ if test_file in opts.xfail or test_full_name in opts.xfail:
+ t.xfails += '*'
+ if test_file in opts.xfail_not or test_full_name in opts.xfail_not:
+ t.xfail_not = True
+
def mark_excluded(discovered_tests, selected_tests):
excluded_tests = set(discovered_tests) - set(selected_tests)
result = lit.Test.Result(lit.Test.EXCLUDED)
@@ -198,15 +209,9 @@
def run_tests(tests, lit_config, opts, discovered_tests):
workers = min(len(tests), opts.workers)
- display = lit.display.create_display(opts, len(tests), discovered_tests,
- workers)
+ display = lit.display.create_display(opts, tests, discovered_tests, workers)
- def progress_callback(test):
- display.update(test)
- if opts.order == 'failing-first':
- touch_file(test)
-
- run = lit.run.Run(tests, lit_config, workers, progress_callback,
+ run = lit.run.Run(tests, lit_config, workers, display.update,
opts.max_failures, opts.timeout)
display.print_header()
@@ -268,7 +273,7 @@
tests_by_code[test.result.code].append(test)
for code in lit.Test.ResultCode.all_codes():
- print_group(tests_by_code[code], code, opts.shown_codes)
+ print_group(sorted(tests_by_code[code], key=lambda t: t.getFullName()), code, opts.shown_codes)
print_summary(tests_by_code, opts.quiet, elapsed)
diff --git a/src/llvm-project/llvm/utils/lit/lit/util.py b/src/llvm-project/llvm/utils/lit/lit/util.py
index 0d8f004..b02cf28 100644
--- a/src/llvm-project/llvm/utils/lit/lit/util.py
+++ b/src/llvm-project/llvm/utils/lit/lit/util.py
@@ -120,10 +120,10 @@
except AttributeError:
n = os.cpu_count() or 1
- # On Windows, with more than 32 processes, process creation often fails with
- # "Too many open files". FIXME: Check if there's a better fix.
+ # On Windows with more than 60 processes, multiprocessing's call to
+ # _winapi.WaitForMultipleObjects() prints an error and lit hangs.
if platform.system() == 'Windows':
- return min(n, 32)
+ return min(n, 60)
return n
diff --git a/src/llvm-project/llvm/utils/lit/setup.py b/src/llvm-project/llvm/utils/lit/setup.py
index df74a31..e42f11f 100644
--- a/src/llvm-project/llvm/utils/lit/setup.py
+++ b/src/llvm-project/llvm/utils/lit/setup.py
@@ -54,7 +54,7 @@
======
The *lit* source is available as part of LLVM, in the LLVM source repository:
-https://github.com/llvm/llvm-project/tree/master/llvm/utils/lit
+https://github.com/llvm/llvm-project/tree/main/llvm/utils/lit
""",
classifiers=[
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-format/DummySubDir/OneTest.py b/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-format/DummySubDir/OneTest.py
index dd49f02..7bff6b6 100644
--- a/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-format/DummySubDir/OneTest.py
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-format/DummySubDir/OneTest.py
@@ -10,6 +10,8 @@
FirstTest.
subTestA
subTestB
+ subTestC
+ subTestD
ParameterizedTest/0.
subTest
ParameterizedTest/1.
@@ -27,6 +29,15 @@
print('I am subTest B, I FAIL')
print('And I have two lines of output')
sys.exit(1)
+elif test_name == 'FirstTest.subTestC':
+ print('I am subTest C, I am SKIPPED')
+ print('[ PASSED ] 0 tests.')
+ print('[ SKIPPED ] 1 test, listed below:')
+ print('[ SKIPPED ] FirstTest.subTestC')
+ sys.exit(0)
+elif test_name == 'FirstTest.subTestD':
+ print('I am subTest D, I am UNRESOLVED')
+ sys.exit(0)
elif test_name in ('ParameterizedTest/0.subTest',
'ParameterizedTest/1.subTest'):
print('I am a parameterized test, I also PASS')
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-upstream-format/DummySubDir/OneTest.py b/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-upstream-format/DummySubDir/OneTest.py
index d7bc596..1061e39 100644
--- a/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-upstream-format/DummySubDir/OneTest.py
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/googletest-upstream-format/DummySubDir/OneTest.py
@@ -11,6 +11,8 @@
FirstTest.
subTestA
subTestB
+ subTestC
+ subTestD
ParameterizedTest/0.
subTest
ParameterizedTest/1.
@@ -29,6 +31,15 @@
print('I am subTest B, I FAIL')
print('And I have two lines of output')
sys.exit(1)
+elif test_name == 'FirstTest.subTestC':
+ print('I am subTest C, I am SKIPPED')
+ print('[ PASSED ] 0 tests.')
+ print('[ SKIPPED ] 1 test, listed below:')
+ print('[ SKIPPED ] FirstTest.subTestC')
+ sys.exit(0)
+elif test_name == 'FirstTest.subTestD':
+ print('I am subTest D, I am UNRESOLVED')
+ sys.exit(0)
elif test_name in ('ParameterizedTest/0.subTest',
'ParameterizedTest/1.subTest'):
print('I am a parameterized test, I also PASS')
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/fail.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/fail.txt
new file mode 100644
index 0000000..15eb81a
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/fail.txt
@@ -0,0 +1 @@
+RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/lit.cfg
new file mode 100644
index 0000000..d908833
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/lit.cfg
@@ -0,0 +1,6 @@
+import lit.formats
+config.name = 'ignore-fail'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/unresolved.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/unresolved.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/unresolved.txt
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/xfail.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/xfail.txt
new file mode 100644
index 0000000..6814cda
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/xfail.txt
@@ -0,0 +1,2 @@
+RUN: false
+XFAIL: *
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/xpass.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/xpass.txt
new file mode 100644
index 0000000..66b8a6a
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/ignore-fail/xpass.txt
@@ -0,0 +1,2 @@
+RUN: true
+XFAIL: *
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld.txt
new file mode 100644
index 0000000..2afd069
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld.lld.txt
@@ -0,0 +1,2 @@
+# REQUIRES: ld.lld
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld.txt
new file mode 100644
index 0000000..656c0ba
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/ld64.lld.txt
@@ -0,0 +1,2 @@
+# REQUIRES: ld64.lld
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lit.cfg
new file mode 100644
index 0000000..f9249ba
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lit.cfg
@@ -0,0 +1,17 @@
+import lit.formats
+config.name = 'search-env'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
+config.llvm_tools_dir = ''
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+import os.path
+curdir = os.path.dirname(__file__)
+# The current directory contains files for each version of LLD, both with and
+# without a .exe extension. The .exe versions will be found on Windows and the
+# ones without will be found on Linux. Note that all files are just empty files,
+# since the test doesn't actually use them.
+lit.llvm.llvm_config.with_environment('PATH', curdir, append_path=True)
+lit.llvm.llvm_config.use_lld(use_installed=True)
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link.txt
new file mode 100644
index 0000000..9553d05
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/lld-link.txt
@@ -0,0 +1,2 @@
+# REQUIRES: lld-link
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld.txt
new file mode 100644
index 0000000..e3487b4
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/lld-features/wasm-ld.txt
@@ -0,0 +1,2 @@
+# REQUIRES: wasm-ld
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/.lit_test_times.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/.lit_test_times.txt
new file mode 100644
index 0000000..73d55de
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/.lit_test_times.txt
@@ -0,0 +1,4 @@
+42.0 not-executed.txt
+3.0 subdir/ccc.txt
+2.0 bbb.txt
+0.1 aaa.txt
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/aaa.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/aaa.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/aaa.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/bbb.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/bbb.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/bbb.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/lit.cfg
new file mode 100644
index 0000000..6320609
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/lit.cfg
@@ -0,0 +1,6 @@
+import lit.formats
+config.name = 'reorder'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/new-test.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/new-test.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/new-test.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/subdir/ccc.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/subdir/ccc.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/reorder/subdir/ccc.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/show-used-features/mixed.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/show-used-features/mixed.txt
index 1de0f74..309b3ea 100644
--- a/src/llvm-project/llvm/utils/lit/tests/Inputs/show-used-features/mixed.txt
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/show-used-features/mixed.txt
@@ -1,4 +1,4 @@
-// REQUIRES: my-require-feature-2 || my-require-feature-3
-// UNSUPPORTED: my-unsupported-feature-2, my-unsupported-feature-3
-// XFAIL: my-xfail-feature-2, my-xfail-feature-3
+// REQUIRES: my-require-feature-2 || my-require-feature-3, my-{{[require]*}}-feature-4
+// UNSUPPORTED: my-unsupported-feature-2, my-unsupported-feature-3 && !my-{{[unsupported]*}}-feature-4
+// XFAIL: my-xfail-feature-2, my-xfail-feature-3, my-{{[xfail]*}}-feature-4
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-args-nested-none.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-args-nested-none.txt
new file mode 100644
index 0000000..86b350d
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-args-nested-none.txt
@@ -0,0 +1 @@
+# RUN: ! ! !
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-args-none.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-args-none.txt
new file mode 100644
index 0000000..8a5e1f9
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-args-none.txt
@@ -0,0 +1 @@
+# RUN: !
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-calls-external.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-calls-external.txt
new file mode 100644
index 0000000..035da88
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/exclamation-calls-external.txt
@@ -0,0 +1,9 @@
+# Simple uses of '!'
+
+# RUN: ! %{python} fail.py
+# RUN: ! ! %{python} pass.py
+# RUN: ! ! ! %{python} fail.py
+# RUN: ! ! ! ! %{python} pass.py
+
+# pass.py succeeds but we expect failure
+# RUN: ! %{python} pass.py
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/fail2.py b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/fail2.py
new file mode 100644
index 0000000..e9fb0bc
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/fail2.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+import print_environment
+import sys
+
+print_environment.execute()
+sys.exit(2)
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/not-calls-fail2.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/not-calls-fail2.txt
new file mode 100644
index 0000000..e184efc
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/shtest-not/not-calls-fail2.txt
@@ -0,0 +1,4 @@
+# Check that "not not" either returns 0 or 1, even if the original
+# program exited with a different code.
+
+# RUN: not not %{python} fail2.py
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-excludes/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-excludes/lit.cfg
new file mode 100644
index 0000000..37d96dd
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-excludes/lit.cfg
@@ -0,0 +1,5 @@
+import lit.formats
+config.name = 'Standalone tests'
+config.test_format = lit.formats.ShTest()
+config.excludes = ['.test']
+config.standalone_tests = True
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-excludes/true.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-excludes/true.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-excludes/true.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-suffixes/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-suffixes/lit.cfg
new file mode 100644
index 0000000..41434c9
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-suffixes/lit.cfg
@@ -0,0 +1,5 @@
+import lit.formats
+config.name = 'Standalone tests'
+config.test_format = lit.formats.ShTest()
+config.suffixes = ['.txt']
+config.standalone_tests = True
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-suffixes/true.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-suffixes/true.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests-with-suffixes/true.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests/lit.cfg
new file mode 100644
index 0000000..12ed7b0
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests/lit.cfg
@@ -0,0 +1,4 @@
+import lit.formats
+config.name = 'Standalone tests'
+config.test_format = lit.formats.ShTest()
+config.standalone_tests = True
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests/true.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests/true.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/standalone-tests/true.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/found b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/found
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/found
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/found.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/found.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/found.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/lit.cfg
new file mode 100644
index 0000000..b1c510e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/lit.cfg
@@ -0,0 +1,12 @@
+import lit.formats
+config.name = 'use-llvm-tool-required'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
+import os.path
+config.llvm_tools_dir = os.path.realpath(os.path.dirname(__file__))
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+lit.llvm.llvm_config.use_llvm_tool('found', required=True)
+lit.llvm.llvm_config.use_llvm_tool('not-found', required=True)
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/true.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/true.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool-required/true.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case10 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case10
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case10
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case10.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case10.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case10.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case2 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case2
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case2.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case2.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case2.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case3 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case3
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case3
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case3.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case3.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case3.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case6 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case6
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case6
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case6.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case6.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case6.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case7 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case7
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case7
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case7.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case7.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case7.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case9 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case9
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case9
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case9.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case9.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/build/case9.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/env-case1 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/env-case1
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/env-case1
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/env-case6 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/env-case6
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/env-case6
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/lit.cfg
new file mode 100644
index 0000000..2bd401a
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/lit.cfg
@@ -0,0 +1,25 @@
+import lit.formats
+config.name = 'use-llvm-tool'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
+config.test_source_root = None
+config.test_exec_root = None
+import os.path
+this_dir = os.path.realpath(os.path.dirname(__file__))
+config.llvm_tools_dir = os.path.join(this_dir, 'build')
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+lit.llvm.llvm_config.with_environment('CASE1', os.path.join(this_dir, 'env-case1'))
+lit.llvm.llvm_config.with_environment('CASE6', os.path.join(this_dir, 'env-case6'))
+lit.llvm.llvm_config.with_environment('PATH', os.path.join(this_dir, 'path'), append_path=True)
+lit.llvm.llvm_config.use_llvm_tool('case1', search_env='CASE1')
+lit.llvm.llvm_config.use_llvm_tool('case2', search_env='CASE2')
+lit.llvm.llvm_config.use_llvm_tool('case3')
+lit.llvm.llvm_config.use_llvm_tool('case4', use_installed=True)
+lit.llvm.llvm_config.use_llvm_tool('case5')
+lit.llvm.llvm_config.use_llvm_tool('case6', search_env='CASE6', use_installed=True)
+lit.llvm.llvm_config.use_llvm_tool('case7', use_installed=True)
+lit.llvm.llvm_config.use_llvm_tool('case8', use_installed=True)
+paths = [os.path.join(this_dir, 'search1'), os.path.join(this_dir, 'search2'), os.path.join(this_dir, 'search3')]
+lit.llvm.llvm_config.use_llvm_tool('case9', search_paths=paths)
+lit.llvm.llvm_config.use_llvm_tool('case10', search_paths=paths, use_installed=True)
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case10 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case10
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case10
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case10.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case10.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case10.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case4 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case4
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case4
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case4.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case4.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case4.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case5 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case5
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case5
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case5.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case5.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case5.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case6 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case6
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case6
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case6.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case6.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case6.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case7 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case7
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case7
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case7.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case7.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/path/case7.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search1/empty b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search1/empty
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search1/empty
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search2/case9 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search2/case9
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search2/case9
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search2/case9.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search2/case9.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search2/case9.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search3/case9 b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search3/case9
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search3/case9
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search3/case9.exe b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search3/case9.exe
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/search3/case9.exe
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/true.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/true.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/use-llvm-tool/true.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/false.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/false.txt
new file mode 100644
index 0000000..49932c3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/false.txt
@@ -0,0 +1 @@
+# RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/lit.cfg
new file mode 100644
index 0000000..09f49c3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/lit.cfg
@@ -0,0 +1,4 @@
+import lit.formats
+config.name = 'top-level-suite :: a'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/test-xfail.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/test-xfail.txt
new file mode 100644
index 0000000..b0d8552
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/test-xfail.txt
@@ -0,0 +1,2 @@
+# XFAIL: *
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/test.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/test.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/a/test.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/false.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/false.txt
new file mode 100644
index 0000000..49932c3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/false.txt
@@ -0,0 +1 @@
+# RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/lit.cfg
new file mode 100644
index 0000000..62f721c
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/lit.cfg
@@ -0,0 +1,4 @@
+import lit.formats
+config.name = 'top-level-suite :: b'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/test-xfail.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/test-xfail.txt
new file mode 100644
index 0000000..f0ae3fe
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/test-xfail.txt
@@ -0,0 +1,2 @@
+# XFAIL: *
+# RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/test.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/test.txt
new file mode 100644
index 0000000..49932c3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/b/test.txt
@@ -0,0 +1 @@
+# RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/false.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/false.txt
new file mode 100644
index 0000000..49932c3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/false.txt
@@ -0,0 +1 @@
+# RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/false2.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/false2.txt
new file mode 100644
index 0000000..49932c3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/false2.txt
@@ -0,0 +1 @@
+# RUN: false
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/lit.cfg
new file mode 100644
index 0000000..4568d61
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/lit.cfg
@@ -0,0 +1,4 @@
+import lit.formats
+config.name = 'top-level-suite'
+config.suffixes = ['.txt']
+config.test_format = lit.formats.ShTest()
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/true-xfail.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/true-xfail.txt
new file mode 100644
index 0000000..b0d8552
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/true-xfail.txt
@@ -0,0 +1,2 @@
+# XFAIL: *
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/true.txt b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/true.txt
new file mode 100644
index 0000000..b80b60b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/Inputs/xfail-cl/true.txt
@@ -0,0 +1 @@
+# RUN: true
diff --git a/src/llvm-project/llvm/utils/lit/tests/check-tested-lit-timeout-ability b/src/llvm-project/llvm/utils/lit/tests/check-tested-lit-timeout-ability
new file mode 100755
index 0000000..3b8dc13
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/check-tested-lit-timeout-ability
@@ -0,0 +1,11 @@
+#!/usr/bin/python3
+
+import sys
+from lit.util import killProcessAndChildrenIsSupported
+
+supported, errormsg = killProcessAndChildrenIsSupported()
+
+if not supported:
+ sys.exit(errormsg)
+
+sys.exit()
diff --git a/src/llvm-project/llvm/utils/lit/tests/custom-result-category.py b/src/llvm-project/llvm/utils/lit/tests/custom-result-category.py
index 8a374e3..d4608b3 100644
--- a/src/llvm-project/llvm/utils/lit/tests/custom-result-category.py
+++ b/src/llvm-project/llvm/utils/lit/tests/custom-result-category.py
@@ -1,6 +1,9 @@
# UNSUPPORTED: system-windows
# Test lit.main.add_result_category() extension API.
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/custom-result-category/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 %{inputs}/custom-result-category | FileCheck %s
# CHECK: CUSTOM_PASS: custom-result-category :: test1.txt
diff --git a/src/llvm-project/llvm/utils/lit/tests/discovery.py b/src/llvm-project/llvm/utils/lit/tests/discovery.py
index cb04eda..39743bf 100644
--- a/src/llvm-project/llvm/utils/lit/tests/discovery.py
+++ b/src/llvm-project/llvm/utils/lit/tests/discovery.py
@@ -148,6 +148,36 @@
# RUN: %{lit} \
# RUN: %{inputs}/discovery/test.not-txt -j 1 --no-indirectly-run-check
+# Check that a standalone test with no suffixes set is run without any errors.
+#
+# RUN: %{lit} %{inputs}/standalone-tests/true.txt -j 1 > %t.out
+# RUN: FileCheck --check-prefix=CHECK-STANDALONE < %t.out %s
+#
+# CHECK-STANDALONE: PASS: Standalone tests :: true.txt
+
+# Check that an error is produced if suffixes variable is set for a suite with
+# standalone tests.
+#
+# RUN: not %{lit} %{inputs}/standalone-tests-with-suffixes -j 1 2> %t.err
+# RUN: FileCheck --check-prefixes=CHECK-STANDALONE-SUFFIXES,CHECK-STANDALONE-DISCOVERY < %t.err %s
+#
+# CHECK-STANDALONE-SUFFIXES: standalone_tests set {{.*}} but suffixes
+
+# Check that an error is produced if excludes variable is set for a suite with
+# standalone tests.
+#
+# RUN: not %{lit} %{inputs}/standalone-tests-with-excludes -j 1 2> %t.err
+# RUN: FileCheck --check-prefixes=CHECK-STANDALONE-EXCLUDES,CHECK-STANDALONE-DISCOVERY < %t.err %s
+#
+# CHECK-STANDALONE-EXCLUDES: standalone_tests set {{.*}} but {{.*}} excludes
+
+# Check that no discovery is done for testsuite with standalone tests.
+#
+# RUN: not %{lit} %{inputs}/standalone-tests -j 1 2>%t.err
+# RUN: FileCheck --check-prefix=CHECK-STANDALONE-DISCOVERY < %t.err %s
+#
+# CHECK-STANDALONE-DISCOVERY: error: did not discover any tests for provided path(s)
+
# Check that we don't recurse infinitely when loading an site specific test
# suite located inside the test source root.
#
diff --git a/src/llvm-project/llvm/utils/lit/tests/googletest-format.py b/src/llvm-project/llvm/utils/lit/tests/googletest-format.py
index 8ea2f83..c5216f5 100644
--- a/src/llvm-project/llvm/utils/lit/tests/googletest-format.py
+++ b/src/llvm-project/llvm/utils/lit/tests/googletest-format.py
@@ -1,5 +1,8 @@
# Check the various features of the GoogleTest format.
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/googletest-format/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -v %{inputs}/googletest-format > %t.out
# FIXME: Temporarily dump test output so we can debug failing tests on
# buildbots.
@@ -9,15 +12,29 @@
# END.
# CHECK: -- Testing:
-# CHECK: PASS: googletest-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/FirstTest.subTestA
-# CHECK: FAIL: googletest-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/FirstTest.subTestB
-# CHECK-NEXT: *** TEST 'googletest-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/FirstTest.subTestB' FAILED ***
+# CHECK: PASS: googletest-format :: [[PATH:[Dd]ummy[Ss]ub[Dd]ir/]][[FILE:OneTest\.py]]/FirstTest.subTestA
+# CHECK: FAIL: googletest-format :: [[PATH]][[FILE]]/[[TEST:FirstTest\.subTestB]]
+# CHECK-NEXT: *** TEST 'googletest-format :: [[PATH]][[FILE]]/[[TEST]]' FAILED ***
+# CHECK-NEXT: Script:
+# CHECK-NEXT: --
+# CHECK-NEXT: [[FILE]] --gtest_filter=[[TEST]]
+# CHECK-NEXT: --
# CHECK-NEXT: I am subTest B, I FAIL
# CHECK-NEXT: And I have two lines of output
# CHECK: ***
-# CHECK: PASS: googletest-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/ParameterizedTest/0.subTest
-# CHECK: PASS: googletest-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/ParameterizedTest/1.subTest
+# CHECK: SKIPPED: googletest-format :: [[PATH]][[FILE]]/FirstTest.subTestC
+# CHECK: UNRESOLVED: googletest-format :: [[PATH]][[FILE]]/[[TEST:FirstTest\.subTestD]]
+# CHECK-NEXT: *** TEST 'googletest-format :: [[PATH]][[FILE]]/[[TEST]]' FAILED ***
+# CHECK-NEXT: Script:
+# CHECK-NEXT: --
+# CHECK-NEXT: [[FILE]] --gtest_filter=[[TEST]]
+# CHECK-NEXT: --
+# CHECK-NEXT: Unable to find [ PASSED ] 1 test. in gtest output
+# CHECK: I am subTest D, I am UNRESOLVED
+# CHECK: PASS: googletest-format :: [[PATH]][[FILE]]/ParameterizedTest/0.subTest
+# CHECK: PASS: googletest-format :: [[PATH]][[FILE]]/ParameterizedTest/1.subTest
# CHECK: Failed Tests (1)
-# CHECK: Passed: 3
-# CHECK: Failed: 1
-
+# CHECK: Skipped{{ *}}: 1
+# CHECK: Passed{{ *}}: 3
+# CHECK: Unresolved{{ *}}: 1
+# CHECK: Failed{{ *}}: 1
diff --git a/src/llvm-project/llvm/utils/lit/tests/googletest-timeout.py b/src/llvm-project/llvm/utils/lit/tests/googletest-timeout.py
index fece385..adfc4d9 100644
--- a/src/llvm-project/llvm/utils/lit/tests/googletest-timeout.py
+++ b/src/llvm-project/llvm/utils/lit/tests/googletest-timeout.py
@@ -19,7 +19,12 @@
# RUN: FileCheck --check-prefix=CHECK-INF < %t.cfgset.out %s
# CHECK-INF: -- Testing:
-# CHECK-INF: TIMEOUT: googletest-timeout :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/T.InfiniteLoopSubTest
+# CHECK-INF: TIMEOUT: googletest-timeout :: [[PATH:[Dd]ummy[Ss]ub[Dd]ir/]][[FILE:OneTest\.py]]/[[TEST:T\.InfiniteLoopSubTest]]
+# CHECK-INF-NEXT: ******************** TEST 'googletest-timeout :: [[PATH]][[FILE]]/[[TEST]]' FAILED ********************
+# CHECK-INF-NEXT: Script:
+# CHECK-INF-NEXT: --
+# CHECK-INF-NEXT: [[FILE]] --gtest_filter=[[TEST]]
+# CHECK-INF-NEXT: --
# CHECK-INF: Timed Out: 1
###############################################################################
diff --git a/src/llvm-project/llvm/utils/lit/tests/googletest-upstream-format.py b/src/llvm-project/llvm/utils/lit/tests/googletest-upstream-format.py
index a620877..8811b1e 100644
--- a/src/llvm-project/llvm/utils/lit/tests/googletest-upstream-format.py
+++ b/src/llvm-project/llvm/utils/lit/tests/googletest-upstream-format.py
@@ -1,20 +1,38 @@
# Check the various features of the GoogleTest format.
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/googletest-upstream-format/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -v %{inputs}/googletest-upstream-format > %t.out
# RUN: FileCheck < %t.out %s
#
# END.
# CHECK: -- Testing:
-# CHECK: PASS: googletest-upstream-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/FirstTest.subTestA
-# CHECK: FAIL: googletest-upstream-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/FirstTest.subTestB
-# CHECK-NEXT: *** TEST 'googletest-upstream-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/FirstTest.subTestB' FAILED ***
+# CHECK: PASS: googletest-upstream-format :: [[PATH:[Dd]ummy[Ss]ub[Dd]ir/]][[FILE:OneTest\.py]]/FirstTest.subTestA
+# CHECK: FAIL: googletest-upstream-format :: [[PATH]][[FILE]]/[[TEST:FirstTest\.subTestB]]
+# CHECK-NEXT: *** TEST 'googletest-upstream-format :: [[PATH]][[FILE]]/[[TEST]]' FAILED ***
+# CHECK-NEXT: Script:
+# CHECK-NEXT: --
+# CHECK-NEXT: [[FILE]] --gtest_filter=[[TEST]]
+# CHECK-NEXT: --
# CHECK-NEXT: Running main() from gtest_main.cc
# CHECK-NEXT: I am subTest B, I FAIL
# CHECK-NEXT: And I have two lines of output
+# CHECK: SKIPPED: googletest-upstream-format :: [[PATH]][[FILE]]/FirstTest.subTestC
+# CHECK: UNRESOLVED: googletest-upstream-format :: [[PATH]][[FILE]]/[[TEST:FirstTest\.subTestD]]
+# CHECK-NEXT: *** TEST 'googletest-upstream-format :: [[PATH]][[FILE]]/[[TEST]]' FAILED ***
+# CHECK-NEXT: Script:
+# CHECK-NEXT: --
+# CHECK-NEXT: [[FILE]] --gtest_filter=[[TEST]]
+# CHECK-NEXT: --
+# CHECK-NEXT: Unable to find [ PASSED ] 1 test. in gtest output
+# CHECK: I am subTest D, I am UNRESOLVED
# CHECK: ***
-# CHECK: PASS: googletest-upstream-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/ParameterizedTest/0.subTest
-# CHECK: PASS: googletest-upstream-format :: {{[Dd]ummy[Ss]ub[Dd]ir}}/OneTest.py/ParameterizedTest/1.subTest
+# CHECK: PASS: googletest-upstream-format :: [[PATH]][[FILE]]/ParameterizedTest/0.subTest
+# CHECK: PASS: googletest-upstream-format :: [[PATH]][[FILE]]/ParameterizedTest/1.subTest
# CHECK: Failed Tests (1)
-# CHECK: Passed: 3
-# CHECK: Failed: 1
+# CHECK: Skipped{{ *}}: 1
+# CHECK: Passed{{ *}}: 3
+# CHECK: Unresolved{{ *}}: 1
+# CHECK: Failed{{ *}}: 1
diff --git a/src/llvm-project/llvm/utils/lit/tests/ignore-fail.py b/src/llvm-project/llvm/utils/lit/tests/ignore-fail.py
new file mode 100644
index 0000000..63c3451
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/ignore-fail.py
@@ -0,0 +1,19 @@
+# Check that --ignore-fail produces exit status 0 despite various kinds of
+# test failures but doesn't otherwise suppress those failures.
+
+# RUN: not %{lit} -j 1 %{inputs}/ignore-fail | FileCheck %s
+# RUN: %{lit} -j 1 --ignore-fail %{inputs}/ignore-fail | FileCheck %s
+
+# END.
+
+# CHECK-DAG: FAIL: ignore-fail :: fail.txt
+# CHECK-DAG: UNRESOLVED: ignore-fail :: unresolved.txt
+# CHECK-DAG: XFAIL: ignore-fail :: xfail.txt
+# CHECK-DAG: XPASS: ignore-fail :: xpass.txt
+
+# CHECK: Testing Time:
+# CHECK-NEXT: Expectedly Failed : 1
+# CHECK-NEXT: Unresolved : 1
+# CHECK-NEXT: Failed : 1
+# CHECK-NEXT: Unexpectedly Passed: 1
+# CHECK-NOT: {{.}}
diff --git a/src/llvm-project/llvm/utils/lit/tests/lit.cfg b/src/llvm-project/llvm/utils/lit/tests/lit.cfg
index 3c49f07..c5c6d50 100644
--- a/src/llvm-project/llvm/utils/lit/tests/lit.cfg
+++ b/src/llvm-project/llvm/utils/lit/tests/lit.cfg
@@ -3,6 +3,7 @@
import os
import platform
import sys
+import subprocess
import lit.formats
from lit.llvm import llvm_config
@@ -71,11 +72,20 @@
config.environment['COVERAGE_PROCESS_START'] = os.path.join(
os.path.dirname(__file__), ".coveragerc")
-# Add a feature to detect if psutil is available
-supported, errormsg = lit_config.maxIndividualTestTimeIsSupported
-if supported:
+# Add a feature to detect if test cancellation is available. Check the ability
+# to do cancellation in the same environment as where RUN commands are run.
+# The reason is that on most systems cancellation depends on psutil being
+# available and RUN commands are run with a cleared PYTHONPATH and user site
+# packages disabled.
+testing_script_path = "/".join((os.path.dirname(__file__),
+ "check-tested-lit-timeout-ability"))
+proc = subprocess.run([sys.executable, testing_script_path],
+ stderr=subprocess.PIPE, env=config.environment,
+ universal_newlines=True)
+if proc.returncode == 0:
config.available_features.add("lit-max-individual-test-time")
else:
+ errormsg = proc.stderr
lit_config.warning('Setting a timeout per test not supported. ' + errormsg
+ ' Some tests will be skipped and the --timeout'
' command line argument will not work.')
@@ -95,7 +105,8 @@
# that might not be present or behave correctly on all platforms. Don't do
# this for 'echo' because an external version is used when it appears in a
# pipeline. Don't do this for ':' because it doesn't appear to be a valid file
-# name under Windows.
+# name under Windows. Don't do this for 'not' because lit uses the external
+# 'not' throughout a RUN line that calls 'not --crash'.
test_bin = os.path.join(os.path.dirname(__file__), 'Inputs', 'fake-externals')
config.environment['PATH'] = os.path.pathsep.join((test_bin,
config.environment['PATH']))
diff --git a/src/llvm-project/llvm/utils/lit/tests/lld-features.py b/src/llvm-project/llvm/utils/lit/tests/lld-features.py
new file mode 100644
index 0000000..d1c360e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/lld-features.py
@@ -0,0 +1,6 @@
+## Show that each of the LLD variants detected by use_lld comes with its own
+## feature.
+
+# RUN: %{lit} %{inputs}/lld-features 2>&1 | FileCheck %s -DDIR=%p
+
+# CHECK: Passed: 4
diff --git a/src/llvm-project/llvm/utils/lit/tests/progress-bar.py b/src/llvm-project/llvm/utils/lit/tests/progress-bar.py
index ceeca68..e6dafff 100644
--- a/src/llvm-project/llvm/utils/lit/tests/progress-bar.py
+++ b/src/llvm-project/llvm/utils/lit/tests/progress-bar.py
@@ -1,5 +1,8 @@
# Check the simple progress bar.
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/progress-bar/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -s %{inputs}/progress-bar > %t.out
# RUN: FileCheck < %t.out %s
#
diff --git a/src/llvm-project/llvm/utils/lit/tests/reorder.py b/src/llvm-project/llvm/utils/lit/tests/reorder.py
new file mode 100644
index 0000000..cac0a4e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/reorder.py
@@ -0,0 +1,23 @@
+## Check that we can reorder test runs.
+
+# RUN: cp %{inputs}/reorder/.lit_test_times.txt %{inputs}/reorder/.lit_test_times.txt.orig
+# RUN: %{lit} -j1 %{inputs}/reorder > %t.out
+# RUN: cp %{inputs}/reorder/.lit_test_times.txt %{inputs}/reorder/.lit_test_times.txt.new
+# RUN: cp %{inputs}/reorder/.lit_test_times.txt.orig %{inputs}/reorder/.lit_test_times.txt
+# RUN: not diff %{inputs}/reorder/.lit_test_times.txt.new %{inputs}/reorder/.lit_test_times.txt.orig
+# RUN: FileCheck --check-prefix=TIMES --implicit-check-not= < %{inputs}/reorder/.lit_test_times.txt.new %s
+# RUN: FileCheck < %t.out %s
+# END.
+
+# TIMES: not-executed.txt
+# TIMES-NEXT: subdir/ccc.txt
+# TIMES-NEXT: bbb.txt
+# TIMES-NEXT: aaa.txt
+# TIMES-NEXT: new-test.txt
+
+# CHECK: -- Testing: 4 tests, 1 workers --
+# CHECK-NEXT: PASS: reorder :: subdir/ccc.txt
+# CHECK-NEXT: PASS: reorder :: bbb.txt
+# CHECK-NEXT: PASS: reorder :: aaa.txt
+# CHECK-NEXT: PASS: reorder :: new-test.txt
+# CHECK: Passed: 4
diff --git a/src/llvm-project/llvm/utils/lit/tests/selecting.py b/src/llvm-project/llvm/utils/lit/tests/selecting.py
index 286a917..b022190 100644
--- a/src/llvm-project/llvm/utils/lit/tests/selecting.py
+++ b/src/llvm-project/llvm/utils/lit/tests/selecting.py
@@ -9,9 +9,12 @@
# CHECK-BAD-PATH: error: did not discover any tests for provided path(s)
# Check that we exit with an error if we filter out all tests, but allow it with --allow-empty-runs.
+# Check that we exit with an error if we skip all tests, but allow it with --allow-empty-runs.
#
# RUN: not %{lit} --filter 'nonexistent' %{inputs}/discovery 2>&1 | FileCheck --check-prefixes=CHECK-BAD-FILTER,CHECK-BAD-FILTER-ERROR %s
# RUN: %{lit} --filter 'nonexistent' --allow-empty-runs %{inputs}/discovery 2>&1 | FileCheck --check-prefixes=CHECK-BAD-FILTER,CHECK-BAD-FILTER-ALLOW %s
+# RUN: not %{lit} --filter-out '.*' %{inputs}/discovery 2>&1 | FileCheck --check-prefixes=CHECK-BAD-FILTER,CHECK-BAD-FILTER-ERROR %s
+# RUN: %{lit} --filter-out '.*' --allow-empty-runs %{inputs}/discovery 2>&1 | FileCheck --check-prefixes=CHECK-BAD-FILTER,CHECK-BAD-FILTER-ALLOW %s
# CHECK-BAD-FILTER: error: filter did not match any tests (of 5 discovered).
# CHECK-BAD-FILTER-ERROR: Use '--allow-empty-runs' to suppress this error.
# CHECK-BAD-FILTER-ALLOW: Suppressing error because '--allow-empty-runs' was specified.
@@ -21,6 +24,9 @@
# RUN: %{lit} --filter 'o[a-z]e' %{inputs}/discovery | FileCheck --check-prefix=CHECK-FILTER %s
# RUN: %{lit} --filter 'O[A-Z]E' %{inputs}/discovery | FileCheck --check-prefix=CHECK-FILTER %s
# RUN: env LIT_FILTER='o[a-z]e' %{lit} %{inputs}/discovery | FileCheck --check-prefix=CHECK-FILTER %s
+# RUN: %{lit} --filter-out 'test-t[a-z]' %{inputs}/discovery | FileCheck --check-prefix=CHECK-FILTER %s
+# RUN: %{lit} --filter-out 'test-t[A-Z]' %{inputs}/discovery | FileCheck --check-prefix=CHECK-FILTER %s
+# RUN: env LIT_FILTER_OUT='test-t[a-z]' %{lit} %{inputs}/discovery | FileCheck --check-prefix=CHECK-FILTER %s
# CHECK-FILTER: Testing: 2 of 5 tests
# CHECK-FILTER: Excluded: 3
diff --git a/src/llvm-project/llvm/utils/lit/tests/show-used-features.py b/src/llvm-project/llvm/utils/lit/tests/show-used-features.py
index 069ee08..b88c68f 100644
--- a/src/llvm-project/llvm/utils/lit/tests/show-used-features.py
+++ b/src/llvm-project/llvm/utils/lit/tests/show-used-features.py
@@ -4,3 +4,6 @@
# CHECK: my-require-feature-1 my-require-feature-2 my-require-feature-3
# CHECK: my-unsupported-feature-1 my-unsupported-feature-2 my-unsupported-feature-3
# CHECK: my-xfail-feature-1 my-xfail-feature-2 my-xfail-feature-3
+# CHECK: {{my-[{][{]\[require\]\*[}][}]-feature-4}}
+# CHECK: {{my-[{][{]\[unsupported\]\*[}][}]-feature-4}}
+# CHECK: {{my-[{][{]\[xfail\]\*[}][}]-feature-4}}
diff --git a/src/llvm-project/llvm/utils/lit/tests/shtest-env.py b/src/llvm-project/llvm/utils/lit/tests/shtest-env.py
index a4ddc0c..ead217a 100644
--- a/src/llvm-project/llvm/utils/lit/tests/shtest-env.py
+++ b/src/llvm-project/llvm/utils/lit/tests/shtest-env.py
@@ -1,5 +1,8 @@
# Check the env command
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/shtest-env/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -a -v %{inputs}/shtest-env \
# RUN: | FileCheck -match-full-lines %s
#
diff --git a/src/llvm-project/llvm/utils/lit/tests/shtest-format.py b/src/llvm-project/llvm/utils/lit/tests/shtest-format.py
index 5c48397..a15c0f9 100644
--- a/src/llvm-project/llvm/utils/lit/tests/shtest-format.py
+++ b/src/llvm-project/llvm/utils/lit/tests/shtest-format.py
@@ -1,5 +1,8 @@
# Check the various features of the ShTest format.
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/shtest-format/.lit_test_times.txt
+
# RUN: rm -f %t.xml
# RUN: not %{lit} -j 1 -v %{inputs}/shtest-format --xunit-xml-output %t.xml > %t.out
# RUN: FileCheck < %t.out %s
diff --git a/src/llvm-project/llvm/utils/lit/tests/shtest-keyword-parse-errors.py b/src/llvm-project/llvm/utils/lit/tests/shtest-keyword-parse-errors.py
index fb652bd5..78cbf81 100644
--- a/src/llvm-project/llvm/utils/lit/tests/shtest-keyword-parse-errors.py
+++ b/src/llvm-project/llvm/utils/lit/tests/shtest-keyword-parse-errors.py
@@ -1,3 +1,6 @@
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/shtest-keyword-parse-errors/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -vv %{inputs}/shtest-keyword-parse-errors > %t.out
# RUN: FileCheck -input-file %t.out %s
#
diff --git a/src/llvm-project/llvm/utils/lit/tests/shtest-not.py b/src/llvm-project/llvm/utils/lit/tests/shtest-not.py
index d361ae8..2b8a69a 100644
--- a/src/llvm-project/llvm/utils/lit/tests/shtest-not.py
+++ b/src/llvm-project/llvm/utils/lit/tests/shtest-not.py
@@ -1,5 +1,8 @@
# Check the not command
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/shtest-not/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -a -v %{inputs}/shtest-not \
# RUN: | FileCheck -match-full-lines %s
#
@@ -7,7 +10,27 @@
# Make sure not and env commands are included in printed commands.
-# CHECK: -- Testing: 13 tests{{.*}}
+# CHECK: -- Testing: 17 tests{{.*}}
+
+# CHECK: FAIL: shtest-not :: exclamation-args-nested-none.txt {{.*}}
+# CHECK: $ "!" "!" "!"
+# CHECK: Error: '!' requires a subcommand
+# CHECK: error: command failed with exit status: {{.*}}
+
+# CHECK: FAIL: shtest-not :: exclamation-args-none.txt {{.*}}
+# CHECK: $ "!"
+# CHECK: Error: '!' requires a subcommand
+# CHECK: error: command failed with exit status: {{.*}}
+
+# CHECK: FAIL: shtest-not :: exclamation-calls-external.txt {{.*}}
+
+# CHECK: $ "!" "{{[^"]*}}" "fail.py"
+# CHECK: $ "!" "!" "{{[^"]*}}" "pass.py"
+# CHECK: $ "!" "!" "!" "{{[^"]*}}" "fail.py"
+# CHECK: $ "!" "!" "!" "!" "{{[^"]*}}" "pass.py"
+
+# CHECK: $ "!" "{{[^"]*}}" "pass.py"
+# CHECK: error: command failed with exit status: {{.*}}
# CHECK: FAIL: shtest-not :: not-args-last-is-crash.txt {{.*}}
# CHECK: $ "not" "--crash"
@@ -98,6 +121,13 @@
# CHECK: $ "not" "not" "--crash" "env" "-u" "BAR" "not" "env" "-u" "FOO" "BAR=1" "{{[^"]*}}" "pass.py"
+# CHECK: FAIL: shtest-not :: not-calls-fail2.txt {{.*}}
+# CHECK-NEXT: {{.*}} TEST 'shtest-not :: not-calls-fail2.txt' FAILED {{.*}}
+# CHECK-NEXT: Script:
+# CHECK-NEXT: --
+# CHECK: --
+# CHECK-NEXT: Exit Code: 1
+
# CHECK: FAIL: shtest-not :: not-calls-mkdir.txt {{.*}}
# CHECK: $ "not" "mkdir" {{.*}}
# CHECK: $ "not" "--crash" "mkdir" "foobar"
@@ -111,5 +141,5 @@
# CHECK: error: command failed with exit status: {{.*}}
# CHECK: Passed: 1
-# CHECK: Failed: 12
+# CHECK: Failed: 16
# CHECK-NOT: {{.}}
diff --git a/src/llvm-project/llvm/utils/lit/tests/shtest-run-at-line.py b/src/llvm-project/llvm/utils/lit/tests/shtest-run-at-line.py
index cd0e081..bf47e64 100644
--- a/src/llvm-project/llvm/utils/lit/tests/shtest-run-at-line.py
+++ b/src/llvm-project/llvm/utils/lit/tests/shtest-run-at-line.py
@@ -1,6 +1,9 @@
# Check that -vv makes the line number of the failing RUN command clear.
# (-v is actually sufficient in the case of the internal shell.)
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/shtest-run-at-line/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -vv %{inputs}/shtest-run-at-line > %t.out
# RUN: FileCheck --input-file %t.out %s
#
diff --git a/src/llvm-project/llvm/utils/lit/tests/shtest-shell.py b/src/llvm-project/llvm/utils/lit/tests/shtest-shell.py
index 4c247de..13cf05f 100644
--- a/src/llvm-project/llvm/utils/lit/tests/shtest-shell.py
+++ b/src/llvm-project/llvm/utils/lit/tests/shtest-shell.py
@@ -1,5 +1,8 @@
# Check the internal shell handling component of the ShTest format.
-#
+
+# FIXME: this test depends on order of tests
+# RUN: rm -f %{inputs}/shtest-shell/.lit_test_times.txt
+
# RUN: not %{lit} -j 1 -v %{inputs}/shtest-shell > %t.out
# FIXME: Temporarily dump test output so we can debug failing tests on
# buildbots.
@@ -8,6 +11,8 @@
#
# Test again in non-UTF shell to catch potential errors with python 2 seen
# on stdout-encoding.txt
+# FIXME: lit's testing sets source_root == exec_root which complicates running lit more than once per test.
+# RUN: rm -f %{inputs}/shtest-shell/.lit_test_times.txt
# RUN: env PYTHONIOENCODING=ascii not %{lit} -j 1 -a %{inputs}/shtest-shell > %t.ascii.out
# FIXME: Temporarily dump test output so we can debug failing tests on
# buildbots.
@@ -288,7 +293,7 @@
# CHECK: FAIL: shtest-shell :: diff-r-error-0.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-0.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: Only in {{.*}}dir1: dir1unique
# CHECK: Only in {{.*}}dir2: dir2unique
@@ -296,7 +301,7 @@
# CHECK: FAIL: shtest-shell :: diff-r-error-1.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-1.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: *** {{.*}}dir1{{.*}}subdir{{.*}}f01
# CHECK: --- {{.*}}dir2{{.*}}subdir{{.*}}f01
@@ -306,35 +311,35 @@
# CHECK: FAIL: shtest-shell :: diff-r-error-2.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-2.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: Only in {{.*}}dir2: extrafile
# CHECK: error: command failed with exit status: 1
# CHECK: FAIL: shtest-shell :: diff-r-error-3.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-3.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: Only in {{.*}}dir1: extra_subdir
# CHECK: error: command failed with exit status: 1
# CHECK: FAIL: shtest-shell :: diff-r-error-4.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-4.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: File {{.*}}dir1{{.*}}extra_subdir is a directory while file {{.*}}dir2{{.*}}extra_subdir is a regular file
# CHECK: error: command failed with exit status: 1
# CHECK: FAIL: shtest-shell :: diff-r-error-5.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-5.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: Only in {{.*}}dir1: extra_subdir
# CHECK: error: command failed with exit status: 1
# CHECK: FAIL: shtest-shell :: diff-r-error-6.txt
# CHECK: *** TEST 'shtest-shell :: diff-r-error-6.txt' FAILED ***
-# CHECK: $ "diff" "-r"
+# CHECK: $ "diff" "-r"
# CHECK: # command output:
# CHECK: File {{.*}}dir1{{.*}}extra_file is a regular empty file while file {{.*}}dir2{{.*}}extra_file is a directory
# CHECK: error: command failed with exit status: 1
diff --git a/src/llvm-project/llvm/utils/lit/tests/use-llvm-tool.py b/src/llvm-project/llvm/utils/lit/tests/use-llvm-tool.py
new file mode 100644
index 0000000..3e190a3
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/use-llvm-tool.py
@@ -0,0 +1,40 @@
+## Show that lit reports the path of tools found via use_llvm_tool.
+## Additionally show that use_llvm_tool uses in order of preference:
+## 1) The path specified in an environment variable,
+## 2) The LLVM tools build directory,
+## 3) The PATH, if requested.
+
+# RUN: %{lit} %{inputs}/use-llvm-tool 2>&1 | \
+# RUN: FileCheck %s -DDIR=%p
+
+## The exact breakdown of cases is:
+## Case | Env | Build Dir | PATH |
+## 1 | / | X | N/S | <- Can be found via env
+## 2 | X | / | N/S | <- Can be found via build dir if env specified
+## 3 | N/S | / | N/S | <- Can be found via build dir
+## 4 | N/S | X | / | <- Can be found via PATH, if requested
+## 5 | N/S | X | N/S | <- Cannot be found via PATH, if not requested
+## 6 | / | / | / | <- Env is preferred over build, PATH
+## 7 | N/S | / | / | <- Build dir is preferred over PATH
+## 8 | X | X | X | <- Say nothing if cannot be found if not required
+## 9 | N/S | override | N/S | <- Use specified search directory, instead of default directory
+## 10 | N/S | override | / | <- Use PATH if not in search directory
+
+## Check the exact path reported for the first case, but don't bother for the
+## others.
+# CHECK: note: using case1: [[DIR]]{{[\\/]}}Inputs{{[\\/]}}use-llvm-tool{{[\\/]}}env-case1
+# CHECK-NEXT: note: using case2: {{.*}}build{{[\\/]}}case2
+# CHECK-NEXT: note: using case3: {{.*}}build{{[\\/]}}case3
+# CHECK-NEXT: note: using case4: {{.*}}path{{[\\/]}}case4
+# CHECK-NOT: case5
+# CHECK-NEXT: note: using case6: {{.*}}env-case6
+# CHECK-NEXT: note: using case7: {{.*}}build{{[\\/]}}case7
+# CHECK-NOT: case8
+# CHECK-NEXT: note: using case9: {{.*}}search2{{[\\/]}}case9
+# CHECK-NEXT: note: using case10: {{.*}}path{{[\\/]}}case10
+
+## Test that if required is True, lit errors if the tool is not found.
+# RUN: not %{lit} %{inputs}/use-llvm-tool-required 2>&1 | \
+# RUN: FileCheck %s --check-prefix=ERROR
+# ERROR: note: using found: {{.*}}found
+# ERROR-NEXT: fatal: couldn't find 'not-found' program
diff --git a/src/llvm-project/llvm/utils/lit/tests/xfail-cl.py b/src/llvm-project/llvm/utils/lit/tests/xfail-cl.py
new file mode 100644
index 0000000..ef1bb04
--- /dev/null
+++ b/src/llvm-project/llvm/utils/lit/tests/xfail-cl.py
@@ -0,0 +1,39 @@
+# Check that XFAILing works via command line or env var.
+
+# RUN: %{lit} --xfail 'false.txt;false2.txt;top-level-suite :: b :: test.txt' \
+# RUN: --xfail-not 'true-xfail.txt;top-level-suite :: a :: test-xfail.txt' \
+# RUN: %{inputs}/xfail-cl \
+# RUN: | FileCheck --check-prefix=CHECK-FILTER %s
+
+# RUN: env LIT_XFAIL='false.txt;false2.txt;top-level-suite :: b :: test.txt' \
+# RUN: LIT_XFAIL_NOT='true-xfail.txt;top-level-suite :: a :: test-xfail.txt' \
+# RUN: %{lit} %{inputs}/xfail-cl \
+# RUN: | FileCheck --check-prefix=CHECK-FILTER %s
+
+# Check that --xfail-not and LIT_XFAIL_NOT always have precedence.
+
+# RUN: env LIT_XFAIL=true-xfail.txt \
+# RUN: %{lit} --xfail true-xfail.txt --xfail-not true-xfail.txt \
+# RUN: --xfail true-xfail.txt %{inputs}/xfail-cl/true-xfail.txt \
+# RUN: | FileCheck --check-prefix=CHECK-OVERRIDE %s
+
+# RUN: env LIT_XFAIL_NOT=true-xfail.txt LIT_XFAIL=true-xfail.txt \
+# RUN: %{lit} --xfail true-xfail.txt %{inputs}/xfail-cl/true-xfail.txt \
+# RUN: | FileCheck --check-prefix=CHECK-OVERRIDE %s
+
+# END.
+
+# CHECK-FILTER: Testing: 10 tests, {{[0-9]*}} workers
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: a :: test.txt
+# CHECK-FILTER-DAG: {{^}}XFAIL: top-level-suite :: b :: test.txt
+# CHECK-FILTER-DAG: {{^}}XFAIL: top-level-suite :: a :: false.txt
+# CHECK-FILTER-DAG: {{^}}XFAIL: top-level-suite :: b :: false.txt
+# CHECK-FILTER-DAG: {{^}}XFAIL: top-level-suite :: false.txt
+# CHECK-FILTER-DAG: {{^}}XFAIL: top-level-suite :: false2.txt
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: true.txt
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: true-xfail.txt
+# CHECK-FILTER-DAG: {{^}}PASS: top-level-suite :: a :: test-xfail.txt
+# CHECK-FILTER-DAG: {{^}}XFAIL: top-level-suite :: b :: test-xfail.txt
+
+# CHECK-OVERRIDE: Testing: 1 tests, {{[0-9]*}} workers
+# CHECK-OVERRIDE: {{^}}PASS: top-level-suite :: true-xfail.txt
diff --git a/src/llvm-project/llvm/utils/lldbDataFormatters.py b/src/llvm-project/llvm/utils/lldbDataFormatters.py
index b5daa09..4fc420f 100644
--- a/src/llvm-project/llvm/utils/lldbDataFormatters.py
+++ b/src/llvm-project/llvm/utils/lldbDataFormatters.py
@@ -4,6 +4,8 @@
Load into LLDB with 'command script import /path/to/lldbDataFormatters.py'
"""
+import lldb
+
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand('type category define -e llvm -l c++')
debugger.HandleCommand('type synthetic add -w llvm '
@@ -15,6 +17,9 @@
debugger.HandleCommand('type synthetic add -w llvm '
'-l lldbDataFormatters.ArrayRefSynthProvider '
'-x "^llvm::ArrayRef<.+>$"')
+ debugger.HandleCommand('type synthetic add -w llvm '
+ '-l lldbDataFormatters.OptionalSynthProvider '
+ '-x "^llvm::Optional<.+>$"')
debugger.HandleCommand('type summary add -w llvm '
'-F lldbDataFormatters.OptionalSummaryProvider '
'-x "^llvm::Optional<.+>$"')
@@ -30,7 +35,7 @@
# Pretty printer for llvm::SmallVector/llvm::SmallVectorImpl
class SmallVectorSynthProvider:
- def __init__(self, valobj, dict):
+ def __init__(self, valobj, internal_dict):
self.valobj = valobj;
self.update() # initialize this provider
@@ -69,7 +74,7 @@
class ArrayRefSynthProvider:
""" Provider for llvm::ArrayRef """
- def __init__(self, valobj, dict):
+ def __init__(self, valobj, internal_dict):
self.valobj = valobj;
self.update() # initialize this provider
@@ -97,7 +102,7 @@
self.type_size = self.data_type.GetByteSize()
assert self.type_size != 0
-def OptionalSummaryProvider(valobj, internal_dict):
+def GetOptionalValue(valobj):
storage = valobj.GetChildMemberWithName('Storage')
if not storage:
storage = valobj
@@ -108,11 +113,33 @@
return '<could not read llvm::Optional>'
if hasVal == 0:
- return 'None'
+ return None
underlying_type = storage.GetType().GetTemplateArgumentType(0)
storage = storage.GetChildMemberWithName('value')
- return str(storage.Cast(underlying_type))
+ return storage.Cast(underlying_type)
+
+def OptionalSummaryProvider(valobj, internal_dict):
+ val = GetOptionalValue(valobj)
+ return val.summary if val else 'None'
+
+class OptionalSynthProvider:
+ """Provides deref support to llvm::Optional<T>"""
+ def __init__(self, valobj, internal_dict):
+ self.valobj = valobj
+
+ def num_children(self):
+ return self.valobj.num_children
+
+ def get_child_index(self, name):
+ if name == '$$dereference$$':
+ return self.valobj.num_children
+ return self.valobj.GetIndexOfChildWithName(name)
+
+ def get_child_at_index(self, index):
+ if index < self.valobj.num_children:
+ return self.valobj.GetChildAtIndex(index)
+ return GetOptionalValue(self.valobj) or lldb.SBValue()
def SmallStringSummaryProvider(valobj, internal_dict):
num_elements = valobj.GetNumChildren()
diff --git a/src/llvm-project/llvm/utils/llvm-compilers-check b/src/llvm-project/llvm/utils/llvm-compilers-check
index 33331fd..3b13245 100755
--- a/src/llvm-project/llvm/utils/llvm-compilers-check
+++ b/src/llvm-project/llvm/utils/llvm-compilers-check
@@ -1,4 +1,4 @@
-#!/usr/bin/python3
+#!/usr/bin/env python3
##===- utils/llvmbuild - Build the LLVM project ----------------*-python-*-===##
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
diff --git a/src/llvm-project/llvm/utils/llvm-native-gxx b/src/llvm-project/llvm/utils/llvm-native-gxx
index db547f6..3c8a703 100755
--- a/src/llvm-project/llvm/utils/llvm-native-gxx
+++ b/src/llvm-project/llvm/utils/llvm-native-gxx
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
# Wrapper around LLVM tools to generate a native .o from llvm-gxx using an
# LLVM back-end (CBE by default).
diff --git a/src/llvm-project/llvm/utils/llvm-original-di-preservation.py b/src/llvm-project/llvm/utils/llvm-original-di-preservation.py
new file mode 100755
index 0000000..0744c3b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/llvm-original-di-preservation.py
@@ -0,0 +1,452 @@
+#!/usr/bin/env python
+#
+# Debugify summary for the original debug info testing.
+#
+
+from __future__ import print_function
+import argparse
+import os
+import sys
+from json import loads
+from collections import defaultdict
+from collections import OrderedDict
+
+class DILocBug:
+ def __init__(self, action, bb_name, fn_name, instr):
+ self.action = action
+ self.bb_name = bb_name
+ self.fn_name = fn_name
+ self.instr = instr
+
+class DISPBug:
+ def __init__(self, action, fn_name):
+ self.action = action
+ self.fn_name = fn_name
+
+class DIVarBug:
+ def __init__(self, action, name, fn_name):
+ self.action = action
+ self.name = name
+ self.fn_name = fn_name
+
+# Report the bugs in form of html.
+def generate_html_report(di_location_bugs, di_subprogram_bugs, di_var_bugs, \
+ di_location_bugs_summary, di_sp_bugs_summary, \
+ di_var_bugs_summary, html_file):
+ fileout = open(html_file, "w")
+
+ html_header = """ <html>
+ <head>
+ <style>
+ table, th, td {
+ border: 1px solid black;
+ }
+ table.center {
+ margin-left: auto;
+ margin-right: auto;
+ }
+ </style>
+ </head>
+ <body>
+ """
+
+ # Create the table for Location bugs.
+ table_title_di_loc = "Location Bugs found by the Debugify"
+
+ table_di_loc = """<table>
+ <caption><b>{}</b></caption>
+ <tr>
+ """.format(table_title_di_loc)
+
+ header_di_loc = ["File", "LLVM Pass Name", "LLVM IR Instruction", \
+ "Function Name", "Basic Block Name", "Action"]
+
+ for column in header_di_loc:
+ table_di_loc += " <th>{0}</th>\n".format(column.strip())
+ table_di_loc += " </tr>\n"
+
+ at_least_one_bug_found = False
+
+ # Handle loction bugs.
+ for file, per_file_bugs in di_location_bugs.items():
+ for llvm_pass, per_pass_bugs in per_file_bugs.items():
+ # No location bugs for the pass.
+ if len(per_pass_bugs) == 0:
+ continue
+ at_least_one_bug_found = True
+ row = []
+ table_di_loc += " </tr>\n"
+ # Get the bugs info.
+ for x in per_pass_bugs:
+ row.append(" <tr>\n")
+ row.append(file)
+ row.append(llvm_pass)
+ row.append(x.instr)
+ row.append(x.fn_name)
+ row.append(x.bb_name)
+ row.append(x.action)
+ row.append(" </tr>\n")
+ # Dump the bugs info into the table.
+ for column in row:
+ # The same file-pass pair can have multiple bugs.
+ if (column == " <tr>\n" or column == " </tr>\n"):
+ table_di_loc += column
+ continue
+ table_di_loc += " <td>{0}</td>\n".format(column.strip())
+ table_di_loc += " <tr>\n"
+
+ if not at_least_one_bug_found:
+ table_di_loc += """ <tr>
+ <td colspan='7'> No bugs found </td>
+ </tr>
+ """
+ table_di_loc += "</table>\n"
+
+ # Create the summary table for the loc bugs.
+ table_title_di_loc_sum = "Summary of Location Bugs"
+ table_di_loc_sum = """<table>
+ <caption><b>{}</b></caption>
+ <tr>
+ """.format(table_title_di_loc_sum)
+
+ header_di_loc_sum = ["LLVM Pass Name", "Number of bugs"]
+
+ for column in header_di_loc_sum:
+ table_di_loc_sum += " <th>{0}</th>\n".format(column.strip())
+ table_di_loc_sum += " </tr>\n"
+
+ # Print the summary.
+ row = []
+ for llvm_pass, num in sorted(di_location_bugs_summary.items()):
+ row.append(" <tr>\n")
+ row.append(llvm_pass)
+ row.append(str(num))
+ row.append(" </tr>\n")
+ for column in row:
+ if (column == " <tr>\n" or column == " </tr>\n"):
+ table_di_loc_sum += column
+ continue
+ table_di_loc_sum += " <td>{0}</td>\n".format(column.strip())
+ table_di_loc_sum += " <tr>\n"
+
+ if not at_least_one_bug_found:
+ table_di_loc_sum += """<tr>
+ <td colspan='2'> No bugs found </td>
+ </tr>
+ """
+ table_di_loc_sum += "</table>\n"
+
+ # Create the table for SP bugs.
+ table_title_di_sp = "SP Bugs found by the Debugify"
+ table_di_sp = """<table>
+ <caption><b>{}</b></caption>
+ <tr>
+ """.format(table_title_di_sp)
+
+ header_di_sp = ["File", "LLVM Pass Name", "Function Name", "Action"]
+
+ for column in header_di_sp:
+ table_di_sp += " <th>{0}</th>\n".format(column.strip())
+ table_di_sp += " </tr>\n"
+
+ at_least_one_bug_found = False
+
+ # Handle fn bugs.
+ for file, per_file_bugs in di_subprogram_bugs.items():
+ for llvm_pass, per_pass_bugs in per_file_bugs.items():
+ # No SP bugs for the pass.
+ if len(per_pass_bugs) == 0:
+ continue
+ at_least_one_bug_found = True
+ row = []
+ table_di_sp += " </tr>\n"
+ # Get the bugs info.
+ for x in per_pass_bugs:
+ row.append(" <tr>\n")
+ row.append(file)
+ row.append(llvm_pass)
+ row.append(x.fn_name)
+ row.append(x.action)
+ row.append(" </tr>\n")
+ # Dump the bugs info into the table.
+ for column in row:
+ # The same file-pass pair can have multiple bugs.
+ if (column == " <tr>\n" or column == " </tr>\n"):
+ table_di_sp += column
+ continue
+ table_di_sp += " <td>{0}</td>\n".format(column.strip())
+ table_di_sp += " <tr>\n"
+
+ if not at_least_one_bug_found:
+ table_di_sp += """<tr>
+ <td colspan='4'> No bugs found </td>
+ </tr>
+ """
+ table_di_sp += "</table>\n"
+
+ # Create the summary table for the sp bugs.
+ table_title_di_sp_sum = "Summary of SP Bugs"
+ table_di_sp_sum = """<table>
+ <caption><b>{}</b></caption>
+ <tr>
+ """.format(table_title_di_sp_sum)
+
+ header_di_sp_sum = ["LLVM Pass Name", "Number of bugs"]
+
+ for column in header_di_sp_sum:
+ table_di_sp_sum += " <th>{0}</th>\n".format(column.strip())
+ table_di_sp_sum += " </tr>\n"
+
+ # Print the summary.
+ row = []
+ for llvm_pass, num in sorted(di_sp_bugs_summary.items()):
+ row.append(" <tr>\n")
+ row.append(llvm_pass)
+ row.append(str(num))
+ row.append(" </tr>\n")
+ for column in row:
+ if (column == " <tr>\n" or column == " </tr>\n"):
+ table_di_sp_sum += column
+ continue
+ table_di_sp_sum += " <td>{0}</td>\n".format(column.strip())
+ table_di_sp_sum += " <tr>\n"
+
+ if not at_least_one_bug_found:
+ table_di_sp_sum += """<tr>
+ <td colspan='2'> No bugs found </td>
+ </tr>
+ """
+ table_di_sp_sum += "</table>\n"
+
+ # Create the table for Variable bugs.
+ table_title_di_var = "Variable Location Bugs found by the Debugify"
+ table_di_var = """<table>
+ <caption><b>{}</b></caption>
+ <tr>
+ """.format(table_title_di_var)
+
+ header_di_var = ["File", "LLVM Pass Name", "Variable", "Function", "Action"]
+
+ for column in header_di_var:
+ table_di_var += " <th>{0}</th>\n".format(column.strip())
+ table_di_var += " </tr>\n"
+
+ at_least_one_bug_found = False
+
+ # Handle var bugs.
+ for file, per_file_bugs in di_var_bugs.items():
+ for llvm_pass, per_pass_bugs in per_file_bugs.items():
+ # No SP bugs for the pass.
+ if len(per_pass_bugs) == 0:
+ continue
+ at_least_one_bug_found = True
+ row = []
+ table_di_var += " </tr>\n"
+ # Get the bugs info.
+ for x in per_pass_bugs:
+ row.append(" <tr>\n")
+ row.append(file)
+ row.append(llvm_pass)
+ row.append(x.name)
+ row.append(x.fn_name)
+ row.append(x.action)
+ row.append(" </tr>\n")
+ # Dump the bugs info into the table.
+ for column in row:
+ # The same file-pass pair can have multiple bugs.
+ if (column == " <tr>\n" or column == " </tr>\n"):
+ table_di_var += column
+ continue
+ table_di_var += " <td>{0}</td>\n".format(column.strip())
+ table_di_var += " <tr>\n"
+
+ if not at_least_one_bug_found:
+ table_di_var += """<tr>
+ <td colspan='4'> No bugs found </td>
+ </tr>
+ """
+ table_di_var += "</table>\n"
+
+ # Create the summary table for the sp bugs.
+ table_title_di_var_sum = "Summary of Variable Location Bugs"
+ table_di_var_sum = """<table>
+ <caption><b>{}</b></caption>
+ <tr>
+ """.format(table_title_di_var_sum)
+
+ header_di_var_sum = ["LLVM Pass Name", "Number of bugs"]
+
+ for column in header_di_var_sum:
+ table_di_var_sum += " <th>{0}</th>\n".format(column.strip())
+ table_di_var_sum += " </tr>\n"
+
+ # Print the summary.
+ row = []
+ for llvm_pass, num in sorted(di_var_bugs_summary.items()):
+ row.append(" <tr>\n")
+ row.append(llvm_pass)
+ row.append(str(num))
+ row.append(" </tr>\n")
+ for column in row:
+ if (column == " <tr>\n" or column == " </tr>\n"):
+ table_di_var_sum += column
+ continue
+ table_di_var_sum += " <td>{0}</td>\n".format(column.strip())
+ table_di_var_sum += " <tr>\n"
+
+ if not at_least_one_bug_found:
+ table_di_var_sum += """<tr>
+ <td colspan='2'> No bugs found </td>
+ </tr>
+ """
+ table_di_var_sum += "</table>\n"
+
+ # Finish the html page.
+ html_footer = """</body>
+ </html>"""
+
+ new_line = "<br>\n"
+
+ fileout.writelines(html_header)
+ fileout.writelines(table_di_loc)
+ fileout.writelines(new_line)
+ fileout.writelines(table_di_loc_sum)
+ fileout.writelines(new_line)
+ fileout.writelines(new_line)
+ fileout.writelines(table_di_sp)
+ fileout.writelines(new_line)
+ fileout.writelines(table_di_sp_sum)
+ fileout.writelines(new_line)
+ fileout.writelines(new_line)
+ fileout.writelines(table_di_var)
+ fileout.writelines(new_line)
+ fileout.writelines(table_di_var_sum)
+ fileout.writelines(html_footer)
+ fileout.close()
+
+ print("The " + html_file + " generated.")
+
+# Read the JSON file.
+def get_json(file):
+ json_parsed = None
+ di_checker_data = []
+
+ # The file contains json object per line.
+ # An example of the line (formatted json):
+ # {
+ # "file": "simple.c",
+ # "pass": "Deduce function attributes in RPO",
+ # "bugs": [
+ # [
+ # {
+ # "action": "drop",
+ # "metadata": "DISubprogram",
+ # "name": "fn2"
+ # },
+ # {
+ # "action": "drop",
+ # "metadata": "DISubprogram",
+ # "name": "fn1"
+ # }
+ # ]
+ # ]
+ #}
+ with open(file) as json_objects_file:
+ for json_object_line in json_objects_file:
+ try:
+ json_object = loads(json_object_line)
+ except:
+ print ("error: No valid di-checker data found.")
+ sys.exit(1)
+ di_checker_data.append(json_object)
+
+ return di_checker_data
+
+# Parse the program arguments.
+def parse_program_args(parser):
+ parser.add_argument("file_name", type=str, help="json file to process")
+ parser.add_argument("html_file", type=str, help="html file to output data")
+
+ return parser.parse_args()
+
+def Main():
+ parser = argparse.ArgumentParser()
+ opts = parse_program_args(parser)
+
+ if not opts.html_file.endswith('.html'):
+ print ("error: The output file must be '.html'.")
+ sys.exit(1)
+
+ debug_info_bugs = get_json(opts.file_name)
+
+ # Use the defaultdict in order to make multidim dicts.
+ di_location_bugs = defaultdict(lambda: defaultdict(dict))
+ di_subprogram_bugs = defaultdict(lambda: defaultdict(dict))
+ di_variable_bugs = defaultdict(lambda: defaultdict(dict))
+
+ # Use the ordered dict to make a summary.
+ di_location_bugs_summary = OrderedDict()
+ di_sp_bugs_summary = OrderedDict()
+ di_var_bugs_summary = OrderedDict()
+
+ # Map the bugs into the file-pass pairs.
+ for bugs_per_pass in debug_info_bugs:
+ bugs_file = bugs_per_pass["file"]
+ bugs_pass = bugs_per_pass["pass"]
+
+ bugs = bugs_per_pass["bugs"][0]
+
+ di_loc_bugs = []
+ di_sp_bugs = []
+ di_var_bugs = []
+
+ for bug in bugs:
+ bugs_metadata = bug["metadata"]
+ if bugs_metadata == "DILocation":
+ action = bug["action"]
+ bb_name = bug["bb-name"]
+ fn_name = bug["fn-name"]
+ instr = bug["instr"]
+ di_loc_bugs.append(DILocBug(action, bb_name, fn_name, instr))
+
+ # Fill the summary dict.
+ if bugs_pass in di_location_bugs_summary:
+ di_location_bugs_summary[bugs_pass] += 1
+ else:
+ di_location_bugs_summary[bugs_pass] = 1
+ elif bugs_metadata == "DISubprogram":
+ action = bug["action"]
+ name = bug["name"]
+ di_sp_bugs.append(DISPBug(action, name))
+
+ # Fill the summary dict.
+ if bugs_pass in di_sp_bugs_summary:
+ di_sp_bugs_summary[bugs_pass] += 1
+ else:
+ di_sp_bugs_summary[bugs_pass] = 1
+ elif bugs_metadata == "dbg-var-intrinsic":
+ action = bug["action"]
+ fn_name = bug["fn-name"]
+ name = bug["name"]
+ di_var_bugs.append(DIVarBug(action, name, fn_name))
+
+ # Fill the summary dict.
+ if bugs_pass in di_var_bugs_summary:
+ di_var_bugs_summary[bugs_pass] += 1
+ else:
+ di_var_bugs_summary[bugs_pass] = 1
+ else:
+ print ("error: Unsupported metadata.")
+ sys.exit(1)
+
+ di_location_bugs[bugs_file][bugs_pass] = di_loc_bugs
+ di_subprogram_bugs[bugs_file][bugs_pass] = di_sp_bugs
+ di_variable_bugs[bugs_file][bugs_pass] = di_var_bugs
+
+ generate_html_report(di_location_bugs, di_subprogram_bugs, di_variable_bugs, \
+ di_location_bugs_summary, di_sp_bugs_summary, \
+ di_var_bugs_summary, opts.html_file)
+
+if __name__ == "__main__":
+ Main()
+ sys.exit(0)
diff --git a/src/llvm-project/llvm/utils/llvm.grm b/src/llvm-project/llvm/utils/llvm.grm
index 398c04d..be6dec7 100644
--- a/src/llvm-project/llvm/utils/llvm.grm
+++ b/src/llvm-project/llvm/utils/llvm.grm
@@ -67,7 +67,7 @@
| ult | ugt | ule | uge | true | false ;
IntType ::= INTTYPE;
-FPType ::= float | double | "ppc_fp128" | fp128 | "x86_fp80";
+FPType ::= half | bfloat | float | double | "ppc_fp128" | fp128 | "x86_fp80";
LocalName ::= LOCALVAR | STRINGCONSTANT | PCTSTRINGCONSTANT ;
OptLocalName ::= LocalName | _ ;
@@ -176,6 +176,7 @@
| sanitize_thread
| sanitize_memory
| mustprogress
+ | nosanitize_coverage
;
OptFuncAttrs ::= + _ | OptFuncAttrs FuncAttr ;
@@ -192,8 +193,8 @@
GlobalVarAttributes ::= + _ | ^ "," GlobalVarAttribute GlobalVarAttributes ;
GlobalVarAttribute ::= SectionString | align EUINT64VAL ;
-PrimType ::= INTTYPE | float | double | "ppc_fp128" | fp128 | "x86_fp80"
- | - label ;
+PrimType ::= INTTYPE | half | bfloat | float | double | "ppc_fp128" | fp128
+ | "x86_fp80" | "x86_mmx" | "x86_amx" | - label ;
Types
::= opaque
diff --git a/src/llvm-project/llvm/utils/prepare-code-coverage-artifact.py b/src/llvm-project/llvm/utils/prepare-code-coverage-artifact.py
index 5c4af24..6d9674e 100755
--- a/src/llvm-project/llvm/utils/prepare-code-coverage-artifact.py
+++ b/src/llvm-project/llvm/utils/prepare-code-coverage-artifact.py
@@ -35,7 +35,7 @@
return profdata_path
def prepare_html_report(host_llvm_cov, profile, report_dir, binaries,
- restricted_dirs):
+ restricted_dirs, compilation_dir):
print(':: Preparing html report for {0}...'.format(binaries), end='')
sys.stdout.flush()
objects = []
@@ -48,6 +48,8 @@
'-instr-profile', profile, '-o', report_dir,
'-show-line-counts-or-regions', '-Xdemangler', 'c++filt',
'-Xdemangler', '-n'] + restricted_dirs
+ if compilation_dir:
+ invocation += ['-compilation-dir=' + compilation_dir]
subprocess.check_call(invocation)
with open(os.path.join(report_dir, 'summary.txt'), 'wb') as Summary:
subprocess.check_call([host_llvm_cov, 'report'] + objects +
@@ -56,16 +58,16 @@
print('Done!')
def prepare_html_reports(host_llvm_cov, profdata_path, report_dir, binaries,
- unified_report, restricted_dirs):
+ unified_report, restricted_dirs, compilation_dir):
if unified_report:
prepare_html_report(host_llvm_cov, profdata_path, report_dir, binaries,
- restricted_dirs)
+ restricted_dirs, compilation_dir)
else:
for binary in binaries:
binary_report_dir = os.path.join(report_dir,
os.path.basename(binary))
prepare_html_report(host_llvm_cov, profdata_path, binary_report_dir,
- [binary], restricted_dirs)
+ [binary], restricted_dirs, compilation_dir)
if __name__ == '__main__':
parser = argparse.ArgumentParser(description=__doc__)
@@ -90,6 +92,8 @@
default=[],
help='Restrict the reporting to the given source paths'
' (must be specified after all other positional arguments)')
+ parser.add_argument('-C', '--compilation-dir', type=str, default="",
+ help='The compilation directory of the binary')
args = parser.parse_args()
if args.use_existing_profdata and args.only_merge:
@@ -109,4 +113,5 @@
if not args.only_merge:
prepare_html_reports(args.host_llvm_cov, profdata_path, args.report_dir,
- args.binaries, args.unified_report, args.restrict)
+ args.binaries, args.unified_report, args.restrict,
+ args.compilation_dir)
diff --git a/src/llvm-project/llvm/utils/release/build_llvm_package.bat b/src/llvm-project/llvm/utils/release/build_llvm_package.bat
index 4747c70..be20724 100755
--- a/src/llvm-project/llvm/utils/release/build_llvm_package.bat
+++ b/src/llvm-project/llvm/utils/release/build_llvm_package.bat
@@ -27,8 +27,8 @@
for /f "usebackq" %%i in (`PowerShell ^(Get-Date^).ToString^('yyyyMMdd'^)`) do set datestamp=%%i
set revision=%1
-set package_version=12.0.1-%revision:~0,8%
-set clang_format_vs_version=12.0.1.%datestamp%
+set package_version=13.0.0-%revision:~0,8%
+set clang_format_vs_version=13.0.0.%datestamp%
set build_dir=llvm_package_%revision:~0,8%
echo Revision: %revision%
diff --git a/src/llvm-project/llvm/utils/release/test-release.sh b/src/llvm-project/llvm/utils/release/test-release.sh
index 6bb6f42..5f602a4 100755
--- a/src/llvm-project/llvm/utils/release/test-release.sh
+++ b/src/llvm-project/llvm/utils/release/test-release.sh
@@ -38,10 +38,10 @@
do_test_suite="yes"
do_openmp="yes"
do_lld="yes"
-do_lldb="no"
+do_lldb="yes"
do_polly="yes"
do_mlir="yes"
-do_flang="no"
+do_flang="yes"
BuildDir="`pwd`"
ExtraConfigureFlags=""
ExportBranch=""
@@ -75,6 +75,7 @@
echo " -no-lldb Disable check-out & build lldb (default)"
echo " -no-polly Disable check-out & build Polly"
echo " -no-mlir Disable check-out & build MLIR"
+ echo " -no-flang Disable check-out & build Flang"
}
while [ $# -gt 0 ]; do
@@ -173,8 +174,8 @@
-no-mlir )
do_mlir="no"
;;
- -flang )
- do_flang="yes"
+ -no-flang )
+ do_flang="no"
;;
-help | --help | -h | --h | -\? )
usage
@@ -189,6 +190,11 @@
shift
done
+if [ $do_mlir = "no" ] && [ $do_flang = "yes" ]; then
+ echo "error: cannot build Flang without MLIR"
+ exit 1
+fi
+
# Check required arguments.
if [ -z "$Release" ]; then
echo "error: no release number specified"
@@ -502,11 +508,8 @@
# Setup the test-suite. Do this early so we can catch failures before
# we do the full 3 stage build.
if [ $do_test_suite = "yes" ]; then
- venv=virtualenv
- if ! type -P 'virtualenv' > /dev/null 2>&1 ; then
- check_program_exists 'python3'
- venv="python3 -m venv"
- fi
+ check_program_exists 'python3'
+ venv="python3 -m venv"
SandboxDir="$BuildDir/sandbox"
Lit=$SandboxDir/bin/lit
diff --git a/src/llvm-project/llvm/utils/revert_checker.py b/src/llvm-project/llvm/utils/revert_checker.py
new file mode 100755
index 0000000..deb4941
--- /dev/null
+++ b/src/llvm-project/llvm/utils/revert_checker.py
@@ -0,0 +1,264 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+"""Checks for reverts of commits across a given git commit.
+
+To clarify the meaning of 'across' with an example, if we had the following
+commit history (where `a -> b` notes that `b` is a direct child of `a`):
+
+123abc -> 223abc -> 323abc -> 423abc -> 523abc
+
+And where 423abc is a revert of 223abc, this revert is considered to be 'across'
+323abc. More generally, a revert A of a parent commit B is considered to be
+'across' a commit C if C is a parent of A and B is a parent of C.
+
+Please note that revert detection in general is really difficult, since merge
+conflicts/etc always introduce _some_ amount of fuzziness. This script just
+uses a bundle of heuristics, and is bound to ignore / incorrectly flag some
+reverts. The hope is that it'll easily catch the vast majority (>90%) of them,
+though.
+
+This is designed to be used in one of two ways: an import in Python, or run
+directly from a shell. If you want to import this, the `find_reverts`
+function is the thing to look at. If you'd rather use this from a shell, have a
+usage example:
+
+```
+./revert_checker.py c47f97169 origin/main origin/release/12.x
+```
+
+This checks for all reverts from the tip of origin/main to c47f97169, which are
+across the latter. It then does the same for origin/release/12.x to c47f97169.
+Duplicate reverts discovered when walking both roots (origin/main and
+origin/release/12.x) are deduplicated in output.
+"""
+
+import argparse
+import collections
+import logging
+import re
+import subprocess
+import sys
+from typing import Generator, List, NamedTuple, Iterable
+
+assert sys.version_info >= (3, 6), 'Only Python 3.6+ is supported.'
+
+# People are creative with their reverts, and heuristics are a bit difficult.
+# Like 90% of of reverts have "This reverts commit ${full_sha}".
+# Some lack that entirely, while others have many of them specified in ad-hoc
+# ways, while others use short SHAs and whatever.
+#
+# The 90% case is trivial to handle (and 100% free + automatic). The extra 10%
+# starts involving human intervention, which is probably not worth it for now.
+
+
+def _try_parse_reverts_from_commit_message(commit_message: str) -> List[str]:
+ if not commit_message:
+ return []
+
+ results = re.findall(r'This reverts commit ([a-f0-9]{40})\b', commit_message)
+
+ first_line = commit_message.splitlines()[0]
+ initial_revert = re.match(r'Revert ([a-f0-9]{6,}) "', first_line)
+ if initial_revert:
+ results.append(initial_revert.group(1))
+ return results
+
+
+def _stream_stdout(command: List[str]) -> Generator[str, None, None]:
+ with subprocess.Popen(
+ command, stdout=subprocess.PIPE, encoding='utf-8', errors='replace') as p:
+ assert p.stdout is not None # for mypy's happiness.
+ yield from p.stdout
+
+
+def _resolve_sha(git_dir: str, sha: str) -> str:
+ if len(sha) == 40:
+ return sha
+
+ return subprocess.check_output(
+ ['git', '-C', git_dir, 'rev-parse', sha],
+ encoding='utf-8',
+ stderr=subprocess.DEVNULL,
+ ).strip()
+
+
+_LogEntry = NamedTuple('_LogEntry', [
+ ('sha', str),
+ ('commit_message', str),
+])
+
+
+def _log_stream(git_dir: str, root_sha: str,
+ end_at_sha: str) -> Iterable[_LogEntry]:
+ sep = 50 * '<>'
+ log_command = [
+ 'git',
+ '-C',
+ git_dir,
+ 'log',
+ '^' + end_at_sha,
+ root_sha,
+ '--format=' + sep + '%n%H%n%B%n',
+ ]
+
+ stdout_stream = iter(_stream_stdout(log_command))
+
+ # Find the next separator line. If there's nothing to log, it may not exist.
+ # It might not be the first line if git feels complainy.
+ found_commit_header = False
+ for line in stdout_stream:
+ if line.rstrip() == sep:
+ found_commit_header = True
+ break
+
+ while found_commit_header:
+ sha = next(stdout_stream, None)
+ assert sha is not None, 'git died?'
+ sha = sha.rstrip()
+
+ commit_message = []
+
+ found_commit_header = False
+ for line in stdout_stream:
+ line = line.rstrip()
+ if line.rstrip() == sep:
+ found_commit_header = True
+ break
+ commit_message.append(line)
+
+ yield _LogEntry(sha, '\n'.join(commit_message).rstrip())
+
+
+def _shas_between(git_dir: str, base_ref: str, head_ref: str) -> Iterable[str]:
+ rev_list = [
+ 'git',
+ '-C',
+ git_dir,
+ 'rev-list',
+ '--first-parent',
+ f'{base_ref}..{head_ref}',
+ ]
+ return (x.strip() for x in _stream_stdout(rev_list))
+
+
+def _rev_parse(git_dir: str, ref: str) -> str:
+ return subprocess.check_output(
+ ['git', '-C', git_dir, 'rev-parse', ref],
+ encoding='utf-8',
+ ).strip()
+
+
+Revert = NamedTuple('Revert', [
+ ('sha', str),
+ ('reverted_sha', str),
+])
+
+
+def _find_common_parent_commit(git_dir: str, ref_a: str, ref_b: str) -> str:
+ """Finds the closest common parent commit between `ref_a` and `ref_b`."""
+ return subprocess.check_output(
+ ['git', '-C', git_dir, 'merge-base', ref_a, ref_b],
+ encoding='utf-8',
+ ).strip()
+
+
+def find_reverts(git_dir: str, across_ref: str, root: str) -> List[Revert]:
+ """Finds reverts across `across_ref` in `git_dir`, starting from `root`.
+
+ These reverts are returned in order of oldest reverts first.
+ """
+ across_sha = _rev_parse(git_dir, across_ref)
+ root_sha = _rev_parse(git_dir, root)
+
+ common_ancestor = _find_common_parent_commit(git_dir, across_sha, root_sha)
+ if common_ancestor != across_sha:
+ raise ValueError(f"{across_sha} isn't an ancestor of {root_sha} "
+ '(common ancestor: {common_ancestor})')
+
+ intermediate_commits = set(_shas_between(git_dir, across_sha, root_sha))
+ assert across_sha not in intermediate_commits
+
+ logging.debug('%d commits appear between %s and %s',
+ len(intermediate_commits), across_sha, root_sha)
+
+ all_reverts = []
+ for sha, commit_message in _log_stream(git_dir, root_sha, across_sha):
+ reverts = _try_parse_reverts_from_commit_message(commit_message)
+ if not reverts:
+ continue
+
+ resolved_reverts = sorted(set(_resolve_sha(git_dir, x) for x in reverts))
+ for reverted_sha in resolved_reverts:
+ if reverted_sha in intermediate_commits:
+ logging.debug('Commit %s reverts %s, which happened after %s', sha,
+ reverted_sha, across_sha)
+ continue
+
+ try:
+ object_type = subprocess.check_output(
+ ['git', '-C', git_dir, 'cat-file', '-t', reverted_sha],
+ encoding='utf-8',
+ stderr=subprocess.DEVNULL,
+ ).strip()
+ except subprocess.CalledProcessError:
+ logging.warning(
+ 'Failed to resolve reverted object %s (claimed to be reverted '
+ 'by sha %s)', reverted_sha, sha)
+ continue
+
+ if object_type == 'commit':
+ all_reverts.append(Revert(sha, reverted_sha))
+ continue
+
+ logging.error("%s claims to revert %s -- which isn't a commit -- %s", sha,
+ object_type, reverted_sha)
+
+ # Since `all_reverts` contains reverts in log order (e.g., newer comes before
+ # older), we need to reverse this to keep with our guarantee of older =
+ # earlier in the result.
+ all_reverts.reverse()
+ return all_reverts
+
+
+def _main() -> None:
+ parser = argparse.ArgumentParser(
+ description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
+ parser.add_argument(
+ 'base_ref', help='Git ref or sha to check for reverts around.')
+ parser.add_argument(
+ '-C', '--git_dir', default='.', help='Git directory to use.')
+ parser.add_argument(
+ 'root', nargs='+', help='Root(s) to search for commits from.')
+ parser.add_argument('--debug', action='store_true')
+ opts = parser.parse_args()
+
+ logging.basicConfig(
+ format='%(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: %(message)s',
+ level=logging.DEBUG if opts.debug else logging.INFO,
+ )
+
+ # `root`s can have related history, so we want to filter duplicate commits
+ # out. The overwhelmingly common case is also to have one root, and it's way
+ # easier to reason about output that comes in an order that's meaningful to
+ # git.
+ seen_reverts = set()
+ all_reverts = []
+ for root in opts.root:
+ for revert in find_reverts(opts.git_dir, opts.base_ref, root):
+ if revert not in seen_reverts:
+ seen_reverts.add(revert)
+ all_reverts.append(revert)
+
+ for revert in all_reverts:
+ print(f'{revert.sha} claims to revert {revert.reverted_sha}')
+
+
+if __name__ == '__main__':
+ _main()
diff --git a/src/llvm-project/llvm/utils/revert_checker_test.py b/src/llvm-project/llvm/utils/revert_checker_test.py
new file mode 100755
index 0000000..6573c25
--- /dev/null
+++ b/src/llvm-project/llvm/utils/revert_checker_test.py
@@ -0,0 +1,118 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+#===----------------------------------------------------------------------===##
+"""Tests for revert_checker.
+
+Note that these tests require having LLVM's git history available, since our
+repository has a few interesting instances of edge-cases.
+"""
+
+import os
+import logging
+import unittest
+from typing import List
+
+import revert_checker
+
+# pylint: disable=protected-access
+
+
+def get_llvm_project_path() -> str:
+ """Returns the path to llvm-project's root."""
+ my_dir = os.path.dirname(__file__)
+ return os.path.realpath(os.path.join(my_dir, '..', '..'))
+
+
+class _SilencingFilter(logging.Filter):
+ """Silences all log messages.
+
+ Also collects info about log messages that would've been emitted.
+ """
+
+ def __init__(self) -> None:
+ self.messages: List[str] = []
+
+ def filter(self, record: logging.LogRecord) -> bool:
+ self.messages.append(record.getMessage())
+ return False
+
+
+class Test(unittest.TestCase):
+ """Tests for revert_checker."""
+
+ def silence_logging(self) -> _SilencingFilter:
+ root = logging.getLogger()
+ filt = _SilencingFilter()
+ root.addFilter(filt)
+ self.addCleanup(root.removeFilter, filt)
+ return filt
+
+ def test_log_stream_with_known_sha_range(self) -> None:
+ start_sha = 'e241573d5972d34a323fa5c64774c4207340beb3'
+ end_sha = 'a7a37517751ffb0f5529011b4ba96e67fcb27510'
+ commits = [
+ revert_checker._LogEntry(
+ 'e241573d5972d34a323fa5c64774c4207340beb3', '\n'.join((
+ '[mlir] NFC: remove IntegerValueSet / MutableIntegerSet',
+ '',
+ 'Summary:',
+ '- these are unused and really not needed now given flat '
+ 'affine',
+ ' constraints',
+ '',
+ 'Differential Revision: https://reviews.llvm.org/D75792',
+ ))),
+ revert_checker._LogEntry(
+ '97572fa6e9daecd648873496fd11f7d1e25a55f0',
+ '[NFC] use hasAnyOperatorName and hasAnyOverloadedOperatorName '
+ 'functions in clang-tidy matchers',
+ ),
+ ]
+
+ logs = list(
+ revert_checker._log_stream(
+ get_llvm_project_path(),
+ root_sha=start_sha,
+ end_at_sha=end_sha,
+ ))
+ self.assertEqual(commits, logs)
+
+ def test_reverted_noncommit_object_is_a_nop(self) -> None:
+ log_filter = self.silence_logging()
+ # c9944df916e41b1014dff5f6f75d52297b48ecdc mentions reverting a non-commit
+ # object. It sits between the given base_ref and root.
+ reverts = revert_checker.find_reverts(
+ git_dir=get_llvm_project_path(),
+ across_ref='c9944df916e41b1014dff5f6f75d52297b48ecdc~',
+ root='c9944df916e41b1014dff5f6f75d52297b48ecdc')
+ self.assertEqual(reverts, [])
+
+ complaint = ('Failed to resolve reverted object '
+ 'edd18355be574122aaa9abf58c15d8c50fb085a1')
+ self.assertTrue(
+ any(x.startswith(complaint) for x in log_filter.messages),
+ log_filter.messages)
+
+ def test_known_reverts_across_arbitrary_llvm_rev(self) -> None:
+ reverts = revert_checker.find_reverts(
+ git_dir=get_llvm_project_path(),
+ across_ref='c47f971694be0159ffddfee8a75ae515eba91439',
+ root='9f981e9adf9c8d29bb80306daf08d2770263ade6')
+ self.assertEqual(reverts, [
+ revert_checker.Revert(
+ sha='4e0fe038f438ae1679eae9e156e1f248595b2373',
+ reverted_sha='65b21282c710afe9c275778820c6e3c1cf46734b'),
+ revert_checker.Revert(
+ sha='9f981e9adf9c8d29bb80306daf08d2770263ade6',
+ reverted_sha='4060016fce3e6a0b926ee9fc59e440a612d3a2ec'),
+ ])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/llvm-project/llvm/utils/sysroot.py b/src/llvm-project/llvm/utils/sysroot.py
new file mode 100755
index 0000000..48b52ec
--- /dev/null
+++ b/src/llvm-project/llvm/utils/sysroot.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python3
+
+"""Helps manage sysroots."""
+
+import argparse
+import os
+import subprocess
+import sys
+
+
+def make_fake_sysroot(out_dir):
+ def cmdout(cmd):
+ return subprocess.check_output(cmd).decode(sys.stdout.encoding).strip()
+
+ if sys.platform == 'win32':
+ p = os.getenv('ProgramFiles(x86)', 'C:\\Program Files (x86)')
+
+ winsdk = os.getenv('WindowsSdkDir')
+ if not winsdk:
+ winsdk = os.path.join(p, 'Windows Kits', '10')
+ print('%WindowsSdkDir% not set. You might want to run this from')
+ print('a Visual Studio cmd prompt. Defaulting to', winsdk)
+
+ vswhere = os.path.join(
+ p, 'Microsoft Visual Studio', 'Installer', 'vswhere')
+ vcid = 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64'
+ vsinstalldir = cmdout(
+ [vswhere, '-latest', '-products', '*', '-requires', vcid,
+ '-property', 'installationPath'])
+
+ def mkjunction(dst, src):
+ subprocess.check_call(['mklink', '/j', dst, src], shell=True)
+ os.mkdir(out_dir)
+ mkjunction(os.path.join(out_dir, 'VC'),
+ os.path.join(vsinstalldir, 'VC'))
+ os.mkdir(os.path.join(out_dir, 'Windows Kits'))
+ mkjunction(os.path.join(out_dir, 'Windows Kits', '10'), winsdk)
+ elif sys.platform == 'darwin':
+ # The SDKs used by default in compiler-rt/cmake/base-config-ix.cmake.
+ # COMPILER_RT_ENABLE_IOS defaults to on.
+ # COMPILER_RT_ENABLE_WATCHOS and COMPILER_RT_ENABLE_TV default to off.
+ # compiler-rt/cmake/config-ix.cmake sets DARWIN_EMBEDDED_PLATFORMS
+ # depending on these.
+ sdks = ['macosx', 'iphoneos', 'iphonesimulator']
+ os.mkdir(out_dir)
+ for sdk in sdks:
+ sdkpath = cmdout(['xcrun', '-sdk', sdk, '-show-sdk-path'])
+ # sdkpath is something like /.../SDKs/MacOSX11.1.sdk, which is a
+ # symlink to MacOSX.sdk in the same directory. Resolve the symlink,
+ # to make the symlink in out_dir less likely to break when the SDK
+ # is updated (which will bump the number on xcrun's output, but not
+ # on the symlink destination).
+ sdkpath = os.path.realpath(sdkpath)
+ os.symlink(sdkpath, os.path.join(out_dir, os.path.basename(sdkpath)))
+ else:
+ os.symlink('/', out_dir)
+
+ print('Done. Pass these flags to cmake:')
+ abs_out_dir = os.path.abspath(out_dir)
+ if sys.platform == 'win32':
+ # CMake doesn't like backslashes in commandline args.
+ abs_out_dir = abs_out_dir.replace(os.path.sep, '/')
+ print(' -DLLVM_WINSYSROOT=' + abs_out_dir)
+ elif sys.platform == 'darwin':
+ flags = [
+ '-DCMAKE_OSX_SYSROOT=' + os.path.join(abs_out_dir, 'MacOSX.sdk'),
+
+ # For find_darwin_sdk_dir() in
+ # compiler-rt/cmake/Modules/CompilerRTDarwinUtils.cmake
+ '-DDARWIN_macosx_CACHED_SYSROOT=' +
+ os.path.join(abs_out_dir, 'MacOSX.sdk'),
+ '-DDARWIN_iphoneos_CACHED_SYSROOT=' +
+ os.path.join(abs_out_dir, 'iPhoneOS.sdk'),
+ '-DDARWIN_iphonesimulator_CACHED_SYSROOT=' +
+ os.path.join(abs_out_dir, 'iPhoneSimulator.sdk'),
+ ]
+ print(' ' + ' '.join(flags))
+ else:
+ print(' -DCMAKE_SYSROOT=' + abs_out_dir + ' to cmake.')
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+
+ subparsers = parser.add_subparsers(dest='command', required=True)
+
+ makefake = subparsers.add_parser('make-fake',
+ help='Create a sysroot that symlinks to local directories.')
+ makefake.add_argument('--out-dir', required=True)
+
+ args = parser.parse_args()
+
+ assert args.command == 'make-fake'
+ make_fake_sysroot(args.out_dir)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/llvm-project/llvm/utils/unittest/CMakeLists.txt b/src/llvm-project/llvm/utils/unittest/CMakeLists.txt
index 43c8fafd..90037ae 100644
--- a/src/llvm-project/llvm/utils/unittest/CMakeLists.txt
+++ b/src/llvm-project/llvm/utils/unittest/CMakeLists.txt
@@ -61,9 +61,6 @@
set_target_properties(gtest PROPERTIES INTERFACE_COMPILE_OPTIONS "-Wno-suggest-override")
endif()
-# Gtest 1.8.0 uses tr1/tuple which is deprecated on MSVC, so we force it off.
-target_compile_definitions(gtest PUBLIC GTEST_HAS_TR1_TUPLE=0)
-
if (NOT LLVM_ENABLE_THREADS)
target_compile_definitions(gtest PUBLIC GTEST_HAS_PTHREAD=0)
endif ()
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/README.LLVM b/src/llvm-project/llvm/utils/unittest/googlemock/README.LLVM
index 9badc7d..dbeb4af 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/README.LLVM
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/README.LLVM
@@ -1,7 +1,7 @@
LLVM notes
----------
-This directory contains the 'googlemock' component of Google Test 1.8.0, with
+This directory contains the 'googlemock' component of Google Test 1.10.0, with
all elements removed except for the actual source code, to minimize the
addition to the LLVM distribution.
@@ -15,3 +15,8 @@
# Put the license in the consistent place for LLVM.
$ mv LICENSE LICENSE.TXT
+
+Modified as follows:
+* Support for std::begin/std::end in gmock-matchers.h
+* IWYU pragmas
+* Disabled -Wdeprecated-copy for clang
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-actions.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-actions.h
index 3237799..0a997a2 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-actions.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-actions.h
@@ -26,13 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used actions.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
@@ -43,13 +44,25 @@
#endif
#include <algorithm>
+#include <functional>
+#include <memory>
#include <string>
+#include <type_traits>
+#include <utility>
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
-#if GTEST_HAS_STD_TYPE_TRAITS_ // Defined by gtest-port.h via gmock-port.h.
-#include <type_traits>
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4100)
+#endif
+
+#ifdef __clang__
+#if __has_warning("-Wdeprecated-copy")
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-copy"
+#endif
#endif
namespace testing {
@@ -65,9 +78,6 @@
namespace internal {
-template <typename F1, typename F2>
-class ActionAdaptor;
-
// BuiltInDefaultValueGetter<T, true>::Get() returns a
// default-constructed T value. BuiltInDefaultValueGetter<T,
// false>::Get() crashes with an error.
@@ -98,8 +108,8 @@
template <typename T>
class BuiltInDefaultValue {
public:
-#if GTEST_HAS_STD_TYPE_TRAITS_
- // This function returns true iff type T has a built-in default value.
+ // This function returns true if and only if type T has a built-in default
+ // value.
static bool Exists() {
return ::std::is_default_constructible<T>::value;
}
@@ -108,18 +118,6 @@
return BuiltInDefaultValueGetter<
T, ::std::is_default_constructible<T>::value>::Get();
}
-
-#else // GTEST_HAS_STD_TYPE_TRAITS_
- // This function returns true iff type T has a built-in default value.
- static bool Exists() {
- return false;
- }
-
- static T Get() {
- return BuiltInDefaultValueGetter<T, false>::Get();
- }
-
-#endif // GTEST_HAS_STD_TYPE_TRAITS_
};
// This partial specialization says that we use the same built-in
@@ -137,7 +135,7 @@
class BuiltInDefaultValue<T*> {
public:
static bool Exists() { return true; }
- static T* Get() { return NULL; }
+ static T* Get() { return nullptr; }
};
// The following specializations define the default values for
@@ -151,9 +149,6 @@
}
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT
-#if GTEST_HAS_GLOBAL_STRING
-GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, "");
-#endif // GTEST_HAS_GLOBAL_STRING
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, "");
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false);
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0');
@@ -220,11 +215,11 @@
// Unsets the default value for type T.
static void Clear() {
delete producer_;
- producer_ = NULL;
+ producer_ = nullptr;
}
- // Returns true iff the user has set the default value for type T.
- static bool IsSet() { return producer_ != NULL; }
+ // Returns true if and only if the user has set the default value for type T.
+ static bool IsSet() { return producer_ != nullptr; }
// Returns true if T has a default return value set by the user or there
// exists a built-in default value.
@@ -236,8 +231,8 @@
// otherwise returns the built-in default value. Requires that Exists()
// is true, which ensures that the return value is well-defined.
static T Get() {
- return producer_ == NULL ?
- internal::BuiltInDefaultValue<T>::Get() : producer_->Produce();
+ return producer_ == nullptr ? internal::BuiltInDefaultValue<T>::Get()
+ : producer_->Produce();
}
private:
@@ -250,7 +245,7 @@
class FixedValueProducer : public ValueProducer {
public:
explicit FixedValueProducer(T value) : value_(value) {}
- virtual T Produce() { return value_; }
+ T Produce() override { return value_; }
private:
const T value_;
@@ -261,7 +256,7 @@
public:
explicit FactoryValueProducer(FactoryFunction factory)
: factory_(factory) {}
- virtual T Produce() { return factory_(); }
+ T Produce() override { return factory_(); }
private:
const FactoryFunction factory_;
@@ -282,12 +277,10 @@
}
// Unsets the default value for type T&.
- static void Clear() {
- address_ = NULL;
- }
+ static void Clear() { address_ = nullptr; }
- // Returns true iff the user has set the default value for type T&.
- static bool IsSet() { return address_ != NULL; }
+ // Returns true if and only if the user has set the default value for type T&.
+ static bool IsSet() { return address_ != nullptr; }
// Returns true if T has a default return value set by the user or there
// exists a built-in default value.
@@ -299,8 +292,8 @@
// otherwise returns the built-in default value if there is one;
// otherwise aborts the process.
static T& Get() {
- return address_ == NULL ?
- internal::BuiltInDefaultValue<T&>::Get() : *address_;
+ return address_ == nullptr ? internal::BuiltInDefaultValue<T&>::Get()
+ : *address_;
}
private:
@@ -318,11 +311,11 @@
// Points to the user-set default value for type T.
template <typename T>
-typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = NULL;
+typename DefaultValue<T>::ValueProducer* DefaultValue<T>::producer_ = nullptr;
// Points to the user-set default value for type T&.
template <typename T>
-T* DefaultValue<T&>::address_ = NULL;
+T* DefaultValue<T&>::address_ = nullptr;
// Implement this interface to define an action for function type F.
template <typename F>
@@ -347,39 +340,53 @@
// An Action<F> is a copyable and IMMUTABLE (except by assignment)
// object that represents an action to be taken when a mock function
// of type F is called. The implementation of Action<T> is just a
-// linked_ptr to const ActionInterface<T>, so copying is fairly cheap.
-// Don't inherit from Action!
-//
+// std::shared_ptr to const ActionInterface<T>. Don't inherit from Action!
// You can view an object implementing ActionInterface<F> as a
// concrete action (including its current state), and an Action<F>
// object as a handle to it.
template <typename F>
class Action {
+ // Adapter class to allow constructing Action from a legacy ActionInterface.
+ // New code should create Actions from functors instead.
+ struct ActionAdapter {
+ // Adapter must be copyable to satisfy std::function requirements.
+ ::std::shared_ptr<ActionInterface<F>> impl_;
+
+ template <typename... Args>
+ typename internal::Function<F>::Result operator()(Args&&... args) {
+ return impl_->Perform(
+ ::std::forward_as_tuple(::std::forward<Args>(args)...));
+ }
+ };
+
public:
typedef typename internal::Function<F>::Result Result;
typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
// Constructs a null Action. Needed for storing Action objects in
// STL containers.
- Action() : impl_(NULL) {}
+ Action() {}
- // Constructs an Action from its implementation. A NULL impl is
- // used to represent the "do-default" action.
- explicit Action(ActionInterface<F>* impl) : impl_(impl) {}
+ // Construct an Action from a specified callable.
+ // This cannot take std::function directly, because then Action would not be
+ // directly constructible from lambda (it would require two conversions).
+ template <typename G,
+ typename = typename ::std::enable_if<
+ ::std::is_constructible<::std::function<F>, G>::value>::type>
+ Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT
- // Copy constructor.
- Action(const Action &action) = default;
- Action &operator=(const Action &action) = default;
+ // Constructs an Action from its implementation.
+ explicit Action(ActionInterface<F>* impl)
+ : fun_(ActionAdapter{::std::shared_ptr<ActionInterface<F>>(impl)}) {}
// This constructor allows us to turn an Action<Func> object into an
// Action<F>, as long as F's arguments can be implicitly converted
- // to Func's and Func's return type can be implicitly converted to
- // F's.
+ // to Func's and Func's return type can be implicitly converted to F's.
template <typename Func>
- explicit Action(const Action<Func>& action);
+ explicit Action(const Action<Func>& action) : fun_(action.fun_) {}
- // Returns true iff this is the DoDefault() action.
- bool IsDoDefault() const { return impl_.get() == NULL; }
+ // Returns true if and only if this is the DoDefault() action.
+ bool IsDoDefault() const { return fun_ == nullptr; }
// Performs the action. Note that this method is const even though
// the corresponding method in ActionInterface is not. The reason
@@ -387,22 +394,19 @@
// another concrete action, not that the concrete action it binds to
// cannot change state. (Think of the difference between a const
// pointer and a pointer to const.)
- Result Perform(const ArgumentTuple& args) const {
- internal::Assert(
- !IsDoDefault(), __FILE__, __LINE__,
- "You are using DoDefault() inside a composite action like "
- "DoAll() or WithArgs(). This is not supported for technical "
- "reasons. Please instead spell out the default action, or "
- "assign the default action to an Action variable and use "
- "the variable in various places.");
- return impl_->Perform(args);
+ Result Perform(ArgumentTuple args) const {
+ if (IsDoDefault()) {
+ internal::IllegalDoDefault(__FILE__, __LINE__);
+ }
+ return internal::Apply(fun_, ::std::move(args));
}
private:
- template <typename F1, typename F2>
- friend class internal::ActionAdaptor;
+ template <typename G>
+ friend class Action;
- internal::linked_ptr<ActionInterface<F> > impl_;
+ // fun_ is an empty function if and only if this is the DoDefault() action.
+ ::std::function<F> fun_;
};
// The PolymorphicAction class template makes it easy to implement a
@@ -417,7 +421,7 @@
// template <typename Result, typename ArgumentTuple>
// Result Perform(const ArgumentTuple& args) const {
// // Processes the arguments and returns a result, using
-// // tr1::get<N>(args) to get the N-th (0-based) argument in the tuple.
+// // std::get<N>(args) to get the N-th (0-based) argument in the tuple.
// }
// ...
// };
@@ -445,7 +449,7 @@
explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
- virtual Result Perform(const ArgumentTuple& args) {
+ Result Perform(const ArgumentTuple& args) override {
return impl_.template Perform<Result>(args);
}
@@ -481,31 +485,11 @@
namespace internal {
-// Allows an Action<F2> object to pose as an Action<F1>, as long as F2
-// and F1 are compatible.
-template <typename F1, typename F2>
-class ActionAdaptor : public ActionInterface<F1> {
- public:
- typedef typename internal::Function<F1>::Result Result;
- typedef typename internal::Function<F1>::ArgumentTuple ArgumentTuple;
-
- explicit ActionAdaptor(const Action<F2>& from) : impl_(from.impl_) {}
-
- virtual Result Perform(const ArgumentTuple& args) {
- return impl_->Perform(args);
- }
-
- private:
- const internal::linked_ptr<ActionInterface<F2> > impl_;
-
- GTEST_DISALLOW_ASSIGN_(ActionAdaptor);
-};
-
// Helper struct to specialize ReturnAction to execute a move instead of a copy
// on return. Useful for move-only types, but could be used on any type.
template <typename T>
struct ByMoveWrapper {
- explicit ByMoveWrapper(T value) : payload(internal::move(value)) {}
+ explicit ByMoveWrapper(T value) : payload(std::move(value)) {}
T payload;
};
@@ -533,18 +517,21 @@
// statement, and conversion of the result of Return to Action<T(U)> is a
// good place for that.
//
+// The real life example of the above scenario happens when an invocation
+// of gtl::Container() is passed into Return.
+//
template <typename R>
class ReturnAction {
public:
// Constructs a ReturnAction object from the value to be returned.
// 'value' is passed by value instead of by const reference in order
// to allow Return("string literal") to compile.
- explicit ReturnAction(R value) : value_(new R(internal::move(value))) {}
+ explicit ReturnAction(R value) : value_(new R(std::move(value))) {}
// This template type conversion operator allows Return(x) to be
// used in ANY function that returns x's type.
template <typename F>
- operator Action<F>() const {
+ operator Action<F>() const { // NOLINT
// Assert statement belongs here because this is the best place to verify
// conditions on F. It produces the clearest error messages
// in most compilers.
@@ -555,8 +542,10 @@
// in the Impl class. But both definitions must be the same.
typedef typename Function<F>::Result Result;
GTEST_COMPILE_ASSERT_(
- !is_reference<Result>::value,
+ !std::is_reference<Result>::value,
use_ReturnRef_instead_of_Return_to_return_a_reference);
+ static_assert(!std::is_void<Result>::value,
+ "Can't use Return() on an action expected to return `void`.");
return Action<F>(new Impl<R, F>(value_));
}
@@ -575,14 +564,14 @@
// Result to call. ImplicitCast_ forces the compiler to convert R to
// Result without considering explicit constructors, thus resolving the
// ambiguity. value_ is then initialized using its copy constructor.
- explicit Impl(const linked_ptr<R>& value)
+ explicit Impl(const std::shared_ptr<R>& value)
: value_before_cast_(*value),
value_(ImplicitCast_<Result>(value_before_cast_)) {}
- virtual Result Perform(const ArgumentTuple&) { return value_; }
+ Result Perform(const ArgumentTuple&) override { return value_; }
private:
- GTEST_COMPILE_ASSERT_(!is_reference<Result>::value,
+ GTEST_COMPILE_ASSERT_(!std::is_reference<Result>::value,
Result_cannot_be_a_reference_type);
// We save the value before casting just in case it is being cast to a
// wrapper type.
@@ -600,24 +589,24 @@
typedef typename Function<F>::Result Result;
typedef typename Function<F>::ArgumentTuple ArgumentTuple;
- explicit Impl(const linked_ptr<R>& wrapper)
+ explicit Impl(const std::shared_ptr<R>& wrapper)
: performed_(false), wrapper_(wrapper) {}
- virtual Result Perform(const ArgumentTuple&) {
+ Result Perform(const ArgumentTuple&) override {
GTEST_CHECK_(!performed_)
<< "A ByMove() action should only be performed once.";
performed_ = true;
- return internal::move(wrapper_->payload);
+ return std::move(wrapper_->payload);
}
private:
bool performed_;
- const linked_ptr<R> wrapper_;
+ const std::shared_ptr<R> wrapper_;
GTEST_DISALLOW_ASSIGN_(Impl);
};
- const linked_ptr<R> value_;
+ const std::shared_ptr<R> value_;
GTEST_DISALLOW_ASSIGN_(ReturnAction);
};
@@ -630,13 +619,7 @@
// pointer type on compile time.
template <typename Result, typename ArgumentTuple>
static Result Perform(const ArgumentTuple&) {
-#if GTEST_LANG_CXX11
return nullptr;
-#else
- GTEST_COMPILE_ASSERT_(internal::is_pointer<Result>::value,
- ReturnNull_can_be_used_to_return_a_pointer_only);
- return NULL;
-#endif // GTEST_LANG_CXX11
}
};
@@ -646,7 +629,7 @@
// Allows Return() to be used in any void-returning function.
template <typename Result, typename ArgumentTuple>
static void Perform(const ArgumentTuple&) {
- CompileAssertTypesEqual<void, Result>();
+ static_assert(std::is_void<Result>::value, "Result should be void.");
}
};
@@ -667,7 +650,7 @@
// Asserts that the function return type is a reference. This
// catches the user error of using ReturnRef(x) when Return(x)
// should be used, and generates some helpful error message.
- GTEST_COMPILE_ASSERT_(internal::is_reference<Result>::value,
+ GTEST_COMPILE_ASSERT_(std::is_reference<Result>::value,
use_Return_instead_of_ReturnRef_to_return_a_value);
return Action<F>(new Impl<F>(ref_));
}
@@ -682,9 +665,7 @@
explicit Impl(T& ref) : ref_(ref) {} // NOLINT
- virtual Result Perform(const ArgumentTuple&) {
- return ref_;
- }
+ Result Perform(const ArgumentTuple&) override { return ref_; }
private:
T& ref_;
@@ -716,7 +697,7 @@
// catches the user error of using ReturnRefOfCopy(x) when Return(x)
// should be used, and generates some helpful error message.
GTEST_COMPILE_ASSERT_(
- internal::is_reference<Result>::value,
+ std::is_reference<Result>::value,
use_Return_instead_of_ReturnRefOfCopy_to_return_a_value);
return Action<F>(new Impl<F>(value_));
}
@@ -731,9 +712,7 @@
explicit Impl(const T& value) : value_(value) {} // NOLINT
- virtual Result Perform(const ArgumentTuple&) {
- return value_;
- }
+ Result Perform(const ArgumentTuple&) override { return value_; }
private:
T value_;
@@ -752,7 +731,7 @@
// This template type conversion operator allows DoDefault() to be
// used in any function.
template <typename F>
- operator Action<F>() const { return Action<F>(NULL); }
+ operator Action<F>() const { return Action<F>(); } // NOLINT
};
// Implements the Assign action to set a given pointer referent to a
@@ -800,92 +779,58 @@
#endif // !GTEST_OS_WINDOWS_MOBILE
// Implements the SetArgumentPointee<N>(x) action for any function
-// whose N-th argument (0-based) is a pointer to x's type. The
-// template parameter kIsProto is true iff type A is ProtocolMessage,
-// proto2::Message, or a sub-class of those.
-template <size_t N, typename A, bool kIsProto>
-class SetArgumentPointeeAction {
- public:
- // Constructs an action that sets the variable pointed to by the
- // N-th function argument to 'value'.
- explicit SetArgumentPointeeAction(const A& value) : value_(value) {}
+// whose N-th argument (0-based) is a pointer to x's type.
+template <size_t N, typename A, typename = void>
+struct SetArgumentPointeeAction {
+ A value;
- template <typename Result, typename ArgumentTuple>
- void Perform(const ArgumentTuple& args) const {
- CompileAssertTypesEqual<void, Result>();
- *::testing::get<N>(args) = value_;
+ template <typename... Args>
+ void operator()(const Args&... args) const {
+ *::std::get<N>(std::tie(args...)) = value;
}
-
- private:
- const A value_;
-
- GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
};
-template <size_t N, typename Proto>
-class SetArgumentPointeeAction<N, Proto, true> {
- public:
- // Constructs an action that sets the variable pointed to by the
- // N-th function argument to 'proto'. Both ProtocolMessage and
- // proto2::Message have the CopyFrom() method, so the same
- // implementation works for both.
- explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) {
- proto_->CopyFrom(proto);
+// Implements the Invoke(object_ptr, &Class::Method) action.
+template <class Class, typename MethodPtr>
+struct InvokeMethodAction {
+ Class* const obj_ptr;
+ const MethodPtr method_ptr;
+
+ template <typename... Args>
+ auto operator()(Args&&... args) const
+ -> decltype((obj_ptr->*method_ptr)(std::forward<Args>(args)...)) {
+ return (obj_ptr->*method_ptr)(std::forward<Args>(args)...);
}
-
- template <typename Result, typename ArgumentTuple>
- void Perform(const ArgumentTuple& args) const {
- CompileAssertTypesEqual<void, Result>();
- ::testing::get<N>(args)->CopyFrom(*proto_);
- }
-
- private:
- const internal::linked_ptr<Proto> proto_;
-
- GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction);
};
// Implements the InvokeWithoutArgs(f) action. The template argument
// FunctionImpl is the implementation type of f, which can be either a
// function pointer or a functor. InvokeWithoutArgs(f) can be used as an
-// Action<F> as long as f's type is compatible with F (i.e. f can be
-// assigned to a tr1::function<F>).
+// Action<F> as long as f's type is compatible with F.
template <typename FunctionImpl>
-class InvokeWithoutArgsAction {
- public:
- // The c'tor makes a copy of function_impl (either a function
- // pointer or a functor).
- explicit InvokeWithoutArgsAction(FunctionImpl function_impl)
- : function_impl_(function_impl) {}
+struct InvokeWithoutArgsAction {
+ FunctionImpl function_impl;
// Allows InvokeWithoutArgs(f) to be used as any action whose type is
// compatible with f.
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple&) { return function_impl_(); }
-
- private:
- FunctionImpl function_impl_;
-
- GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction);
+ template <typename... Args>
+ auto operator()(const Args&...) -> decltype(function_impl()) {
+ return function_impl();
+ }
};
// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action.
template <class Class, typename MethodPtr>
-class InvokeMethodWithoutArgsAction {
- public:
- InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr)
- : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {}
+struct InvokeMethodWithoutArgsAction {
+ Class* const obj_ptr;
+ const MethodPtr method_ptr;
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple&) const {
- return (obj_ptr_->*method_ptr_)();
+ using ReturnType = typename std::result_of<MethodPtr(Class*)>::type;
+
+ template <typename... Args>
+ ReturnType operator()(const Args&...) const {
+ return (obj_ptr->*method_ptr)();
}
-
- private:
- Class* const obj_ptr_;
- const MethodPtr method_ptr_;
-
- GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction);
};
// Implements the IgnoreResult(action) action.
@@ -907,7 +852,7 @@
typedef typename internal::Function<F>::Result Result;
// Asserts at compile time that F returns void.
- CompileAssertTypesEqual<void, Result>();
+ static_assert(std::is_void<Result>::value, "Result type should be void.");
return Action<F>(new Impl<F>(action_));
}
@@ -921,7 +866,7 @@
explicit Impl(const A& action) : action_(action) {}
- virtual void Perform(const ArgumentTuple& args) {
+ void Perform(const ArgumentTuple& args) override {
// Performs the action and ignores its result.
action_.Perform(args);
}
@@ -942,76 +887,51 @@
GTEST_DISALLOW_ASSIGN_(IgnoreResultAction);
};
-// A ReferenceWrapper<T> object represents a reference to type T,
-// which can be either const or not. It can be explicitly converted
-// from, and implicitly converted to, a T&. Unlike a reference,
-// ReferenceWrapper<T> can be copied and can survive template type
-// inference. This is used to support by-reference arguments in the
-// InvokeArgument<N>(...) action. The idea was from "reference
-// wrappers" in tr1, which we don't have in our source tree yet.
-template <typename T>
-class ReferenceWrapper {
- public:
- // Constructs a ReferenceWrapper<T> object from a T&.
- explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT
+template <typename InnerAction, size_t... I>
+struct WithArgsAction {
+ InnerAction action;
- // Allows a ReferenceWrapper<T> object to be implicitly converted to
- // a T&.
- operator T&() const { return *pointer_; }
- private:
- T* pointer_;
+ // The inner action could be anything convertible to Action<X>.
+ // We use the conversion operator to detect the signature of the inner Action.
+ template <typename R, typename... Args>
+ operator Action<R(Args...)>() const { // NOLINT
+ Action<R(typename std::tuple_element<I, std::tuple<Args...>>::type...)>
+ converted(action);
+
+ return [converted](Args... args) -> R {
+ return converted.Perform(std::forward_as_tuple(
+ std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...))...));
+ };
+ }
};
-// Allows the expression ByRef(x) to be printed as a reference to x.
-template <typename T>
-void PrintTo(const ReferenceWrapper<T>& ref, ::std::ostream* os) {
- T& value = ref;
- UniversalPrinter<T&>::Print(value, os);
-}
-
-// Does two actions sequentially. Used for implementing the DoAll(a1,
-// a2, ...) action.
-template <typename Action1, typename Action2>
-class DoBothAction {
- public:
- DoBothAction(Action1 action1, Action2 action2)
- : action1_(action1), action2_(action2) {}
-
- // This template type conversion operator allows DoAll(a1, ..., a_n)
- // to be used in ANY function of compatible type.
- template <typename F>
- operator Action<F>() const {
- return Action<F>(new Impl<F>(action1_, action2_));
+template <typename... Actions>
+struct DoAllAction {
+ private:
+ template <typename... Args, size_t... I>
+ std::vector<Action<void(Args...)>> Convert(IndexSequence<I...>) const {
+ return {std::get<I>(actions)...};
}
- private:
- // Implements the DoAll(...) action for a particular function type F.
- template <typename F>
- class Impl : public ActionInterface<F> {
- public:
- typedef typename Function<F>::Result Result;
- typedef typename Function<F>::ArgumentTuple ArgumentTuple;
- typedef typename Function<F>::MakeResultVoid VoidResult;
+ public:
+ std::tuple<Actions...> actions;
- Impl(const Action<VoidResult>& action1, const Action<F>& action2)
- : action1_(action1), action2_(action2) {}
-
- virtual Result Perform(const ArgumentTuple& args) {
- action1_.Perform(args);
- return action2_.Perform(args);
- }
-
- private:
- const Action<VoidResult> action1_;
- const Action<F> action2_;
-
- GTEST_DISALLOW_ASSIGN_(Impl);
- };
-
- Action1 action1_;
- Action2 action2_;
-
- GTEST_DISALLOW_ASSIGN_(DoBothAction);
+ template <typename R, typename... Args>
+ operator Action<R(Args...)>() const { // NOLINT
+ struct Op {
+ std::vector<Action<void(Args...)>> converted;
+ Action<R(Args...)> last;
+ R operator()(Args... args) const {
+ auto tuple_args = std::forward_as_tuple(std::forward<Args>(args)...);
+ for (auto& a : converted) {
+ a.Perform(tuple_args);
+ }
+ return last.Perform(tuple_args);
+ }
+ };
+ return Op{Convert<Args...>(MakeIndexSequence<sizeof...(Actions) - 1>()),
+ std::get<sizeof...(Actions) - 1>(actions)};
+ }
};
} // namespace internal
@@ -1032,9 +952,9 @@
// return sqrt(x*x + y*y);
// }
// ...
-// EXEPCT_CALL(mock, Foo("abc", _, _))
+// EXPECT_CALL(mock, Foo("abc", _, _))
// .WillOnce(Invoke(DistanceToOriginWithLabel));
-// EXEPCT_CALL(mock, Bar(5, _, _))
+// EXPECT_CALL(mock, Bar(5, _, _))
// .WillOnce(Invoke(DistanceToOriginWithIndex));
//
// you could write
@@ -1044,25 +964,55 @@
// return sqrt(x*x + y*y);
// }
// ...
-// EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
-// EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
+// EXPECT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin));
+// EXPECT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin));
typedef internal::IgnoredValue Unused;
-// This constructor allows us to turn an Action<From> object into an
-// Action<To>, as long as To's arguments can be implicitly converted
-// to From's and From's return type cann be implicitly converted to
-// To's.
-template <typename To>
-template <typename From>
-Action<To>::Action(const Action<From>& from)
- : impl_(new internal::ActionAdaptor<To, From>(from)) {}
+// Creates an action that does actions a1, a2, ..., sequentially in
+// each invocation.
+template <typename... Action>
+internal::DoAllAction<typename std::decay<Action>::type...> DoAll(
+ Action&&... action) {
+ return {std::forward_as_tuple(std::forward<Action>(action)...)};
+}
+
+// WithArg<k>(an_action) creates an action that passes the k-th
+// (0-based) argument of the mock function to an_action and performs
+// it. It adapts an action accepting one argument to one that accepts
+// multiple arguments. For convenience, we also provide
+// WithArgs<k>(an_action) (defined below) as a synonym.
+template <size_t k, typename InnerAction>
+internal::WithArgsAction<typename std::decay<InnerAction>::type, k>
+WithArg(InnerAction&& action) {
+ return {std::forward<InnerAction>(action)};
+}
+
+// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
+// the selected arguments of the mock function to an_action and
+// performs it. It serves as an adaptor between actions with
+// different argument lists.
+template <size_t k, size_t... ks, typename InnerAction>
+internal::WithArgsAction<typename std::decay<InnerAction>::type, k, ks...>
+WithArgs(InnerAction&& action) {
+ return {std::forward<InnerAction>(action)};
+}
+
+// WithoutArgs(inner_action) can be used in a mock function with a
+// non-empty argument list to perform inner_action, which takes no
+// argument. In other words, it adapts an action accepting no
+// argument to one that accepts (and ignores) arguments.
+template <typename InnerAction>
+internal::WithArgsAction<typename std::decay<InnerAction>::type>
+WithoutArgs(InnerAction&& action) {
+ return {std::forward<InnerAction>(action)};
+}
// Creates an action that returns 'value'. 'value' is passed by value
// instead of const reference - otherwise Return("string literal")
// will trigger a compiler error about using array as initializer.
template <typename R>
internal::ReturnAction<R> Return(R value) {
- return internal::ReturnAction<R>(internal::move(value));
+ return internal::ReturnAction<R>(std::move(value));
}
// Creates an action that returns NULL.
@@ -1095,7 +1045,7 @@
// invariant.
template <typename R>
internal::ByMoveWrapper<R> ByMove(R x) {
- return internal::ByMoveWrapper<R>(internal::move(x));
+ return internal::ByMoveWrapper<R>(std::move(x));
}
// Creates an action that does the default action for the give mock function.
@@ -1106,43 +1056,14 @@
// Creates an action that sets the variable pointed by the N-th
// (0-based) function argument to 'value'.
template <size_t N, typename T>
-PolymorphicAction<
- internal::SetArgumentPointeeAction<
- N, T, internal::IsAProtocolMessage<T>::value> >
-SetArgPointee(const T& x) {
- return MakePolymorphicAction(internal::SetArgumentPointeeAction<
- N, T, internal::IsAProtocolMessage<T>::value>(x));
+internal::SetArgumentPointeeAction<N, T> SetArgPointee(T x) {
+ return {std::move(x)};
}
-#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN)
-// This overload allows SetArgPointee() to accept a string literal.
-// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish
-// this overload from the templated version and emit a compile error.
-template <size_t N>
-PolymorphicAction<
- internal::SetArgumentPointeeAction<N, const char*, false> >
-SetArgPointee(const char* p) {
- return MakePolymorphicAction(internal::SetArgumentPointeeAction<
- N, const char*, false>(p));
-}
-
-template <size_t N>
-PolymorphicAction<
- internal::SetArgumentPointeeAction<N, const wchar_t*, false> >
-SetArgPointee(const wchar_t* p) {
- return MakePolymorphicAction(internal::SetArgumentPointeeAction<
- N, const wchar_t*, false>(p));
-}
-#endif
-
// The following version is DEPRECATED.
template <size_t N, typename T>
-PolymorphicAction<
- internal::SetArgumentPointeeAction<
- N, T, internal::IsAProtocolMessage<T>::value> >
-SetArgumentPointee(const T& x) {
- return MakePolymorphicAction(internal::SetArgumentPointeeAction<
- N, T, internal::IsAProtocolMessage<T>::value>(x));
+internal::SetArgumentPointeeAction<N, T> SetArgumentPointee(T x) {
+ return {std::move(x)};
}
// Creates an action that sets a pointer referent to a given value.
@@ -1163,24 +1084,38 @@
#endif // !GTEST_OS_WINDOWS_MOBILE
-// Various overloads for InvokeWithoutArgs().
+// Various overloads for Invoke().
+
+// Legacy function.
+// Actions can now be implicitly constructed from callables. No need to create
+// wrapper objects.
+// This function exists for backwards compatibility.
+template <typename FunctionImpl>
+typename std::decay<FunctionImpl>::type Invoke(FunctionImpl&& function_impl) {
+ return std::forward<FunctionImpl>(function_impl);
+}
+
+// Creates an action that invokes the given method on the given object
+// with the mock function's arguments.
+template <class Class, typename MethodPtr>
+internal::InvokeMethodAction<Class, MethodPtr> Invoke(Class* obj_ptr,
+ MethodPtr method_ptr) {
+ return {obj_ptr, method_ptr};
+}
// Creates an action that invokes 'function_impl' with no argument.
template <typename FunctionImpl>
-PolymorphicAction<internal::InvokeWithoutArgsAction<FunctionImpl> >
+internal::InvokeWithoutArgsAction<typename std::decay<FunctionImpl>::type>
InvokeWithoutArgs(FunctionImpl function_impl) {
- return MakePolymorphicAction(
- internal::InvokeWithoutArgsAction<FunctionImpl>(function_impl));
+ return {std::move(function_impl)};
}
// Creates an action that invokes the given method on the given object
// with no argument.
template <class Class, typename MethodPtr>
-PolymorphicAction<internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> >
-InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) {
- return MakePolymorphicAction(
- internal::InvokeMethodWithoutArgsAction<Class, MethodPtr>(
- obj_ptr, method_ptr));
+internal::InvokeMethodWithoutArgsAction<Class, MethodPtr> InvokeWithoutArgs(
+ Class* obj_ptr, MethodPtr method_ptr) {
+ return {obj_ptr, method_ptr};
}
// Creates an action that performs an_action and throws away its
@@ -1198,11 +1133,25 @@
// where Base is a base class of Derived, just write:
//
// ByRef<const Base>(derived)
+//
+// N.B. ByRef is redundant with std::ref, std::cref and std::reference_wrapper.
+// However, it may still be used for consistency with ByMove().
template <typename T>
-inline internal::ReferenceWrapper<T> ByRef(T& l_value) { // NOLINT
- return internal::ReferenceWrapper<T>(l_value);
+inline ::std::reference_wrapper<T> ByRef(T& l_value) { // NOLINT
+ return ::std::reference_wrapper<T>(l_value);
}
} // namespace testing
+#ifdef __clang__
+#if __has_warning("-Wdeprecated-copy")
+#pragma clang diagnostic pop
+#endif
+#endif
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-cardinalities.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-cardinalities.h
index b0da3bd..05b66d4 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-cardinalities.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-cardinalities.h
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -35,16 +34,22 @@
// cardinalities can be defined by the user implementing the
// CardinalityInterface interface if necessary.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
#include <limits.h>
+#include <memory>
#include <ostream> // NOLINT
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
namespace testing {
// To implement a cardinality Foo, define:
@@ -67,10 +72,12 @@
virtual int ConservativeLowerBound() const { return 0; }
virtual int ConservativeUpperBound() const { return INT_MAX; }
- // Returns true iff call_count calls will satisfy this cardinality.
+ // Returns true if and only if call_count calls will satisfy this
+ // cardinality.
virtual bool IsSatisfiedByCallCount(int call_count) const = 0;
- // Returns true iff call_count calls will saturate this cardinality.
+ // Returns true if and only if call_count calls will saturate this
+ // cardinality.
virtual bool IsSaturatedByCallCount(int call_count) const = 0;
// Describes self to an ostream.
@@ -79,9 +86,8 @@
// A Cardinality is a copyable and IMMUTABLE (except by assignment)
// object that specifies how many times a mock function is expected to
-// be called. The implementation of Cardinality is just a linked_ptr
-// to const CardinalityInterface, so copying is fairly cheap.
-// Don't inherit from Cardinality!
+// be called. The implementation of Cardinality is just a std::shared_ptr
+// to const CardinalityInterface. Don't inherit from Cardinality!
class GTEST_API_ Cardinality {
public:
// Constructs a null cardinality. Needed for storing Cardinality
@@ -96,17 +102,19 @@
int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); }
int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); }
- // Returns true iff call_count calls will satisfy this cardinality.
+ // Returns true if and only if call_count calls will satisfy this
+ // cardinality.
bool IsSatisfiedByCallCount(int call_count) const {
return impl_->IsSatisfiedByCallCount(call_count);
}
- // Returns true iff call_count calls will saturate this cardinality.
+ // Returns true if and only if call_count calls will saturate this
+ // cardinality.
bool IsSaturatedByCallCount(int call_count) const {
return impl_->IsSaturatedByCallCount(call_count);
}
- // Returns true iff call_count calls will over-saturate this
+ // Returns true if and only if call_count calls will over-saturate this
// cardinality, i.e. exceed the maximum number of allowed calls.
bool IsOverSaturatedByCallCount(int call_count) const {
return impl_->IsSaturatedByCallCount(call_count) &&
@@ -121,7 +129,7 @@
::std::ostream* os);
private:
- internal::linked_ptr<const CardinalityInterface> impl_;
+ std::shared_ptr<const CardinalityInterface> impl_;
};
// Creates a cardinality that allows at least n calls.
@@ -146,4 +154,6 @@
} // namespace testing
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-function-mocker.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-function-mocker.h
new file mode 100644
index 0000000..cc1535c
--- /dev/null
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-function-mocker.h
@@ -0,0 +1,253 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Google Mock - a framework for writing C++ mock classes.
+//
+// This file implements MOCK_METHOD.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
+#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT
+
+#include "gmock/gmock-generated-function-mockers.h" // NOLINT
+#include "gmock/internal/gmock-pp.h"
+
+#define MOCK_METHOD(...) \
+ GMOCK_PP_VARIADIC_CALL(GMOCK_INTERNAL_MOCK_METHOD_ARG_, __VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_1(...) \
+ GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_2(...) \
+ GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_3(_Ret, _MethodName, _Args) \
+ GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, ())
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_4(_Ret, _MethodName, _Args, _Spec) \
+ GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Args); \
+ GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Spec); \
+ GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE( \
+ GMOCK_PP_NARG0 _Args, GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)); \
+ GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
+ GMOCK_INTERNAL_MOCK_METHOD_IMPL( \
+ GMOCK_PP_NARG0 _Args, _MethodName, GMOCK_INTERNAL_HAS_CONST(_Spec), \
+ GMOCK_INTERNAL_HAS_OVERRIDE(_Spec), GMOCK_INTERNAL_HAS_FINAL(_Spec), \
+ GMOCK_INTERNAL_HAS_NOEXCEPT(_Spec), GMOCK_INTERNAL_GET_CALLTYPE(_Spec), \
+ (GMOCK_INTERNAL_SIGNATURE(_Ret, _Args)))
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_5(...) \
+ GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_6(...) \
+ GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_ARG_7(...) \
+ GMOCK_INTERNAL_WRONG_ARITY(__VA_ARGS__)
+
+#define GMOCK_INTERNAL_WRONG_ARITY(...) \
+ static_assert( \
+ false, \
+ "MOCK_METHOD must be called with 3 or 4 arguments. _Ret, " \
+ "_MethodName, _Args and optionally _Spec. _Args and _Spec must be " \
+ "enclosed in parentheses. If _Ret is a type with unprotected commas, " \
+ "it must also be enclosed in parentheses.")
+
+#define GMOCK_INTERNAL_ASSERT_PARENTHESIS(_Tuple) \
+ static_assert( \
+ GMOCK_PP_IS_ENCLOSED_PARENS(_Tuple), \
+ GMOCK_PP_STRINGIZE(_Tuple) " should be enclosed in parentheses.")
+
+#define GMOCK_INTERNAL_ASSERT_VALID_SIGNATURE(_N, ...) \
+ static_assert( \
+ std::is_function<__VA_ARGS__>::value, \
+ "Signature must be a function type, maybe return type contains " \
+ "unprotected comma."); \
+ static_assert( \
+ ::testing::tuple_size<typename ::testing::internal::Function< \
+ __VA_ARGS__>::ArgumentTuple>::value == _N, \
+ "This method does not take " GMOCK_PP_STRINGIZE( \
+ _N) " arguments. Parenthesize all types with unproctected commas.")
+
+#define GMOCK_INTERNAL_ASSERT_VALID_SPEC(_Spec) \
+ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT, ~, _Spec)
+
+#define GMOCK_INTERNAL_MOCK_METHOD_IMPL(_N, _MethodName, _Constness, \
+ _Override, _Final, _Noexcept, \
+ _CallType, _Signature) \
+ typename ::testing::internal::Function<GMOCK_PP_REMOVE_PARENS( \
+ _Signature)>::Result \
+ GMOCK_INTERNAL_EXPAND(_CallType) \
+ _MethodName(GMOCK_PP_REPEAT(GMOCK_INTERNAL_PARAMETER, _Signature, _N)) \
+ GMOCK_PP_IF(_Constness, const, ) GMOCK_PP_IF(_Noexcept, noexcept, ) \
+ GMOCK_PP_IF(_Override, override, ) \
+ GMOCK_PP_IF(_Final, final, ) { \
+ GMOCK_MOCKER_(_N, _Constness, _MethodName) \
+ .SetOwnerAndName(this, #_MethodName); \
+ return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
+ .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \
+ } \
+ ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
+ GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \
+ GMOCK_PP_IF(_Constness, const, ) { \
+ GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \
+ return GMOCK_MOCKER_(_N, _Constness, _MethodName) \
+ .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \
+ } \
+ ::testing::MockSpec<GMOCK_PP_REMOVE_PARENS(_Signature)> gmock_##_MethodName( \
+ const ::testing::internal::WithoutMatchers&, \
+ GMOCK_PP_IF(_Constness, const, )::testing::internal::Function< \
+ GMOCK_PP_REMOVE_PARENS(_Signature)>*) \
+ const GMOCK_PP_IF(_Noexcept, noexcept, ) { \
+ return GMOCK_PP_CAT(::testing::internal::AdjustConstness_, \
+ GMOCK_PP_IF(_Constness, const, ))(this) \
+ ->gmock_##_MethodName(GMOCK_PP_REPEAT( \
+ GMOCK_INTERNAL_A_MATCHER_ARGUMENT, _Signature, _N)); \
+ } \
+ mutable ::testing::FunctionMocker<GMOCK_PP_REMOVE_PARENS(_Signature)> \
+ GMOCK_MOCKER_(_N, _Constness, _MethodName)
+
+#define GMOCK_INTERNAL_EXPAND(...) __VA_ARGS__
+
+// Five Valid modifiers.
+#define GMOCK_INTERNAL_HAS_CONST(_Tuple) \
+ GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_CONST, ~, _Tuple))
+
+#define GMOCK_INTERNAL_HAS_OVERRIDE(_Tuple) \
+ GMOCK_PP_HAS_COMMA( \
+ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_OVERRIDE, ~, _Tuple))
+
+#define GMOCK_INTERNAL_HAS_FINAL(_Tuple) \
+ GMOCK_PP_HAS_COMMA(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_FINAL, ~, _Tuple))
+
+#define GMOCK_INTERNAL_HAS_NOEXCEPT(_Tuple) \
+ GMOCK_PP_HAS_COMMA( \
+ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_DETECT_NOEXCEPT, ~, _Tuple))
+
+#define GMOCK_INTERNAL_GET_CALLTYPE(_Tuple) \
+ GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_CALLTYPE_IMPL, ~, _Tuple)
+
+#define GMOCK_INTERNAL_ASSERT_VALID_SPEC_ELEMENT(_i, _, _elem) \
+ static_assert( \
+ (GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem)) + \
+ GMOCK_PP_HAS_COMMA(GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem)) + \
+ GMOCK_INTERNAL_IS_CALLTYPE(_elem)) == 1, \
+ GMOCK_PP_STRINGIZE( \
+ _elem) " cannot be recognized as a valid specification modifier.");
+
+// Modifiers implementation.
+#define GMOCK_INTERNAL_DETECT_CONST(_i, _, _elem) \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_CONST_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_CONST_I_const ,
+
+#define GMOCK_INTERNAL_DETECT_OVERRIDE(_i, _, _elem) \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_OVERRIDE_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_OVERRIDE_I_override ,
+
+#define GMOCK_INTERNAL_DETECT_FINAL(_i, _, _elem) \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_FINAL_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_FINAL_I_final ,
+
+// TODO(iserna): Maybe noexcept should accept an argument here as well.
+#define GMOCK_INTERNAL_DETECT_NOEXCEPT(_i, _, _elem) \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_DETECT_NOEXCEPT_I_, _elem)
+
+#define GMOCK_INTERNAL_DETECT_NOEXCEPT_I_noexcept ,
+
+#define GMOCK_INTERNAL_GET_CALLTYPE_IMPL(_i, _, _elem) \
+ GMOCK_PP_IF(GMOCK_INTERNAL_IS_CALLTYPE(_elem), \
+ GMOCK_INTERNAL_GET_VALUE_CALLTYPE, GMOCK_PP_EMPTY) \
+ (_elem)
+
+// TODO(iserna): GMOCK_INTERNAL_IS_CALLTYPE and
+// GMOCK_INTERNAL_GET_VALUE_CALLTYPE needed more expansions to work on windows
+// maybe they can be simplified somehow.
+#define GMOCK_INTERNAL_IS_CALLTYPE(_arg) \
+ GMOCK_INTERNAL_IS_CALLTYPE_I( \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
+#define GMOCK_INTERNAL_IS_CALLTYPE_I(_arg) GMOCK_PP_IS_ENCLOSED_PARENS(_arg)
+
+#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE(_arg) \
+ GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I( \
+ GMOCK_PP_CAT(GMOCK_INTERNAL_IS_CALLTYPE_HELPER_, _arg))
+#define GMOCK_INTERNAL_GET_VALUE_CALLTYPE_I(_arg) \
+ GMOCK_PP_CAT(GMOCK_PP_IDENTITY, _arg)
+
+#define GMOCK_INTERNAL_IS_CALLTYPE_HELPER_Calltype
+
+#define GMOCK_INTERNAL_SIGNATURE(_Ret, _Args) \
+ GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_Ret), GMOCK_PP_REMOVE_PARENS, \
+ GMOCK_PP_IDENTITY) \
+ (_Ret)(GMOCK_PP_FOR_EACH(GMOCK_INTERNAL_GET_TYPE, _, _Args))
+
+#define GMOCK_INTERNAL_GET_TYPE(_i, _, _elem) \
+ GMOCK_PP_COMMA_IF(_i) \
+ GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(_elem), GMOCK_PP_REMOVE_PARENS, \
+ GMOCK_PP_IDENTITY) \
+ (_elem)
+
+#define GMOCK_INTERNAL_PARAMETER(_i, _Signature, _) \
+ GMOCK_PP_COMMA_IF(_i) \
+ GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
+ GMOCK_PP_REMOVE_PARENS(_Signature)) \
+ gmock_a##_i
+
+#define GMOCK_INTERNAL_FORWARD_ARG(_i, _Signature, _) \
+ GMOCK_PP_COMMA_IF(_i) \
+ ::std::forward<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
+ GMOCK_PP_REMOVE_PARENS(_Signature))>( \
+ gmock_a##_i)
+
+#define GMOCK_INTERNAL_MATCHER_PARAMETER(_i, _Signature, _) \
+ GMOCK_PP_COMMA_IF(_i) \
+ GMOCK_INTERNAL_MATCHER_O(typename, GMOCK_PP_INC(_i), \
+ GMOCK_PP_REMOVE_PARENS(_Signature)) \
+ gmock_a##_i
+
+#define GMOCK_INTERNAL_MATCHER_ARGUMENT(_i, _1, _2) \
+ GMOCK_PP_COMMA_IF(_i) \
+ gmock_a##_i
+
+#define GMOCK_INTERNAL_A_MATCHER_ARGUMENT(_i, _Signature, _) \
+ GMOCK_PP_COMMA_IF(_i) \
+ ::testing::A<GMOCK_INTERNAL_ARG_O(typename, GMOCK_PP_INC(_i), \
+ GMOCK_PP_REMOVE_PARENS(_Signature))>()
+
+#define GMOCK_INTERNAL_ARG_O(_tn, _i, ...) GMOCK_ARG_(_tn, _i, __VA_ARGS__)
+
+#define GMOCK_INTERNAL_MATCHER_O(_tn, _i, ...) \
+ GMOCK_MATCHER_(_tn, _i, __VA_ARGS__)
+
+#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-actions.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-actions.h
index ee00ad8..c538dce 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-actions.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-actions.h
@@ -1,4 +1,6 @@
-// This file was GENERATED by a script. DO NOT EDIT BY HAND!!!
+// This file was GENERATED by command:
+// pump.py gmock-generated-actions.h.pump
+// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
@@ -28,471 +30,28 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used variadic actions.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
+#include <memory>
+#include <utility>
+
#include "gmock/gmock-actions.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
namespace internal {
-// InvokeHelper<F> knows how to unpack an N-tuple and invoke an N-ary
-// function or method with the unpacked values, where F is a function
-// type that takes N arguments.
-template <typename Result, typename ArgumentTuple>
-class InvokeHelper;
-
-template <typename R>
-class InvokeHelper<R, ::testing::tuple<> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<>&) {
- return function();
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<>&) {
- return (obj_ptr->*method_ptr)();
- }
-};
-
-template <typename R, typename A1>
-class InvokeHelper<R, ::testing::tuple<A1> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1>& args) {
- return function(get<0>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args));
- }
-};
-
-template <typename R, typename A1, typename A2>
-class InvokeHelper<R, ::testing::tuple<A1, A2> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2>& args) {
- return function(get<0>(args), get<1>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3,
- A4>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4,
- A5>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args), get<4>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4, A5>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args), get<4>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
- A6>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args), get<4>(args), get<5>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4, A5, A6>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args), get<4>(args), get<5>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
- A6, A7>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args), get<4>(args), get<5>(args), get<6>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4, A5, A6,
- A7>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args), get<4>(args), get<5>(args),
- get<6>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
- A6, A7, A8>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args), get<4>(args), get<5>(args), get<6>(args),
- get<7>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7,
- A8>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args), get<4>(args), get<5>(args),
- get<6>(args), get<7>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
- A6, A7, A8, A9>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args), get<4>(args), get<5>(args), get<6>(args),
- get<7>(args), get<8>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
- A9>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args), get<4>(args), get<5>(args),
- get<6>(args), get<7>(args), get<8>(args));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-class InvokeHelper<R, ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
- A10> > {
- public:
- template <typename Function>
- static R Invoke(Function function, const ::testing::tuple<A1, A2, A3, A4, A5,
- A6, A7, A8, A9, A10>& args) {
- return function(get<0>(args), get<1>(args), get<2>(args),
- get<3>(args), get<4>(args), get<5>(args), get<6>(args),
- get<7>(args), get<8>(args), get<9>(args));
- }
-
- template <class Class, typename MethodPtr>
- static R InvokeMethod(Class* obj_ptr,
- MethodPtr method_ptr,
- const ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8,
- A9, A10>& args) {
- return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args),
- get<2>(args), get<3>(args), get<4>(args), get<5>(args),
- get<6>(args), get<7>(args), get<8>(args), get<9>(args));
- }
-};
-
-// An INTERNAL macro for extracting the type of a tuple field. It's
-// subject to change without notice - DO NOT USE IN USER CODE!
-#define GMOCK_FIELD_(Tuple, N) \
- typename ::testing::tuple_element<N, Tuple>::type
-
-// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::type is the
-// type of an n-ary function whose i-th (1-based) argument type is the
-// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple
-// type, and whose return type is Result. For example,
-// SelectArgs<int, ::testing::tuple<bool, char, double, long>, 0, 3>::type
-// is int(bool, long).
-//
-// SelectArgs<Result, ArgumentTuple, k1, k2, ..., k_n>::Select(args)
-// returns the selected fields (k1, k2, ..., k_n) of args as a tuple.
-// For example,
-// SelectArgs<int, tuple<bool, char, double>, 2, 0>::Select(
-// ::testing::make_tuple(true, 'a', 2.5))
-// returns tuple (2.5, true).
-//
-// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be
-// in the range [0, 10]. Duplicates are allowed and they don't have
-// to be in an ascending or descending order.
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4, int k5, int k6, int k7, int k8, int k9, int k10>
-class SelectArgs {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
- GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
- GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9),
- GMOCK_FIELD_(ArgumentTuple, k10));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
- get<k8>(args), get<k9>(args), get<k10>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple>
-class SelectArgs<Result, ArgumentTuple,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef Result type();
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& /* args */) {
- return SelectedArgs();
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1>
-class SelectArgs<Result, ArgumentTuple,
- k1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, -1, -1, -1, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4, int k5>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, k5, -1, -1, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args), get<k5>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4, int k5, int k6>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, k5, k6, -1, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
- GMOCK_FIELD_(ArgumentTuple, k6));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args), get<k5>(args), get<k6>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4, int k5, int k6, int k7>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, k5, k6, k7, -1, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
- GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4, int k5, int k6, int k7, int k8>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, k5, k6, k7, k8, -1, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
- GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
- GMOCK_FIELD_(ArgumentTuple, k8));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
- get<k8>(args));
- }
-};
-
-template <typename Result, typename ArgumentTuple, int k1, int k2, int k3,
- int k4, int k5, int k6, int k7, int k8, int k9>
-class SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, k5, k6, k7, k8, k9, -1> {
- public:
- typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1),
- GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3),
- GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5),
- GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7),
- GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9));
- typedef typename Function<type>::ArgumentTuple SelectedArgs;
- static SelectedArgs Select(const ArgumentTuple& args) {
- return SelectedArgs(get<k1>(args), get<k2>(args), get<k3>(args),
- get<k4>(args), get<k5>(args), get<k6>(args), get<k7>(args),
- get<k8>(args), get<k9>(args));
- }
-};
-
-#undef GMOCK_FIELD_
-
-// Implements the WithArgs action.
-template <typename InnerAction, int k1 = -1, int k2 = -1, int k3 = -1,
- int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
- int k9 = -1, int k10 = -1>
-class WithArgsAction {
- public:
- explicit WithArgsAction(const InnerAction& action) : action_(action) {}
-
- template <typename F>
- operator Action<F>() const { return MakeAction(new Impl<F>(action_)); }
-
- private:
- template <typename F>
- class Impl : public ActionInterface<F> {
- public:
- typedef typename Function<F>::Result Result;
- typedef typename Function<F>::ArgumentTuple ArgumentTuple;
-
- explicit Impl(const InnerAction& action) : action_(action) {}
-
- virtual Result Perform(const ArgumentTuple& args) {
- return action_.Perform(SelectArgs<Result, ArgumentTuple, k1, k2, k3, k4,
- k5, k6, k7, k8, k9, k10>::Select(args));
- }
-
- private:
- typedef typename SelectArgs<Result, ArgumentTuple,
- k1, k2, k3, k4, k5, k6, k7, k8, k9, k10>::type InnerFunctionType;
-
- Action<InnerFunctionType> action_;
- };
-
- const InnerAction action_;
-
- GTEST_DISALLOW_ASSIGN_(WithArgsAction);
-};
-
// A macro from the ACTION* family (defined later in this file)
// defines an action that can be used in a mock function. Typically,
// these actions only care about a subset of the arguments of the mock
@@ -513,7 +72,7 @@
template <typename Result, class Impl>
class ActionHelper {
public:
- static Result Perform(Impl* impl, const ::testing::tuple<>& args) {
+ static Result Perform(Impl* impl, const ::std::tuple<>& args) {
return impl->template gmock_PerformImpl<>(args, ExcessiveArg(),
ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
@@ -521,266 +80,100 @@
}
template <typename A0>
- static Result Perform(Impl* impl, const ::testing::tuple<A0>& args) {
- return impl->template gmock_PerformImpl<A0>(args, get<0>(args),
+ static Result Perform(Impl* impl, const ::std::tuple<A0>& args) {
+ return impl->template gmock_PerformImpl<A0>(args, std::get<0>(args),
ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
ExcessiveArg());
}
template <typename A0, typename A1>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1>& args) {
- return impl->template gmock_PerformImpl<A0, A1>(args, get<0>(args),
- get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1>& args) {
+ return impl->template gmock_PerformImpl<A0, A1>(args, std::get<0>(args),
+ std::get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
ExcessiveArg());
}
template <typename A0, typename A1, typename A2>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2>& args) {
- return impl->template gmock_PerformImpl<A0, A1, A2>(args, get<0>(args),
- get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(),
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2>& args) {
+ return impl->template gmock_PerformImpl<A0, A1, A2>(args,
+ std::get<0>(args), std::get<1>(args), std::get<2>(args),
ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
- ExcessiveArg());
+ ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2,
- A3>& args) {
- return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args, get<0>(args),
- get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(),
- ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
- ExcessiveArg());
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3>& args) {
+ return impl->template gmock_PerformImpl<A0, A1, A2, A3>(args,
+ std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
+ ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3, typename A4>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3,
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3,
A4>& args) {
return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4>(args,
- get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
- ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
- ExcessiveArg());
+ std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), std::get<4>(args), ExcessiveArg(), ExcessiveArg(),
+ ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3, typename A4,
typename A5>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4,
A5>& args) {
return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5>(args,
- get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
- get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(),
- ExcessiveArg());
+ std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), std::get<4>(args), std::get<5>(args),
+ ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
- A5, A6>& args) {
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+ A6>& args) {
return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6>(args,
- get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args),
- get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(),
- ExcessiveArg());
+ std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), std::get<4>(args), std::get<5>(args),
+ std::get<6>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
- A5, A6, A7>& args) {
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+ A6, A7>& args) {
return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6,
- A7>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
- get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(),
- ExcessiveArg());
+ A7>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), std::get<4>(args), std::get<5>(args),
+ std::get<6>(args), std::get<7>(args), ExcessiveArg(), ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
- A5, A6, A7, A8>& args) {
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+ A6, A7, A8>& args) {
return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7,
- A8>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
- get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
+ A8>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), std::get<4>(args), std::get<5>(args),
+ std::get<6>(args), std::get<7>(args), std::get<8>(args),
ExcessiveArg());
}
template <typename A0, typename A1, typename A2, typename A3, typename A4,
typename A5, typename A6, typename A7, typename A8, typename A9>
- static Result Perform(Impl* impl, const ::testing::tuple<A0, A1, A2, A3, A4,
- A5, A6, A7, A8, A9>& args) {
+ static Result Perform(Impl* impl, const ::std::tuple<A0, A1, A2, A3, A4, A5,
+ A6, A7, A8, A9>& args) {
return impl->template gmock_PerformImpl<A0, A1, A2, A3, A4, A5, A6, A7, A8,
- A9>(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args),
- get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args),
- get<9>(args));
+ A9>(args, std::get<0>(args), std::get<1>(args), std::get<2>(args),
+ std::get<3>(args), std::get<4>(args), std::get<5>(args),
+ std::get<6>(args), std::get<7>(args), std::get<8>(args),
+ std::get<9>(args));
}
};
} // namespace internal
-
-// Various overloads for Invoke().
-
-// WithArgs<N1, N2, ..., Nk>(an_action) creates an action that passes
-// the selected arguments of the mock function to an_action and
-// performs it. It serves as an adaptor between actions with
-// different argument lists. C++ doesn't support default arguments for
-// function templates, so we have to overload it.
-template <int k1, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1>(action);
-}
-
-template <int k1, int k2, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2>(action);
-}
-
-template <int k1, int k2, int k3, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3>(action);
-}
-
-template <int k1, int k2, int k3, int k4, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
- typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6,
- k7>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
- typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7,
- k8>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
- int k9, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8, k9>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
- k9>(action);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
- int k9, int k10, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
- k9, k10>
-WithArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k1, k2, k3, k4, k5, k6, k7, k8,
- k9, k10>(action);
-}
-
-// Creates an action that does actions a1, a2, ..., sequentially in
-// each invocation.
-template <typename Action1, typename Action2>
-inline internal::DoBothAction<Action1, Action2>
-DoAll(Action1 a1, Action2 a2) {
- return internal::DoBothAction<Action1, Action2>(a1, a2);
-}
-
-template <typename Action1, typename Action2, typename Action3>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- Action3> >
-DoAll(Action1 a1, Action2 a2, Action3 a3) {
- return DoAll(a1, DoAll(a2, a3));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, Action4> > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) {
- return DoAll(a1, DoAll(a2, a3, a4));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4, typename Action5>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, internal::DoBothAction<Action4,
- Action5> > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) {
- return DoAll(a1, DoAll(a2, a3, a4, a5));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4, typename Action5, typename Action6>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, internal::DoBothAction<Action4,
- internal::DoBothAction<Action5, Action6> > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) {
- return DoAll(a1, DoAll(a2, a3, a4, a5, a6));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4, typename Action5, typename Action6, typename Action7>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, internal::DoBothAction<Action4,
- internal::DoBothAction<Action5, internal::DoBothAction<Action6,
- Action7> > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
- Action7 a7) {
- return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4, typename Action5, typename Action6, typename Action7,
- typename Action8>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, internal::DoBothAction<Action4,
- internal::DoBothAction<Action5, internal::DoBothAction<Action6,
- internal::DoBothAction<Action7, Action8> > > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
- Action7 a7, Action8 a8) {
- return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4, typename Action5, typename Action6, typename Action7,
- typename Action8, typename Action9>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, internal::DoBothAction<Action4,
- internal::DoBothAction<Action5, internal::DoBothAction<Action6,
- internal::DoBothAction<Action7, internal::DoBothAction<Action8,
- Action9> > > > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
- Action7 a7, Action8 a8, Action9 a9) {
- return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9));
-}
-
-template <typename Action1, typename Action2, typename Action3,
- typename Action4, typename Action5, typename Action6, typename Action7,
- typename Action8, typename Action9, typename Action10>
-inline internal::DoBothAction<Action1, internal::DoBothAction<Action2,
- internal::DoBothAction<Action3, internal::DoBothAction<Action4,
- internal::DoBothAction<Action5, internal::DoBothAction<Action6,
- internal::DoBothAction<Action7, internal::DoBothAction<Action8,
- internal::DoBothAction<Action9, Action10> > > > > > > > >
-DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6,
- Action7 a7, Action8 a8, Action9 a9, Action10 a10) {
- return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10));
-}
-
} // namespace testing
// The ACTION* family of macros can be used in a namespace scope to
@@ -868,30 +261,29 @@
//
// CAVEAT:
//
-// ACTION*() can only be used in a namespace scope. The reason is
-// that C++ doesn't yet allow function-local types to be used to
-// instantiate templates. The up-coming C++0x standard will fix this.
-// Once that's done, we'll consider supporting using ACTION*() inside
-// a function.
+// ACTION*() can only be used in a namespace scope as templates cannot be
+// declared inside of a local class.
+// Users can, however, define any local functors (e.g. a lambda) that
+// can be used as actions.
//
// MORE INFORMATION:
//
-// To learn more about using these macros, please search for 'ACTION'
-// on http://code.google.com/p/googlemock/wiki/CookBook.
+// To learn more about using these macros, please search for 'ACTION' on
+// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
// An internal macro needed for implementing ACTION*().
#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\
const args_type& args GTEST_ATTRIBUTE_UNUSED_, \
- arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \
- arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \
- arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \
- arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \
- arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \
- arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \
- arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \
- arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \
- arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \
- arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_
+ const arg0_type& arg0 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg1_type& arg1 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg2_type& arg2 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg3_type& arg3 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg4_type& arg4 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg5_type& arg5 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg6_type& arg6 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg7_type& arg7 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg8_type& arg8 GTEST_ATTRIBUTE_UNUSED_, \
+ const arg9_type& arg9 GTEST_ATTRIBUTE_UNUSED_
// Sometimes you want to give an action explicit template parameters
// that cannot be inferred from its value parameters. ACTION() and
@@ -917,7 +309,7 @@
// ACTION_TEMPLATE(DuplicateArg,
// HAS_2_TEMPLATE_PARAMS(int, k, typename, T),
// AND_1_VALUE_PARAMS(output)) {
-// *output = T(::testing::get<k>(args));
+// *output = T(::std::get<k>(args));
// }
// ...
// int n;
@@ -1075,52 +467,67 @@
#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\
()
#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\
- (p0##_type gmock_p0) : p0(gmock_p0)
+ (p0##_type gmock_p0) : p0(::std::move(gmock_p0))
#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\
- (p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1)
+ (p0##_type gmock_p0, p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1))
#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\
(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2)
+ p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2))
#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3)
+ p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3))
#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4)
+ p3##_type gmock_p3, p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4))
#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5)
+ p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5))
#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6)
+ p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6))
#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7)
+ p6##_type gmock_p6, p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+ p7(::std::move(gmock_p7))
#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8)
+ p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+ p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8))
#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \
p7, p8, p9)\
(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
- p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8), p9(gmock_p9)
+ p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+ p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
+ p9(::std::move(gmock_p9))
// Declares the fields for storing the value parameters.
#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS()
@@ -1250,6 +657,10 @@
public:\
explicit GMOCK_ACTION_CLASS_(name, value_params)\
GMOCK_INTERNAL_INIT_##value_params {}\
+ GMOCK_ACTION_CLASS_(name, value_params)(\
+ const GMOCK_ACTION_CLASS_(name, value_params)&) noexcept = default;\
+ GMOCK_ACTION_CLASS_(name, value_params)(\
+ GMOCK_ACTION_CLASS_(name, value_params)&&) noexcept = default;\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1266,10 +677,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
GMOCK_INTERNAL_DEFN_##value_params\
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
@@ -1279,8 +692,6 @@
new gmock_Impl<F>(GMOCK_INTERNAL_LIST_##value_params));\
}\
GMOCK_INTERNAL_DEFN_##value_params\
- private:\
- GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\
};\
template <GMOCK_INTERNAL_DECL_##template_params\
GMOCK_INTERNAL_DECL_TYPE_##value_params>\
@@ -1327,10 +738,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
@@ -1356,7 +769,8 @@
template <typename p0##_type>\
class name##ActionP {\
public:\
- explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\
+ explicit name##ActionP(p0##_type gmock_p0) : \
+ p0(::std::forward<p0##_type>(gmock_p0)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1364,7 +778,8 @@
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
- explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\
+ explicit gmock_Impl(p0##_type gmock_p0) : \
+ p0(::std::forward<p0##_type>(gmock_p0)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1373,10 +788,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
private:\
GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
@@ -1406,8 +823,9 @@
template <typename p0##_type, typename p1##_type>\
class name##ActionP2 {\
public:\
- name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
- p1(gmock_p1) {}\
+ name##ActionP2(p0##_type gmock_p0, \
+ p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1415,8 +833,9 @@
typedef typename ::testing::internal::Function<F>::Result return_type;\
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
- gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
- p1(gmock_p1) {}\
+ gmock_Impl(p0##_type gmock_p0, \
+ p1##_type gmock_p1) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1425,10 +844,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
private:\
@@ -1462,7 +883,9 @@
class name##ActionP3 {\
public:\
name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+ p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1471,7 +894,9 @@
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+ p2##_type gmock_p2) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1480,10 +905,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1521,8 +948,11 @@
class name##ActionP4 {\
public:\
name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3) {}\
+ p2##_type gmock_p2, \
+ p3##_type gmock_p3) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1531,8 +961,10 @@
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3) {}\
+ p3##_type gmock_p3) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1541,10 +973,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1589,8 +1023,11 @@
public:\
name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, \
- p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4) {}\
+ p4##_type gmock_p4) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1599,8 +1036,12 @@
typedef typename ::testing::internal::Function<F>::ArgumentTuple\
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
- p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \
- p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\
+ p3##_type gmock_p3, \
+ p4##_type gmock_p4) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1609,10 +1050,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1659,8 +1102,12 @@
public:\
name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
+ p5##_type gmock_p5) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1670,8 +1117,12 @@
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\
+ p5##_type gmock_p5) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1680,10 +1131,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1733,9 +1186,14 @@
public:\
name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
- p6(gmock_p6) {}\
+ p5##_type gmock_p5, \
+ p6##_type gmock_p6) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1745,8 +1203,13 @@
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
+ p6##_type gmock_p6) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1755,10 +1218,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1815,9 +1280,14 @@
name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, \
- p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7) {}\
+ p7##_type gmock_p7) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)), \
+ p7(::std::forward<p7##_type>(gmock_p7)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1827,9 +1297,15 @@
args_type;\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
- p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \
- p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \
- p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
+ p6##_type gmock_p6, \
+ p7##_type gmock_p7) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)), \
+ p7(::std::forward<p7##_type>(gmock_p7)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1838,10 +1314,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1902,9 +1380,15 @@
name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8) {}\
+ p8##_type gmock_p8) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)), \
+ p7(::std::forward<p7##_type>(gmock_p7)), \
+ p8(::std::forward<p8##_type>(gmock_p8)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -1915,9 +1399,15 @@
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8) {}\
+ p8##_type gmock_p8) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)), \
+ p7(::std::forward<p7##_type>(gmock_p7)), \
+ p8(::std::forward<p8##_type>(gmock_p8)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -1926,10 +1416,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -1994,9 +1486,17 @@
name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
+ p8##_type gmock_p8, \
+ p9##_type gmock_p9) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)), \
+ p7(::std::forward<p7##_type>(gmock_p7)), \
+ p8(::std::forward<p8##_type>(gmock_p8)), \
+ p9(::std::forward<p9##_type>(gmock_p9)) {}\
template <typename F>\
class gmock_Impl : public ::testing::ActionInterface<F> {\
public:\
@@ -2007,9 +1507,16 @@
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
- p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\
+ p9##_type gmock_p9) : p0(::std::forward<p0##_type>(gmock_p0)), \
+ p1(::std::forward<p1##_type>(gmock_p1)), \
+ p2(::std::forward<p2##_type>(gmock_p2)), \
+ p3(::std::forward<p3##_type>(gmock_p3)), \
+ p4(::std::forward<p4##_type>(gmock_p4)), \
+ p5(::std::forward<p5##_type>(gmock_p5)), \
+ p6(::std::forward<p6##_type>(gmock_p6)), \
+ p7(::std::forward<p7##_type>(gmock_p7)), \
+ p8(::std::forward<p8##_type>(gmock_p8)), \
+ p9(::std::forward<p9##_type>(gmock_p9)) {}\
virtual return_type Perform(const args_type& args) {\
return ::testing::internal::ActionHelper<return_type, gmock_Impl>::\
Perform(this, args);\
@@ -2018,10 +1525,12 @@
typename arg3_type, typename arg4_type, typename arg5_type, \
typename arg6_type, typename arg7_type, typename arg8_type, \
typename arg9_type>\
- return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \
- arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \
- arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \
- arg9_type arg9) const;\
+ return_type gmock_PerformImpl(const args_type& args, \
+ const arg0_type& arg0, const arg1_type& arg1, \
+ const arg2_type& arg2, const arg3_type& arg3, \
+ const arg4_type& arg4, const arg5_type& arg5, \
+ const arg6_type& arg6, const arg7_type& arg7, \
+ const arg8_type& arg8, const arg9_type& arg9) const;\
p0##_type p0;\
p1##_type p1;\
p2##_type p2;\
@@ -2201,7 +1710,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args));
+ ::std::get<k>(args));
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2210,7 +1719,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0);
+ ::std::get<k>(args), p0);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2219,7 +1728,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1);
+ ::std::get<k>(args), p0, p1);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2228,7 +1737,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2);
+ ::std::get<k>(args), p0, p1, p2);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2237,7 +1746,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3);
+ ::std::get<k>(args), p0, p1, p2, p3);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2246,7 +1755,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3, p4);
+ ::std::get<k>(args), p0, p1, p2, p3, p4);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2255,7 +1764,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3, p4, p5);
+ ::std::get<k>(args), p0, p1, p2, p3, p4, p5);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2264,7 +1773,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6);
+ ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2273,7 +1782,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7);
+ ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2282,7 +1791,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8);
+ ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8);
}
ACTION_TEMPLATE(InvokeArgument,
@@ -2291,7 +1800,7 @@
using internal::invoke_argument::InvokeArgumentAdl;
return InvokeArgumentAdl<return_type>(
internal::invoke_argument::AdlTag(),
- ::testing::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
+ ::std::get<k>(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9);
}
// Various overloads for ReturnNew<T>().
@@ -2371,7 +1880,7 @@
} // namespace testing
-// Include any custom actions added by the local installation.
+// Include any custom callback actions added by the local installation.
// We must include this header at the end to make sure it can use the
// declarations from this file.
#include "gmock/internal/custom/gmock-generated-actions.h"
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-function-mockers.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-function-mockers.h
index feec9857..d131bea 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-function-mockers.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-function-mockers.h
@@ -30,297 +30,78 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements function mockers of various arities.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
+#include <functional>
+#include <utility>
+
#include "gmock/gmock-spec-builders.h"
#include "gmock/internal/gmock-internal-utils.h"
-#if GTEST_HAS_STD_FUNCTION_
-# include <functional>
-#endif
-
namespace testing {
namespace internal {
+// Removes the given pointer; this is a helper for the expectation setter method
+// for parameterless matchers.
+//
+// We want to make sure that the user cannot set a parameterless expectation on
+// overloaded methods, including methods which are overloaded on const. Example:
+//
+// class MockClass {
+// MOCK_METHOD0(GetName, string&());
+// MOCK_CONST_METHOD0(GetName, const string&());
+// };
+//
+// TEST() {
+// // This should be an error, as it's not clear which overload is expected.
+// EXPECT_CALL(mock, GetName).WillOnce(ReturnRef(value));
+// }
+//
+// Here are the generated expectation-setter methods:
+//
+// class MockClass {
+// // Overload 1
+// MockSpec<string&()> gmock_GetName() { ... }
+// // Overload 2. Declared const so that the compiler will generate an
+// // error when trying to resolve between this and overload 4 in
+// // 'gmock_GetName(WithoutMatchers(), nullptr)'.
+// MockSpec<string&()> gmock_GetName(
+// const WithoutMatchers&, const Function<string&()>*) const {
+// // Removes const from this, calls overload 1
+// return AdjustConstness_(this)->gmock_GetName();
+// }
+//
+// // Overload 3
+// const string& gmock_GetName() const { ... }
+// // Overload 4
+// MockSpec<const string&()> gmock_GetName(
+// const WithoutMatchers&, const Function<const string&()>*) const {
+// // Does not remove const, calls overload 3
+// return AdjustConstness_const(this)->gmock_GetName();
+// }
+// }
+//
+template <typename MockType>
+const MockType* AdjustConstness_const(const MockType* mock) {
+ return mock;
+}
-template <typename F>
-class FunctionMockerBase;
-
-// Note: class FunctionMocker really belongs to the ::testing
-// namespace. However if we define it in ::testing, MSVC will
-// complain when classes in ::testing::internal declare it as a
-// friend class template. To workaround this compiler bug, we define
-// FunctionMocker in ::testing::internal and import it into ::testing.
-template <typename F>
-class FunctionMocker;
-
-template <typename R>
-class FunctionMocker<R()> : public
- internal::FunctionMockerBase<R()> {
- public:
- typedef R F();
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With() {
- return this->current_spec();
- }
-
- R Invoke() {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple());
- }
-};
-
-template <typename R, typename A1>
-class FunctionMocker<R(A1)> : public
- internal::FunctionMockerBase<R(A1)> {
- public:
- typedef R F(A1);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1));
- return this->current_spec();
- }
-
- R Invoke(A1 a1) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1));
- }
-};
-
-template <typename R, typename A1, typename A2>
-class FunctionMocker<R(A1, A2)> : public
- internal::FunctionMockerBase<R(A1, A2)> {
- public:
- typedef R F(A1, A2);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3>
-class FunctionMocker<R(A1, A2, A3)> : public
- internal::FunctionMockerBase<R(A1, A2, A3)> {
- public:
- typedef R F(A1, A2, A3);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4>
-class FunctionMocker<R(A1, A2, A3, A4)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4)> {
- public:
- typedef R F(A1, A2, A3, A4);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-class FunctionMocker<R(A1, A2, A3, A4, A5)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4, A5)> {
- public:
- typedef R F(A1, A2, A3, A4, A5);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6)> {
- public:
- typedef R F(A1, A2, A3, A4, A5, A6);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
- const Matcher<A6>& m6) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
- m6));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7)> {
- public:
- typedef R F(A1, A2, A3, A4, A5, A6, A7);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
- const Matcher<A6>& m6, const Matcher<A7>& m7) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
- m6, m7));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
- public:
- typedef R F(A1, A2, A3, A4, A5, A6, A7, A8);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
- const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
- m6, m7, m8));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
- public:
- typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
- const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
- const Matcher<A9>& m9) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
- m6, m7, m8, m9));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9));
- }
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-class FunctionMocker<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : public
- internal::FunctionMockerBase<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> {
- public:
- typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
- typedef typename internal::Function<F>::ArgumentTuple ArgumentTuple;
-
- MockSpec<F>& With(const Matcher<A1>& m1, const Matcher<A2>& m2,
- const Matcher<A3>& m3, const Matcher<A4>& m4, const Matcher<A5>& m5,
- const Matcher<A6>& m6, const Matcher<A7>& m7, const Matcher<A8>& m8,
- const Matcher<A9>& m9, const Matcher<A10>& m10) {
- this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5,
- m6, m7, m8, m9, m10));
- return this->current_spec();
- }
-
- R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9,
- A10 a10) {
- // Even though gcc and MSVC don't enforce it, 'this->' is required
- // by the C++ standard [14.6.4] here, as the base class type is
- // dependent on the template argument (and thus shouldn't be
- // looked into when resolving InvokeWith).
- return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9,
- a10));
- }
-};
+// Removes const from and returns the given pointer; this is a helper for the
+// expectation setter method for parameterless matchers.
+template <typename MockType>
+MockType* AdjustConstness_(const MockType* mock) {
+ return const_cast<MockType*>(mock);
+}
} // namespace internal
@@ -342,7 +123,7 @@
// The type of argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_ARG_(tn, N, ...) \
- tn ::testing::internal::Function<__VA_ARGS__>::Argument##N
+ tn ::testing::internal::Function<__VA_ARGS__>::template Arg<N-1>::type
// The matcher type for argument N of the given function type.
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
@@ -356,78 +137,101 @@
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \
+ static_assert(0 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 0), \
- this_method_does_not_take_0_arguments); \
GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \
return GMOCK_MOCKER_(0, constness, Method).Invoke(); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method() constness { \
GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(0, constness, Method).With(); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \
+ static_assert(1 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 1), \
- this_method_does_not_take_1_argument); \
GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \
+ return GMOCK_MOCKER_(1, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \
GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \
+ static_assert(2 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 2), \
- this_method_does_not_take_2_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \
+ return GMOCK_MOCKER_(2, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \
GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \
return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \
+ static_assert(3 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 3), \
- this_method_does_not_take_3_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, \
+ __VA_ARGS__) gmock_a3) constness { \
GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3); \
+ return GMOCK_MOCKER_(3, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \
@@ -435,25 +239,35 @@
return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \
+ static_assert(4 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 4), \
- this_method_does_not_take_4_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \
GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4); \
+ return GMOCK_MOCKER_(4, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -462,26 +276,38 @@
return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \
+ static_assert(5 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
- GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 5), \
- this_method_does_not_take_5_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+ __VA_ARGS__) gmock_a5) constness { \
GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4, gmock_a5); \
+ return GMOCK_MOCKER_(5, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+ ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -491,27 +317,41 @@
return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \
+ static_assert(6 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
- GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
- GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 6), \
- this_method_does_not_take_6_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+ __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, \
+ __VA_ARGS__) gmock_a6) constness { \
GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
+ return GMOCK_MOCKER_(6, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+ ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+ ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -522,28 +362,43 @@
return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \
+ static_assert(7 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
- GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
- GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
- GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 7), \
- this_method_does_not_take_7_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+ __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \
GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
+ return GMOCK_MOCKER_(7, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+ ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+ ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+ ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -555,29 +410,46 @@
return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \
+ static_assert(8 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
- GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
- GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
- GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
- GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 8), \
- this_method_does_not_take_8_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+ __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
+ __VA_ARGS__) gmock_a8) constness { \
GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
+ return GMOCK_MOCKER_(8, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+ ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+ ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+ ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
+ ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -590,31 +462,49 @@
return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \
+ static_assert(9 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
- GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
- GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
- GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
- GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
- GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 9), \
- this_method_does_not_take_9_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+ __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
+ __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, \
+ __VA_ARGS__) gmock_a9) constness { \
GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
- gmock_a9); \
+ return GMOCK_MOCKER_(9, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+ ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+ ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+ ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
+ ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
+ ::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -629,32 +519,51 @@
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \
gmock_a9); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \
Method)
// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!!
#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \
+ static_assert(10 == \
+ ::testing::internal::Function<__VA_ARGS__>::ArgumentCount, \
+ "MOCK_METHOD<N> must match argument count.");\
GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \
- GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \
- GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \
- GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
- GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \
- GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \
- GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
- GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \
- GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \
- GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
- GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
- GTEST_COMPILE_ASSERT_((::testing::tuple_size< \
- tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \
- == 10), \
- this_method_does_not_take_10_arguments); \
+ GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, GMOCK_ARG_(tn, 2, \
+ __VA_ARGS__) gmock_a2, GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \
+ GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, GMOCK_ARG_(tn, 5, \
+ __VA_ARGS__) gmock_a5, GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \
+ GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, GMOCK_ARG_(tn, 8, \
+ __VA_ARGS__) gmock_a8, GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \
+ GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \
GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \
- return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \
- gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
- gmock_a10); \
+ return GMOCK_MOCKER_(10, constness, \
+ Method).Invoke(::std::forward<GMOCK_ARG_(tn, 1, \
+ __VA_ARGS__)>(gmock_a1), \
+ ::std::forward<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(gmock_a2), \
+ ::std::forward<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(gmock_a3), \
+ ::std::forward<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(gmock_a4), \
+ ::std::forward<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(gmock_a5), \
+ ::std::forward<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(gmock_a6), \
+ ::std::forward<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(gmock_a7), \
+ ::std::forward<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(gmock_a8), \
+ ::std::forward<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(gmock_a9), \
+ ::std::forward<GMOCK_ARG_(tn, 10, __VA_ARGS__)>(gmock_a10)); \
} \
- ::testing::MockSpec<__VA_ARGS__>& \
+ ::testing::MockSpec<__VA_ARGS__> \
gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \
GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \
GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \
@@ -671,6 +580,21 @@
gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \
gmock_a10); \
} \
+ ::testing::MockSpec<__VA_ARGS__> gmock_##Method( \
+ const ::testing::internal::WithoutMatchers&, \
+ constness ::testing::internal::Function<__VA_ARGS__>* ) const { \
+ return ::testing::internal::AdjustConstness_##constness(this)-> \
+ gmock_##Method(::testing::A<GMOCK_ARG_(tn, 1, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 2, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 3, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 4, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 5, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 6, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 7, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 8, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 9, __VA_ARGS__)>(), \
+ ::testing::A<GMOCK_ARG_(tn, 10, __VA_ARGS__)>()); \
+ } \
mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \
Method)
@@ -825,273 +749,6 @@
#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \
GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__)
-// A MockFunction<F> class has one mock method whose type is F. It is
-// useful when you just want your test code to emit some messages and
-// have Google Mock verify the right messages are sent (and perhaps at
-// the right times). For example, if you are exercising code:
-//
-// Foo(1);
-// Foo(2);
-// Foo(3);
-//
-// and want to verify that Foo(1) and Foo(3) both invoke
-// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
-//
-// TEST(FooTest, InvokesBarCorrectly) {
-// MyMock mock;
-// MockFunction<void(string check_point_name)> check;
-// {
-// InSequence s;
-//
-// EXPECT_CALL(mock, Bar("a"));
-// EXPECT_CALL(check, Call("1"));
-// EXPECT_CALL(check, Call("2"));
-// EXPECT_CALL(mock, Bar("a"));
-// }
-// Foo(1);
-// check.Call("1");
-// Foo(2);
-// check.Call("2");
-// Foo(3);
-// }
-//
-// The expectation spec says that the first Bar("a") must happen
-// before check point "1", the second Bar("a") must happen after check
-// point "2", and nothing should happen between the two check
-// points. The explicit check points make it easy to tell which
-// Bar("a") is called by which call to Foo().
-//
-// MockFunction<F> can also be used to exercise code that accepts
-// std::function<F> callbacks. To do so, use AsStdFunction() method
-// to create std::function proxy forwarding to original object's Call.
-// Example:
-//
-// TEST(FooTest, RunsCallbackWithBarArgument) {
-// MockFunction<int(string)> callback;
-// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
-// Foo(callback.AsStdFunction());
-// }
-template <typename F>
-class MockFunction;
-
-template <typename R>
-class MockFunction<R()> {
- public:
- MockFunction() {}
-
- MOCK_METHOD0_T(Call, R());
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R()> AsStdFunction() {
- return [this]() -> R {
- return this->Call();
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0>
-class MockFunction<R(A0)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD1_T(Call, R(A0));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0)> AsStdFunction() {
- return [this](A0 a0) -> R {
- return this->Call(a0);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1>
-class MockFunction<R(A0, A1)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD2_T(Call, R(A0, A1));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1)> AsStdFunction() {
- return [this](A0 a0, A1 a1) -> R {
- return this->Call(a0, a1);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2>
-class MockFunction<R(A0, A1, A2)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD3_T(Call, R(A0, A1, A2));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2) -> R {
- return this->Call(a0, a1, a2);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3>
-class MockFunction<R(A0, A1, A2, A3)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD4_T(Call, R(A0, A1, A2, A3));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R {
- return this->Call(a0, a1, a2, a3);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
- typename A4>
-class MockFunction<R(A0, A1, A2, A3, A4)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3, A4)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R {
- return this->Call(a0, a1, a2, a3, a4);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
- typename A4, typename A5>
-class MockFunction<R(A0, A1, A2, A3, A4, A5)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3, A4, A5)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R {
- return this->Call(a0, a1, a2, a3, a4, a5);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
- typename A4, typename A5, typename A6>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3, A4, A5, A6)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R {
- return this->Call(a0, a1, a2, a3, a4, a5, a6);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
- typename A4, typename A5, typename A6, typename A7>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3, A4, A5, A6, A7)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R {
- return this->Call(a0, a1, a2, a3, a4, a5, a6, a7);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
- typename A4, typename A5, typename A6, typename A7, typename A8>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
- A8 a8) -> R {
- return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
-template <typename R, typename A0, typename A1, typename A2, typename A3,
- typename A4, typename A5, typename A6, typename A7, typename A8,
- typename A9>
-class MockFunction<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
- public:
- MockFunction() {}
-
- MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9));
-
-#if GTEST_HAS_STD_FUNCTION_
- std::function<R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)> AsStdFunction() {
- return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7,
- A8 a8, A9 a9) -> R {
- return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
- };
- }
-#endif // GTEST_HAS_STD_FUNCTION_
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction);
-};
-
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-matchers.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-matchers.h
index d210fd9..48ea935 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-matchers.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-matchers.h
@@ -35,6 +35,8 @@
//
// This file implements some commonly used variadic matchers.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_
@@ -43,1128 +45,10 @@
#include <iterator>
#include <sstream>
#include <string>
+#include <utility>
#include <vector>
#include "gmock/gmock-matchers.h"
-namespace testing {
-namespace internal {
-
-// The type of the i-th (0-based) field of Tuple.
-#define GMOCK_FIELD_TYPE_(Tuple, i) \
- typename ::testing::tuple_element<i, Tuple>::type
-
-// TupleFields<Tuple, k0, ..., kn> is for selecting fields from a
-// tuple of type Tuple. It has two members:
-//
-// type: a tuple type whose i-th field is the ki-th field of Tuple.
-// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple.
-//
-// For example, in class TupleFields<tuple<bool, char, int>, 2, 0>, we have:
-//
-// type is tuple<int, bool>, and
-// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true).
-
-template <class Tuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
- int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
- int k9 = -1>
-class TupleFields;
-
-// This generic version is used when there are 10 selectors.
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
- int k7, int k8, int k9>
-class TupleFields {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
- GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
- GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8),
- GMOCK_FIELD_TYPE_(Tuple, k9)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
- get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t), get<k9>(t));
- }
-};
-
-// The following specialization is used for 0 ~ 9 selectors.
-
-template <class Tuple>
-class TupleFields<Tuple, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<> type;
- static type GetSelectedFields(const Tuple& /* t */) {
- return type();
- }
-};
-
-template <class Tuple, int k0>
-class TupleFields<Tuple, k0, -1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t));
- }
-};
-
-template <class Tuple, int k0, int k1>
-class TupleFields<Tuple, k0, k1, -1, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2>
-class TupleFields<Tuple, k0, k1, k2, -1, -1, -1, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3>
-class TupleFields<Tuple, k0, k1, k2, k3, -1, -1, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, -1, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, -1, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
- GMOCK_FIELD_TYPE_(Tuple, k5)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
- get<k5>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, -1, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
- GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
- get<k5>(t), get<k6>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
- int k7>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, -1, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
- GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
- GMOCK_FIELD_TYPE_(Tuple, k7)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
- get<k5>(t), get<k6>(t), get<k7>(t));
- }
-};
-
-template <class Tuple, int k0, int k1, int k2, int k3, int k4, int k5, int k6,
- int k7, int k8>
-class TupleFields<Tuple, k0, k1, k2, k3, k4, k5, k6, k7, k8, -1> {
- public:
- typedef ::testing::tuple<GMOCK_FIELD_TYPE_(Tuple, k0),
- GMOCK_FIELD_TYPE_(Tuple, k1), GMOCK_FIELD_TYPE_(Tuple, k2),
- GMOCK_FIELD_TYPE_(Tuple, k3), GMOCK_FIELD_TYPE_(Tuple, k4),
- GMOCK_FIELD_TYPE_(Tuple, k5), GMOCK_FIELD_TYPE_(Tuple, k6),
- GMOCK_FIELD_TYPE_(Tuple, k7), GMOCK_FIELD_TYPE_(Tuple, k8)> type;
- static type GetSelectedFields(const Tuple& t) {
- return type(get<k0>(t), get<k1>(t), get<k2>(t), get<k3>(t), get<k4>(t),
- get<k5>(t), get<k6>(t), get<k7>(t), get<k8>(t));
- }
-};
-
-#undef GMOCK_FIELD_TYPE_
-
-// Implements the Args() matcher.
-template <class ArgsTuple, int k0 = -1, int k1 = -1, int k2 = -1, int k3 = -1,
- int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1, int k8 = -1,
- int k9 = -1>
-class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
- public:
- // ArgsTuple may have top-level const or reference modifiers.
- typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple;
- typedef typename internal::TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5,
- k6, k7, k8, k9>::type SelectedArgs;
- typedef Matcher<const SelectedArgs&> MonomorphicInnerMatcher;
-
- template <typename InnerMatcher>
- explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
- : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
-
- virtual bool MatchAndExplain(ArgsTuple args,
- MatchResultListener* listener) const {
- const SelectedArgs& selected_args = GetSelectedArgs(args);
- if (!listener->IsInterested())
- return inner_matcher_.Matches(selected_args);
-
- PrintIndices(listener->stream());
- *listener << "are " << PrintToString(selected_args);
-
- StringMatchResultListener inner_listener;
- const bool match = inner_matcher_.MatchAndExplain(selected_args,
- &inner_listener);
- PrintIfNotEmpty(inner_listener.str(), listener->stream());
- return match;
- }
-
- virtual void DescribeTo(::std::ostream* os) const {
- *os << "are a tuple ";
- PrintIndices(os);
- inner_matcher_.DescribeTo(os);
- }
-
- virtual void DescribeNegationTo(::std::ostream* os) const {
- *os << "are a tuple ";
- PrintIndices(os);
- inner_matcher_.DescribeNegationTo(os);
- }
-
- private:
- static SelectedArgs GetSelectedArgs(ArgsTuple args) {
- return TupleFields<RawArgsTuple, k0, k1, k2, k3, k4, k5, k6, k7, k8,
- k9>::GetSelectedFields(args);
- }
-
- // Prints the indices of the selected fields.
- static void PrintIndices(::std::ostream* os) {
- *os << "whose fields (";
- const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 };
- for (int i = 0; i < 10; i++) {
- if (indices[i] < 0)
- break;
-
- if (i >= 1)
- *os << ", ";
-
- *os << "#" << indices[i];
- }
- *os << ") ";
- }
-
- const MonomorphicInnerMatcher inner_matcher_;
-
- GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl);
-};
-
-template <class InnerMatcher, int k0 = -1, int k1 = -1, int k2 = -1,
- int k3 = -1, int k4 = -1, int k5 = -1, int k6 = -1, int k7 = -1,
- int k8 = -1, int k9 = -1>
-class ArgsMatcher {
- public:
- explicit ArgsMatcher(const InnerMatcher& inner_matcher)
- : inner_matcher_(inner_matcher) {}
-
- template <typename ArgsTuple>
- operator Matcher<ArgsTuple>() const {
- return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k0, k1, k2, k3, k4, k5,
- k6, k7, k8, k9>(inner_matcher_));
- }
-
- private:
- const InnerMatcher inner_matcher_;
-
- GTEST_DISALLOW_ASSIGN_(ArgsMatcher);
-};
-
-// A set of metafunctions for computing the result type of AllOf.
-// AllOf(m1, ..., mN) returns
-// AllOfResultN<decltype(m1), ..., decltype(mN)>::type.
-
-// Although AllOf isn't defined for one argument, AllOfResult1 is defined
-// to simplify the implementation.
-template <typename M1>
-struct AllOfResult1 {
- typedef M1 type;
-};
-
-template <typename M1, typename M2>
-struct AllOfResult2 {
- typedef BothOfMatcher<
- typename AllOfResult1<M1>::type,
- typename AllOfResult1<M2>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3>
-struct AllOfResult3 {
- typedef BothOfMatcher<
- typename AllOfResult1<M1>::type,
- typename AllOfResult2<M2, M3>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4>
-struct AllOfResult4 {
- typedef BothOfMatcher<
- typename AllOfResult2<M1, M2>::type,
- typename AllOfResult2<M3, M4>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-struct AllOfResult5 {
- typedef BothOfMatcher<
- typename AllOfResult2<M1, M2>::type,
- typename AllOfResult3<M3, M4, M5>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6>
-struct AllOfResult6 {
- typedef BothOfMatcher<
- typename AllOfResult3<M1, M2, M3>::type,
- typename AllOfResult3<M4, M5, M6>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7>
-struct AllOfResult7 {
- typedef BothOfMatcher<
- typename AllOfResult3<M1, M2, M3>::type,
- typename AllOfResult4<M4, M5, M6, M7>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8>
-struct AllOfResult8 {
- typedef BothOfMatcher<
- typename AllOfResult4<M1, M2, M3, M4>::type,
- typename AllOfResult4<M5, M6, M7, M8>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9>
-struct AllOfResult9 {
- typedef BothOfMatcher<
- typename AllOfResult4<M1, M2, M3, M4>::type,
- typename AllOfResult5<M5, M6, M7, M8, M9>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9, typename M10>
-struct AllOfResult10 {
- typedef BothOfMatcher<
- typename AllOfResult5<M1, M2, M3, M4, M5>::type,
- typename AllOfResult5<M6, M7, M8, M9, M10>::type
- > type;
-};
-
-// A set of metafunctions for computing the result type of AnyOf.
-// AnyOf(m1, ..., mN) returns
-// AnyOfResultN<decltype(m1), ..., decltype(mN)>::type.
-
-// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined
-// to simplify the implementation.
-template <typename M1>
-struct AnyOfResult1 {
- typedef M1 type;
-};
-
-template <typename M1, typename M2>
-struct AnyOfResult2 {
- typedef EitherOfMatcher<
- typename AnyOfResult1<M1>::type,
- typename AnyOfResult1<M2>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3>
-struct AnyOfResult3 {
- typedef EitherOfMatcher<
- typename AnyOfResult1<M1>::type,
- typename AnyOfResult2<M2, M3>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4>
-struct AnyOfResult4 {
- typedef EitherOfMatcher<
- typename AnyOfResult2<M1, M2>::type,
- typename AnyOfResult2<M3, M4>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-struct AnyOfResult5 {
- typedef EitherOfMatcher<
- typename AnyOfResult2<M1, M2>::type,
- typename AnyOfResult3<M3, M4, M5>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6>
-struct AnyOfResult6 {
- typedef EitherOfMatcher<
- typename AnyOfResult3<M1, M2, M3>::type,
- typename AnyOfResult3<M4, M5, M6>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7>
-struct AnyOfResult7 {
- typedef EitherOfMatcher<
- typename AnyOfResult3<M1, M2, M3>::type,
- typename AnyOfResult4<M4, M5, M6, M7>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8>
-struct AnyOfResult8 {
- typedef EitherOfMatcher<
- typename AnyOfResult4<M1, M2, M3, M4>::type,
- typename AnyOfResult4<M5, M6, M7, M8>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9>
-struct AnyOfResult9 {
- typedef EitherOfMatcher<
- typename AnyOfResult4<M1, M2, M3, M4>::type,
- typename AnyOfResult5<M5, M6, M7, M8, M9>::type
- > type;
-};
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9, typename M10>
-struct AnyOfResult10 {
- typedef EitherOfMatcher<
- typename AnyOfResult5<M1, M2, M3, M4, M5>::type,
- typename AnyOfResult5<M6, M7, M8, M9, M10>::type
- > type;
-};
-
-} // namespace internal
-
-// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
-// fields of it matches a_matcher. C++ doesn't support default
-// arguments for function templates, so we have to overload it.
-template <typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher>(matcher);
-}
-
-template <int k1, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1>(matcher);
-}
-
-template <int k1, int k2, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2>(matcher);
-}
-
-template <int k1, int k2, int k3, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7,
- typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6,
- k7>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
- typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7,
- k8>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
- int k9, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
- k9>(matcher);
-}
-
-template <int k1, int k2, int k3, int k4, int k5, int k6, int k7, int k8,
- int k9, int k10, typename InnerMatcher>
-inline internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8, k9,
- k10>
-Args(const InnerMatcher& matcher) {
- return internal::ArgsMatcher<InnerMatcher, k1, k2, k3, k4, k5, k6, k7, k8,
- k9, k10>(matcher);
-}
-
-// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with
-// n elements, where the i-th element in the container must
-// match the i-th argument in the list. Each argument of
-// ElementsAre() can be either a value or a matcher. We support up to
-// 10 arguments.
-//
-// The use of DecayArray in the implementation allows ElementsAre()
-// to accept string literals, whose type is const char[N], but we
-// want to treat them as const char*.
-//
-// NOTE: Since ElementsAre() cares about the order of the elements, it
-// must not be used with containers whose elements's order is
-// undefined (e.g. hash_map).
-
-inline internal::ElementsAreMatcher<
- ::testing::tuple<> >
-ElementsAre() {
- typedef ::testing::tuple<> Args;
- return internal::ElementsAreMatcher<Args>(Args());
-}
-
-template <typename T1>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type> >
-ElementsAre(const T1& e1) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1));
-}
-
-template <typename T1, typename T2>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type> >
-ElementsAre(const T1& e1, const T2& e2) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2));
-}
-
-template <typename T1, typename T2, typename T3>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3));
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7,
- e8));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7,
- e8, e9));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-inline internal::ElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type,
- typename internal::DecayArray<T10>::type> >
-ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
- const T10& e10) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type,
- typename internal::DecayArray<T10>::type> Args;
- return internal::ElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5, e6, e7,
- e8, e9, e10));
-}
-
-// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension
-// that matches n elements in any order. We support up to n=10 arguments.
-
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<> >
-UnorderedElementsAre() {
- typedef ::testing::tuple<> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args());
-}
-
-template <typename T1>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type> >
-UnorderedElementsAre(const T1& e1) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1));
-}
-
-template <typename T1, typename T2>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2));
-}
-
-template <typename T1, typename T2, typename T3>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3));
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
- e6));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
- e6, e7));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7, const T8& e8) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
- e6, e7, e8));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
- e6, e7, e8, e9));
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-inline internal::UnorderedElementsAreMatcher<
- ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type,
- typename internal::DecayArray<T10>::type> >
-UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4,
- const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9,
- const T10& e10) {
- typedef ::testing::tuple<
- typename internal::DecayArray<T1>::type,
- typename internal::DecayArray<T2>::type,
- typename internal::DecayArray<T3>::type,
- typename internal::DecayArray<T4>::type,
- typename internal::DecayArray<T5>::type,
- typename internal::DecayArray<T6>::type,
- typename internal::DecayArray<T7>::type,
- typename internal::DecayArray<T8>::type,
- typename internal::DecayArray<T9>::type,
- typename internal::DecayArray<T10>::type> Args;
- return internal::UnorderedElementsAreMatcher<Args>(Args(e1, e2, e3, e4, e5,
- e6, e7, e8, e9, e10));
-}
-
-// AllOf(m1, m2, ..., mk) matches any value that matches all of the given
-// sub-matchers. AllOf is called fully qualified to prevent ADL from firing.
-
-template <typename M1, typename M2>
-inline typename internal::AllOfResult2<M1, M2>::type
-AllOf(M1 m1, M2 m2) {
- return typename internal::AllOfResult2<M1, M2>::type(
- m1,
- m2);
-}
-
-template <typename M1, typename M2, typename M3>
-inline typename internal::AllOfResult3<M1, M2, M3>::type
-AllOf(M1 m1, M2 m2, M3 m3) {
- return typename internal::AllOfResult3<M1, M2, M3>::type(
- m1,
- ::testing::AllOf(m2, m3));
-}
-
-template <typename M1, typename M2, typename M3, typename M4>
-inline typename internal::AllOfResult4<M1, M2, M3, M4>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4) {
- return typename internal::AllOfResult4<M1, M2, M3, M4>::type(
- ::testing::AllOf(m1, m2),
- ::testing::AllOf(m3, m4));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-inline typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) {
- return typename internal::AllOfResult5<M1, M2, M3, M4, M5>::type(
- ::testing::AllOf(m1, m2),
- ::testing::AllOf(m3, m4, m5));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6>
-inline typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) {
- return typename internal::AllOfResult6<M1, M2, M3, M4, M5, M6>::type(
- ::testing::AllOf(m1, m2, m3),
- ::testing::AllOf(m4, m5, m6));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7>
-inline typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) {
- return typename internal::AllOfResult7<M1, M2, M3, M4, M5, M6, M7>::type(
- ::testing::AllOf(m1, m2, m3),
- ::testing::AllOf(m4, m5, m6, m7));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8>
-inline typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) {
- return typename internal::AllOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type(
- ::testing::AllOf(m1, m2, m3, m4),
- ::testing::AllOf(m5, m6, m7, m8));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9>
-inline typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) {
- return typename internal::AllOfResult9<M1, M2, M3, M4, M5, M6, M7, M8,
- M9>::type(
- ::testing::AllOf(m1, m2, m3, m4),
- ::testing::AllOf(m5, m6, m7, m8, m9));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9, typename M10>
-inline typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
- M10>::type
-AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
- return typename internal::AllOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
- M10>::type(
- ::testing::AllOf(m1, m2, m3, m4, m5),
- ::testing::AllOf(m6, m7, m8, m9, m10));
-}
-
-// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given
-// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing.
-
-template <typename M1, typename M2>
-inline typename internal::AnyOfResult2<M1, M2>::type
-AnyOf(M1 m1, M2 m2) {
- return typename internal::AnyOfResult2<M1, M2>::type(
- m1,
- m2);
-}
-
-template <typename M1, typename M2, typename M3>
-inline typename internal::AnyOfResult3<M1, M2, M3>::type
-AnyOf(M1 m1, M2 m2, M3 m3) {
- return typename internal::AnyOfResult3<M1, M2, M3>::type(
- m1,
- ::testing::AnyOf(m2, m3));
-}
-
-template <typename M1, typename M2, typename M3, typename M4>
-inline typename internal::AnyOfResult4<M1, M2, M3, M4>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4) {
- return typename internal::AnyOfResult4<M1, M2, M3, M4>::type(
- ::testing::AnyOf(m1, m2),
- ::testing::AnyOf(m3, m4));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5>
-inline typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) {
- return typename internal::AnyOfResult5<M1, M2, M3, M4, M5>::type(
- ::testing::AnyOf(m1, m2),
- ::testing::AnyOf(m3, m4, m5));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6>
-inline typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) {
- return typename internal::AnyOfResult6<M1, M2, M3, M4, M5, M6>::type(
- ::testing::AnyOf(m1, m2, m3),
- ::testing::AnyOf(m4, m5, m6));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7>
-inline typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) {
- return typename internal::AnyOfResult7<M1, M2, M3, M4, M5, M6, M7>::type(
- ::testing::AnyOf(m1, m2, m3),
- ::testing::AnyOf(m4, m5, m6, m7));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8>
-inline typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) {
- return typename internal::AnyOfResult8<M1, M2, M3, M4, M5, M6, M7, M8>::type(
- ::testing::AnyOf(m1, m2, m3, m4),
- ::testing::AnyOf(m5, m6, m7, m8));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9>
-inline typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8, M9>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) {
- return typename internal::AnyOfResult9<M1, M2, M3, M4, M5, M6, M7, M8,
- M9>::type(
- ::testing::AnyOf(m1, m2, m3, m4),
- ::testing::AnyOf(m5, m6, m7, m8, m9));
-}
-
-template <typename M1, typename M2, typename M3, typename M4, typename M5,
- typename M6, typename M7, typename M8, typename M9, typename M10>
-inline typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
- M10>::type
-AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) {
- return typename internal::AnyOfResult10<M1, M2, M3, M4, M5, M6, M7, M8, M9,
- M10>::type(
- ::testing::AnyOf(m1, m2, m3, m4, m5),
- ::testing::AnyOf(m6, m7, m8, m9, m10));
-}
-
-} // namespace testing
-
-
// The MATCHER* family of macros can be used in a namespace scope to
// define custom matchers easily.
//
@@ -1270,7 +154,7 @@
// using testing::PrintToString;
//
// MATCHER_P2(InClosedRange, low, hi,
-// string(negation ? "is not" : "is") + " in range [" +
+// std::string(negation ? "is not" : "is") + " in range [" +
// PrintToString(low) + ", " + PrintToString(hi) + "]") {
// return low <= arg && arg <= hi;
// }
@@ -1368,28 +252,28 @@
// overloading matchers based on parameter types (as opposed to just
// based on the number of parameters).
//
-// MATCHER*() can only be used in a namespace scope. The reason is
-// that C++ doesn't yet allow function-local types to be used to
-// instantiate templates. The up-coming C++0x standard will fix this.
-// Once that's done, we'll consider supporting using MATCHER*() inside
-// a function.
+// MATCHER*() can only be used in a namespace scope as templates cannot be
+// declared inside of a local class.
//
// More Information
// ================
//
// To learn more about using these macros, please search for 'MATCHER'
-// on http://code.google.com/p/googlemock/wiki/CookBook.
+// on
+// https://github.com/google/googletest/blob/master/googlemock/docs/cook_book.md
#define MATCHER(name, description)\
class name##Matcher {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl()\
{}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
@@ -1397,16 +281,16 @@
*gmock_os << FormatDescription(true);\
}\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<>()));\
+ ::std::tuple<>()));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1416,14 +300,13 @@
name##Matcher() {\
}\
private:\
- GTEST_DISALLOW_ASSIGN_(name##Matcher);\
};\
inline name##Matcher name() {\
return name##Matcher();\
}\
template <typename arg_type>\
bool name##Matcher::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1432,41 +315,42 @@
class name##MatcherP {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
explicit gmock_Impl(p0##_type gmock_p0)\
- : p0(gmock_p0) {}\
+ : p0(::std::move(gmock_p0)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
+ p0##_type const p0;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type>(p0)));\
+ ::std::tuple<p0##_type>(p0)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
new gmock_Impl<arg_type>(p0));\
}\
- explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\
+ explicit name##MatcherP(p0##_type gmock_p0) : p0(::std::move(gmock_p0)) {\
}\
- p0##_type p0;\
+ p0##_type const p0;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP);\
};\
template <typename p0##_type>\
inline name##MatcherP<p0##_type> name(p0##_type p0) {\
@@ -1475,7 +359,7 @@
template <typename p0##_type>\
template <typename arg_type>\
bool name##MatcherP<p0##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1484,44 +368,46 @@
class name##MatcherP2 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\
- : p0(gmock_p0), p1(gmock_p1) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
+ p0##_type const p0;\
+ p1##_type const p1;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type>(p0, p1)));\
+ ::std::tuple<p0##_type, p1##_type>(p0, p1)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
return ::testing::Matcher<arg_type>(\
new gmock_Impl<arg_type>(p0, p1));\
}\
- name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \
- p1(gmock_p1) {\
+ name##MatcherP2(p0##_type gmock_p0, \
+ p1##_type gmock_p1) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
+ p0##_type const p0;\
+ p1##_type const p1;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP2);\
};\
template <typename p0##_type, typename p1##_type>\
inline name##MatcherP2<p0##_type, p1##_type> name(p0##_type p0, \
@@ -1532,7 +418,7 @@
template <typename arg_type>\
bool name##MatcherP2<p0##_type, \
p1##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1541,33 +427,35 @@
class name##MatcherP3 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, \
- p2)));\
+ ::std::tuple<p0##_type, p1##_type, p2##_type>(p0, p1, p2)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1575,13 +463,13 @@
new gmock_Impl<arg_type>(p0, p1, p2));\
}\
name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\
+ p2##_type gmock_p2) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP3);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type>\
inline name##MatcherP3<p0##_type, p1##_type, p2##_type> name(p0##_type p0, \
@@ -1592,7 +480,7 @@
template <typename arg_type>\
bool name##MatcherP3<p0##_type, p1##_type, \
p2##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1602,35 +490,38 @@
class name##MatcherP4 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, \
- p3##_type>(p0, p1, p2, p3)));\
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type>(p0, \
+ p1, p2, p3)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1638,15 +529,15 @@
new gmock_Impl<arg_type>(p0, p1, p2, p3));\
}\
name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \
- p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3) {\
+ p2##_type gmock_p2, p3##_type gmock_p3) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP4);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type>\
@@ -1661,7 +552,7 @@
template <typename arg_type>\
bool name##MatcherP4<p0##_type, p1##_type, p2##_type, \
p3##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1671,37 +562,40 @@
class name##MatcherP5 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+ p4(::std::move(gmock_p4)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type>(p0, p1, p2, p3, p4)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1710,16 +604,16 @@
}\
name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, \
- p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4) {\
+ p4##_type gmock_p4) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP5);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type>\
@@ -1734,7 +628,7 @@
template <typename arg_type>\
bool name##MatcherP5<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1744,38 +638,41 @@
class name##MatcherP6 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+ p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type>(p0, p1, p2, p3, p4, p5)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1784,17 +681,18 @@
}\
name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\
+ p5##_type gmock_p5) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP6);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type>\
@@ -1809,7 +707,7 @@
template <typename arg_type>\
bool name##MatcherP6<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1820,41 +718,45 @@
class name##MatcherP7 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+ p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+ p6(::std::move(gmock_p6)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type>(p0, p1, p2, p3, p4, p5, \
p6)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1863,19 +765,19 @@
}\
name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
- p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \
- p6(gmock_p6) {\
+ p5##_type gmock_p5, p6##_type gmock_p6) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP7);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -1893,7 +795,7 @@
template <typename arg_type>\
bool name##MatcherP7<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1904,42 +806,46 @@
class name##MatcherP8 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+ p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+ p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
- p7##_type p7;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
+ p7##_type const p7;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type>(p0, p1, p2, \
p3, p4, p5, p6, p7)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -1949,20 +855,21 @@
name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, \
- p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7) {\
+ p7##_type gmock_p7) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+ p7(::std::move(gmock_p7)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
- p7##_type p7;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
+ p7##_type const p7;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP8);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -1982,7 +889,7 @@
bool name##MatcherP8<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, \
p7##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -1993,44 +900,48 @@
class name##MatcherP9 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+ p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+ p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \
+ p8(::std::move(gmock_p8)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
- p7##_type p7;\
- p8##_type p8;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
+ p7##_type const p7;\
+ p8##_type const p8;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, \
p8##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -2040,21 +951,22 @@
name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \
- p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8) {\
+ p8##_type gmock_p8) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+ p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
- p7##_type p7;\
- p8##_type p8;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
+ p7##_type const p7;\
+ p8##_type const p8;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP9);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -2075,7 +987,7 @@
bool name##MatcherP9<p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \
p5##_type, p6##_type, p7##_type, \
p8##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
@@ -2087,46 +999,50 @@
class name##MatcherP10 {\
public:\
template <typename arg_type>\
- class gmock_Impl : public ::testing::MatcherInterface<arg_type> {\
+ class gmock_Impl : public ::testing::MatcherInterface<\
+ GTEST_REFERENCE_TO_CONST_(arg_type)> {\
public:\
gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \
p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \
p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \
p9##_type gmock_p9)\
- : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \
- p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \
- p8(gmock_p8), p9(gmock_p9) {}\
+ : p0(::std::move(gmock_p0)), p1(::std::move(gmock_p1)), \
+ p2(::std::move(gmock_p2)), p3(::std::move(gmock_p3)), \
+ p4(::std::move(gmock_p4)), p5(::std::move(gmock_p5)), \
+ p6(::std::move(gmock_p6)), p7(::std::move(gmock_p7)), \
+ p8(::std::move(gmock_p8)), p9(::std::move(gmock_p9)) {}\
virtual bool MatchAndExplain(\
- arg_type arg, ::testing::MatchResultListener* result_listener) const;\
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
+ ::testing::MatchResultListener* result_listener) const;\
virtual void DescribeTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(false);\
}\
virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\
*gmock_os << FormatDescription(true);\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
- p7##_type p7;\
- p8##_type p8;\
- p9##_type p9;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
+ p7##_type const p7;\
+ p8##_type const p8;\
+ p9##_type const p9;\
private:\
- ::testing::internal::string FormatDescription(bool negation) const {\
- const ::testing::internal::string gmock_description = (description);\
- if (!gmock_description.empty())\
+ ::std::string FormatDescription(bool negation) const {\
+ ::std::string gmock_description = (description);\
+ if (!gmock_description.empty()) {\
return gmock_description;\
+ }\
return ::testing::internal::FormatMatcherDescription(\
negation, #name, \
::testing::internal::UniversalTersePrintTupleFieldsToStrings(\
- ::testing::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
+ ::std::tuple<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
p9##_type>(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\
}\
- GTEST_DISALLOW_ASSIGN_(gmock_Impl);\
};\
template <typename arg_type>\
operator ::testing::Matcher<arg_type>() const {\
@@ -2136,22 +1052,24 @@
name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \
p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \
p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \
- p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \
- p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \
- p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\
+ p8##_type gmock_p8, p9##_type gmock_p9) : p0(::std::move(gmock_p0)), \
+ p1(::std::move(gmock_p1)), p2(::std::move(gmock_p2)), \
+ p3(::std::move(gmock_p3)), p4(::std::move(gmock_p4)), \
+ p5(::std::move(gmock_p5)), p6(::std::move(gmock_p6)), \
+ p7(::std::move(gmock_p7)), p8(::std::move(gmock_p8)), \
+ p9(::std::move(gmock_p9)) {\
}\
- p0##_type p0;\
- p1##_type p1;\
- p2##_type p2;\
- p3##_type p3;\
- p4##_type p4;\
- p5##_type p5;\
- p6##_type p6;\
- p7##_type p7;\
- p8##_type p8;\
- p9##_type p9;\
+ p0##_type const p0;\
+ p1##_type const p1;\
+ p2##_type const p2;\
+ p3##_type const p3;\
+ p4##_type const p4;\
+ p5##_type const p5;\
+ p6##_type const p6;\
+ p7##_type const p7;\
+ p8##_type const p8;\
+ p9##_type const p9;\
private:\
- GTEST_DISALLOW_ASSIGN_(name##MatcherP10);\
};\
template <typename p0##_type, typename p1##_type, typename p2##_type, \
typename p3##_type, typename p4##_type, typename p5##_type, \
@@ -2174,7 +1092,7 @@
bool name##MatcherP10<p0##_type, p1##_type, p2##_type, p3##_type, \
p4##_type, p5##_type, p6##_type, p7##_type, p8##_type, \
p9##_type>::gmock_Impl<arg_type>::MatchAndExplain(\
- arg_type arg, \
+ GTEST_REFERENCE_TO_CONST_(arg_type) arg,\
::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\
const
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-nice-strict.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-nice-strict.h
deleted file mode 100644
index 9a5c15f..0000000
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-generated-nice-strict.h
+++ /dev/null
@@ -1,399 +0,0 @@
-// This file was GENERATED by command:
-// pump.py gmock-generated-nice-strict.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
-
-// Implements class templates NiceMock, NaggyMock, and StrictMock.
-//
-// Given a mock class MockFoo that is created using Google Mock,
-// NiceMock<MockFoo> is a subclass of MockFoo that allows
-// uninteresting calls (i.e. calls to mock methods that have no
-// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
-// that prints a warning when an uninteresting call occurs, and
-// StrictMock<MockFoo> is a subclass of MockFoo that treats all
-// uninteresting calls as errors.
-//
-// Currently a mock is naggy by default, so MockFoo and
-// NaggyMock<MockFoo> behave like the same. However, we will soon
-// switch the default behavior of mocks to be nice, as that in general
-// leads to more maintainable tests. When that happens, MockFoo will
-// stop behaving like NaggyMock<MockFoo> and start behaving like
-// NiceMock<MockFoo>.
-//
-// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
-// their respective base class, with up-to 10 arguments. Therefore
-// you can write NiceMock<MockFoo>(5, "a") to construct a nice mock
-// where MockFoo has a constructor that accepts (int, const char*),
-// for example.
-//
-// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
-// and StrictMock<MockFoo> only works for mock methods defined using
-// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
-// If a mock method is defined in a base class of MockFoo, the "nice"
-// or "strict" modifier may not affect it, depending on the compiler.
-// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
-// supported.
-//
-// Another known limitation is that the constructors of the base mock
-// cannot have arguments passed by non-const reference, which are
-// banned by the Google C++ style guide anyway.
-
-// IWYU pragma: private, include "gmock/gmock.h"
-
-#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
-
-#include "gmock/gmock-spec-builders.h"
-#include "gmock/internal/gmock-port.h"
-
-namespace testing {
-
-template <class MockClass>
-class NiceMock : public MockClass {
- public:
- // We don't factor out the constructor body to a common method, as
- // we have to avoid a possible clash with members of MockClass.
- NiceMock() {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- // C++ doesn't (yet) allow inheritance of constructors, so we have
- // to define it for each arity.
- template <typename A1>
- explicit NiceMock(const A1& a1) : MockClass(a1) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
- template <typename A1, typename A2>
- NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3>
- NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4>
- NiceMock(const A1& a1, const A2& a2, const A3& a3,
- const A4& a4) : MockClass(a1, a2, a3, a4) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5>
- NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6>
- NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7>
- NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
- a6, a7) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8>
- NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
- a2, a3, a4, a5, a6, a7, a8) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9>
- NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8,
- const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9, typename A10>
- NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
- const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
- ::testing::Mock::AllowUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- virtual ~NiceMock() {
- ::testing::Mock::UnregisterCallReaction(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
-};
-
-template <class MockClass>
-class NaggyMock : public MockClass {
- public:
- // We don't factor out the constructor body to a common method, as
- // we have to avoid a possible clash with members of MockClass.
- NaggyMock() {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- // C++ doesn't (yet) allow inheritance of constructors, so we have
- // to define it for each arity.
- template <typename A1>
- explicit NaggyMock(const A1& a1) : MockClass(a1) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
- template <typename A1, typename A2>
- NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3,
- const A4& a4) : MockClass(a1, a2, a3, a4) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
- a6, a7) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
- a2, a3, a4, a5, a6, a7, a8) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8,
- const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9, typename A10>
- NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
- const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
- ::testing::Mock::WarnUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- virtual ~NaggyMock() {
- ::testing::Mock::UnregisterCallReaction(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
-};
-
-template <class MockClass>
-class StrictMock : public MockClass {
- public:
- // We don't factor out the constructor body to a common method, as
- // we have to avoid a possible clash with members of MockClass.
- StrictMock() {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- // C++ doesn't (yet) allow inheritance of constructors, so we have
- // to define it for each arity.
- template <typename A1>
- explicit StrictMock(const A1& a1) : MockClass(a1) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
- template <typename A1, typename A2>
- StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3>
- StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4>
- StrictMock(const A1& a1, const A2& a2, const A3& a3,
- const A4& a4) : MockClass(a1, a2, a3, a4) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5>
- StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5) : MockClass(a1, a2, a3, a4, a5) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6>
- StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7>
- StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5,
- a6, a7) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8>
- StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1,
- a2, a3, a4, a5, a6, a7, a8) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9>
- StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8,
- const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9, typename A10>
- StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4,
- const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9,
- const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) {
- ::testing::Mock::FailUninterestingCalls(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- virtual ~StrictMock() {
- ::testing::Mock::UnregisterCallReaction(
- internal::ImplicitCast_<MockClass*>(this));
- }
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
-};
-
-// The following specializations catch some (relatively more common)
-// user errors of nesting nice and strict mocks. They do NOT catch
-// all possible errors.
-
-// These specializations are declared but not defined, as NiceMock,
-// NaggyMock, and StrictMock cannot be nested.
-
-template <typename MockClass>
-class NiceMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class NiceMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class NiceMock<StrictMock<MockClass> >;
-
-template <typename MockClass>
-class NaggyMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class NaggyMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class NaggyMock<StrictMock<MockClass> >;
-
-template <typename MockClass>
-class StrictMock<NiceMock<MockClass> >;
-template <typename MockClass>
-class StrictMock<NaggyMock<MockClass> >;
-template <typename MockClass>
-class StrictMock<StrictMock<MockClass> >;
-
-} // namespace testing
-
-#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-matchers.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-matchers.h
index 755dbb9..8c604cf 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-matchers.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-matchers.h
@@ -26,14 +26,18 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some commonly used argument matchers. More
// matchers can be defined by the user implementing the
// MatcherInterface<T> interface if necessary.
+//
+// See googletest/include/gtest/gtest-matchers.h for the definition of class
+// Matcher, class MatcherInterface, and others.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
// IWYU pragma: private, include "gmock/gmock.h"
@@ -42,20 +46,37 @@
#include <math.h>
#include <algorithm>
+#include <initializer_list>
#include <iterator>
#include <limits>
+#include <memory>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
+#include <type_traits>
#include <utility>
#include <vector>
-
#include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
-#if GTEST_HAS_STD_INITIALIZER_LIST_
-# include <initializer_list> // NOLINT -- must be after gtest.h
+// MSVC warning C5046 is new as of VS2017 version 15.8.
+#if defined(_MSC_VER) && _MSC_VER >= 1915
+#define GMOCK_MAYBE_5046_ 5046
+#else
+#define GMOCK_MAYBE_5046_
+#endif
+
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(
+ 4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by
+ clients of class B */
+ /* Symbol involving type with internal linkage not defined */)
+
+#ifdef __clang__
+#if __has_warning("-Wdeprecated-copy")
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-copy"
+#endif
#endif
namespace testing {
@@ -72,123 +93,13 @@
// ownership management as Matcher objects can now be copied like
// plain values.
-// MatchResultListener is an abstract class. Its << operator can be
-// used by a matcher to explain why a value matches or doesn't match.
-//
-// TODO([email protected]): add method
-// bool InterestedInWhy(bool result) const;
-// to indicate whether the listener is interested in why the match
-// result is 'result'.
-class MatchResultListener {
- public:
- // Creates a listener object with the given underlying ostream. The
- // listener does not own the ostream, and does not dereference it
- // in the constructor or destructor.
- explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
- virtual ~MatchResultListener() = 0; // Makes this class abstract.
-
- // Streams x to the underlying ostream; does nothing if the ostream
- // is NULL.
- template <typename T>
- MatchResultListener& operator<<(const T& x) {
- if (stream_ != NULL)
- *stream_ << x;
- return *this;
- }
-
- // Returns the underlying ostream.
- ::std::ostream* stream() { return stream_; }
-
- // Returns true iff the listener is interested in an explanation of
- // the match result. A matcher's MatchAndExplain() method can use
- // this information to avoid generating the explanation when no one
- // intends to hear it.
- bool IsInterested() const { return stream_ != NULL; }
-
- private:
- ::std::ostream* const stream_;
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
-};
-
-inline MatchResultListener::~MatchResultListener() {
-}
-
-// An instance of a subclass of this knows how to describe itself as a
-// matcher.
-class MatcherDescriberInterface {
- public:
- virtual ~MatcherDescriberInterface() {}
-
- // Describes this matcher to an ostream. The function should print
- // a verb phrase that describes the property a value matching this
- // matcher should have. The subject of the verb phrase is the value
- // being matched. For example, the DescribeTo() method of the Gt(7)
- // matcher prints "is greater than 7".
- virtual void DescribeTo(::std::ostream* os) const = 0;
-
- // Describes the negation of this matcher to an ostream. For
- // example, if the description of this matcher is "is greater than
- // 7", the negated description could be "is not greater than 7".
- // You are not required to override this when implementing
- // MatcherInterface, but it is highly advised so that your matcher
- // can produce good error messages.
- virtual void DescribeNegationTo(::std::ostream* os) const {
- *os << "not (";
- DescribeTo(os);
- *os << ")";
- }
-};
-
-// The implementation of a matcher.
-template <typename T>
-class MatcherInterface : public MatcherDescriberInterface {
- public:
- // Returns true iff the matcher matches x; also explains the match
- // result to 'listener' if necessary (see the next paragraph), in
- // the form of a non-restrictive relative clause ("which ...",
- // "whose ...", etc) that describes x. For example, the
- // MatchAndExplain() method of the Pointee(...) matcher should
- // generate an explanation like "which points to ...".
- //
- // Implementations of MatchAndExplain() should add an explanation of
- // the match result *if and only if* they can provide additional
- // information that's not already present (or not obvious) in the
- // print-out of x and the matcher's description. Whether the match
- // succeeds is not a factor in deciding whether an explanation is
- // needed, as sometimes the caller needs to print a failure message
- // when the match succeeds (e.g. when the matcher is used inside
- // Not()).
- //
- // For example, a "has at least 10 elements" matcher should explain
- // what the actual element count is, regardless of the match result,
- // as it is useful information to the reader; on the other hand, an
- // "is empty" matcher probably only needs to explain what the actual
- // size is when the match fails, as it's redundant to say that the
- // size is 0 when the value is already known to be empty.
- //
- // You should override this method when defining a new matcher.
- //
- // It's the responsibility of the caller (Google Mock) to guarantee
- // that 'listener' is not NULL. This helps to simplify a matcher's
- // implementation when it doesn't care about the performance, as it
- // can talk to 'listener' without checking its validity first.
- // However, in order to implement dummy listeners efficiently,
- // listener->stream() may be NULL.
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
-
- // Inherits these methods from MatcherDescriberInterface:
- // virtual void DescribeTo(::std::ostream* os) const = 0;
- // virtual void DescribeNegationTo(::std::ostream* os) const;
-};
-
// A match result listener that stores the explanation in a string.
class StringMatchResultListener : public MatchResultListener {
public:
StringMatchResultListener() : MatchResultListener(&ss_) {}
// Returns the explanation accumulated so far.
- internal::string str() const { return ss_.str(); }
+ std::string str() const { return ss_.str(); }
// Clears the explanation accumulated so far.
void Clear() { ss_.str(""); }
@@ -199,306 +110,6 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener);
};
-namespace internal {
-
-struct AnyEq {
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const { return a == b; }
-};
-struct AnyNe {
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const { return a != b; }
-};
-struct AnyLt {
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const { return a < b; }
-};
-struct AnyGt {
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const { return a > b; }
-};
-struct AnyLe {
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const { return a <= b; }
-};
-struct AnyGe {
- template <typename A, typename B>
- bool operator()(const A& a, const B& b) const { return a >= b; }
-};
-
-// A match result listener that ignores the explanation.
-class DummyMatchResultListener : public MatchResultListener {
- public:
- DummyMatchResultListener() : MatchResultListener(NULL) {}
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
-};
-
-// A match result listener that forwards the explanation to a given
-// ostream. The difference between this and MatchResultListener is
-// that the former is concrete.
-class StreamMatchResultListener : public MatchResultListener {
- public:
- explicit StreamMatchResultListener(::std::ostream* os)
- : MatchResultListener(os) {}
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
-};
-
-// An internal class for implementing Matcher<T>, which will derive
-// from it. We put functionalities common to all Matcher<T>
-// specializations here to avoid code duplication.
-template <typename T>
-class MatcherBase {
- public:
- // Returns true iff the matcher matches x; also explains the match
- // result to 'listener'.
- bool MatchAndExplain(T x, MatchResultListener* listener) const {
- return impl_->MatchAndExplain(x, listener);
- }
-
- // Returns true iff this matcher matches x.
- bool Matches(T x) const {
- DummyMatchResultListener dummy;
- return MatchAndExplain(x, &dummy);
- }
-
- // Describes this matcher to an ostream.
- void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
-
- // Describes the negation of this matcher to an ostream.
- void DescribeNegationTo(::std::ostream* os) const {
- impl_->DescribeNegationTo(os);
- }
-
- // Explains why x matches, or doesn't match, the matcher.
- void ExplainMatchResultTo(T x, ::std::ostream* os) const {
- StreamMatchResultListener listener(os);
- MatchAndExplain(x, &listener);
- }
-
- // Returns the describer for this matcher object; retains ownership
- // of the describer, which is only guaranteed to be alive when
- // this matcher object is alive.
- const MatcherDescriberInterface* GetDescriber() const {
- return impl_.get();
- }
-
- protected:
- MatcherBase() {}
-
- // Constructs a matcher from its implementation.
- explicit MatcherBase(const MatcherInterface<T>* impl)
- : impl_(impl) {}
-
- virtual ~MatcherBase() {}
-
- private:
- // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar
- // interfaces. The former dynamically allocates a chunk of memory
- // to hold the reference count, while the latter tracks all
- // references using a circular linked list without allocating
- // memory. It has been observed that linked_ptr performs better in
- // typical scenarios. However, shared_ptr can out-perform
- // linked_ptr when there are many more uses of the copy constructor
- // than the default constructor.
- //
- // If performance becomes a problem, we should see if using
- // shared_ptr helps.
- ::testing::internal::linked_ptr<const MatcherInterface<T> > impl_;
-};
-
-} // namespace internal
-
-// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
-// object that can check whether a value of type T matches. The
-// implementation of Matcher<T> is just a linked_ptr to const
-// MatcherInterface<T>, so copying is fairly cheap. Don't inherit
-// from Matcher!
-template <typename T>
-class Matcher : public internal::MatcherBase<T> {
- public:
- // Constructs a null matcher. Needed for storing Matcher objects in STL
- // containers. A default-constructed matcher is not yet initialized. You
- // cannot use it until a valid value has been assigned to it.
- explicit Matcher() {} // NOLINT
-
- // Constructs a matcher from its implementation.
- explicit Matcher(const MatcherInterface<T>* impl)
- : internal::MatcherBase<T>(impl) {}
-
- // Implicit constructor here allows people to write
- // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
- Matcher(T value); // NOLINT
-};
-
-// The following two specializations allow the user to write str
-// instead of Eq(str) and "foo" instead of Eq("foo") when a string
-// matcher is expected.
-template <>
-class GTEST_API_ Matcher<const internal::string&>
- : public internal::MatcherBase<const internal::string&> {
- public:
- Matcher() {}
-
- explicit Matcher(const MatcherInterface<const internal::string&>* impl)
- : internal::MatcherBase<const internal::string&>(impl) {}
-
- // Allows the user to write str instead of Eq(str) sometimes, where
- // str is a string object.
- Matcher(const internal::string& s); // NOLINT
-
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
- Matcher(const char* s); // NOLINT
-};
-
-template <>
-class GTEST_API_ Matcher<internal::string>
- : public internal::MatcherBase<internal::string> {
- public:
- Matcher() {}
-
- explicit Matcher(const MatcherInterface<internal::string>* impl)
- : internal::MatcherBase<internal::string>(impl) {}
-
- // Allows the user to write str instead of Eq(str) sometimes, where
- // str is a string object.
- Matcher(const internal::string& s); // NOLINT
-
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
- Matcher(const char* s); // NOLINT
-};
-
-#if GTEST_HAS_STRING_PIECE_
-// The following two specializations allow the user to write str
-// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece
-// matcher is expected.
-template <>
-class GTEST_API_ Matcher<const StringPiece&>
- : public internal::MatcherBase<const StringPiece&> {
- public:
- Matcher() {}
-
- explicit Matcher(const MatcherInterface<const StringPiece&>* impl)
- : internal::MatcherBase<const StringPiece&>(impl) {}
-
- // Allows the user to write str instead of Eq(str) sometimes, where
- // str is a string object.
- Matcher(const internal::string& s); // NOLINT
-
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
- Matcher(const char* s); // NOLINT
-
- // Allows the user to pass StringPieces directly.
- Matcher(StringPiece s); // NOLINT
-};
-
-template <>
-class GTEST_API_ Matcher<StringPiece>
- : public internal::MatcherBase<StringPiece> {
- public:
- Matcher() {}
-
- explicit Matcher(const MatcherInterface<StringPiece>* impl)
- : internal::MatcherBase<StringPiece>(impl) {}
-
- // Allows the user to write str instead of Eq(str) sometimes, where
- // str is a string object.
- Matcher(const internal::string& s); // NOLINT
-
- // Allows the user to write "foo" instead of Eq("foo") sometimes.
- Matcher(const char* s); // NOLINT
-
- // Allows the user to pass StringPieces directly.
- Matcher(StringPiece s); // NOLINT
-};
-#endif // GTEST_HAS_STRING_PIECE_
-
-// The PolymorphicMatcher class template makes it easy to implement a
-// polymorphic matcher (i.e. a matcher that can match values of more
-// than one type, e.g. Eq(n) and NotNull()).
-//
-// To define a polymorphic matcher, a user should provide an Impl
-// class that has a DescribeTo() method and a DescribeNegationTo()
-// method, and define a member function (or member function template)
-//
-// bool MatchAndExplain(const Value& value,
-// MatchResultListener* listener) const;
-//
-// See the definition of NotNull() for a complete example.
-template <class Impl>
-class PolymorphicMatcher {
- public:
- explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
-
- // Returns a mutable reference to the underlying matcher
- // implementation object.
- Impl& mutable_impl() { return impl_; }
-
- // Returns an immutable reference to the underlying matcher
- // implementation object.
- const Impl& impl() const { return impl_; }
-
- template <typename T>
- operator Matcher<T>() const {
- return Matcher<T>(new MonomorphicImpl<T>(impl_));
- }
-
- private:
- template <typename T>
- class MonomorphicImpl : public MatcherInterface<T> {
- public:
- explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
-
- virtual void DescribeTo(::std::ostream* os) const {
- impl_.DescribeTo(os);
- }
-
- virtual void DescribeNegationTo(::std::ostream* os) const {
- impl_.DescribeNegationTo(os);
- }
-
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
- return impl_.MatchAndExplain(x, listener);
- }
-
- private:
- const Impl impl_;
-
- GTEST_DISALLOW_ASSIGN_(MonomorphicImpl);
- };
-
- Impl impl_;
-
- GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher);
-};
-
-// Creates a matcher from its implementation. This is easier to use
-// than the Matcher<T> constructor as it doesn't require you to
-// explicitly write the template argument, e.g.
-//
-// MakeMatcher(foo);
-// vs
-// Matcher<const string&>(foo);
-template <typename T>
-inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
- return Matcher<T>(impl);
-}
-
-// Creates a polymorphic matcher from its implementation. This is
-// easier to use than the PolymorphicMatcher<Impl> constructor as it
-// doesn't require you to explicitly write the template argument, e.g.
-//
-// MakePolymorphicMatcher(foo);
-// vs
-// PolymorphicMatcher<TypeOfFoo>(foo);
-template <class Impl>
-inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
- return PolymorphicMatcher<Impl>(impl);
-}
-
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
namespace internal {
@@ -517,7 +128,7 @@
class MatcherCastImpl {
public:
static Matcher<T> Cast(const M& polymorphic_matcher_or_value) {
- // M can be a polymorhic matcher, in which case we want to use
+ // M can be a polymorphic matcher, in which case we want to use
// its conversion operator to create Matcher<T>. Or it can be a value
// that should be passed to the Matcher<T>'s constructor.
//
@@ -530,24 +141,18 @@
// polymorphic_matcher_or_value to Matcher<T> because it won't trigger
// a user-defined conversion from M to T if one exists (assuming M is
// a value).
- return CastImpl(
- polymorphic_matcher_or_value,
- BooleanConstant<
- internal::ImplicitlyConvertible<M, Matcher<T> >::value>());
+ return CastImpl(polymorphic_matcher_or_value,
+ std::is_convertible<M, Matcher<T>>{},
+ std::is_convertible<M, T>{});
}
private:
- static Matcher<T> CastImpl(const M& value, BooleanConstant<false>) {
- // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
- // matcher. It must be a value then. Use direct initialization to create
- // a matcher.
- return Matcher<T>(ImplicitCast_<T>(value));
- }
-
+ template <bool Ignore>
static Matcher<T> CastImpl(const M& polymorphic_matcher_or_value,
- BooleanConstant<true>) {
+ std::true_type /* convertible_to_matcher */,
+ bool_constant<Ignore>) {
// M is implicitly convertible to Matcher<T>, which means that either
- // M is a polymorhpic matcher or Matcher<T> has an implicit constructor
+ // M is a polymorphic matcher or Matcher<T> has an implicit constructor
// from M. In both cases using the implicit conversion will produce a
// matcher.
//
@@ -556,6 +161,29 @@
// (first to create T from M and then to create Matcher<T> from T).
return polymorphic_matcher_or_value;
}
+
+ // M can't be implicitly converted to Matcher<T>, so M isn't a polymorphic
+ // matcher. It's a value of a type implicitly convertible to T. Use direct
+ // initialization to create a matcher.
+ static Matcher<T> CastImpl(const M& value,
+ std::false_type /* convertible_to_matcher */,
+ std::true_type /* convertible_to_T */) {
+ return Matcher<T>(ImplicitCast_<T>(value));
+ }
+
+ // M can't be implicitly converted to either Matcher<T> or T. Attempt to use
+ // polymorphic matcher Eq(value) in this case.
+ //
+ // Note that we first attempt to perform an implicit cast on the value and
+ // only fall back to the polymorphic Eq() matcher afterwards because the
+ // latter calls bool operator==(const Lhs& lhs, const Rhs& rhs) in the end
+ // which might be undefined even when Rhs is implicitly convertible to Lhs
+ // (e.g. std::pair<const int, int> vs. std::pair<int, int>).
+ //
+ // We don't define this method inline as we need the declaration of Eq().
+ static Matcher<T> CastImpl(const M& value,
+ std::false_type /* convertible_to_matcher */,
+ std::false_type /* convertible_to_T */);
};
// This more specialized version is used when MatcherCast()'s argument
@@ -575,15 +203,29 @@
: source_matcher_(source_matcher) {}
// We delegate the matching logic to the source matcher.
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+ bool MatchAndExplain(T x, MatchResultListener* listener) const override {
+ using FromType = typename std::remove_cv<typename std::remove_pointer<
+ typename std::remove_reference<T>::type>::type>::type;
+ using ToType = typename std::remove_cv<typename std::remove_pointer<
+ typename std::remove_reference<U>::type>::type>::type;
+ // Do not allow implicitly converting base*/& to derived*/&.
+ static_assert(
+ // Do not trigger if only one of them is a pointer. That implies a
+ // regular conversion and not a down_cast.
+ (std::is_pointer<typename std::remove_reference<T>::type>::value !=
+ std::is_pointer<typename std::remove_reference<U>::type>::value) ||
+ std::is_same<FromType, ToType>::value ||
+ !std::is_base_of<FromType, ToType>::value,
+ "Can't implicitly convert from <base> to <derived>");
+
return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
source_matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
source_matcher_.DescribeNegationTo(os);
}
@@ -615,11 +257,8 @@
// Implements SafeMatcherCast().
//
-// We use an intermediate class to do the actual safe casting as Nokia's
-// Symbian compiler cannot decide between
-// template <T, M> ... (M) and
-// template <T, U> ... (const Matcher<U>&)
-// for function templates but can for member function templates.
+// FIXME: The intermediate SafeMatcherCastImpl class was introduced as a
+// workaround for a compiler bug, and can now be removed.
template <typename T>
class SafeMatcherCastImpl {
public:
@@ -642,13 +281,13 @@
template <typename U>
static inline Matcher<T> Cast(const Matcher<U>& matcher) {
// Enforce that T can be implicitly converted to U.
- GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible<T, U>::value),
- T_must_be_implicitly_convertible_to_U);
+ GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value),
+ "T must be implicitly convertible to U");
// Enforce that we are not converting a non-reference type T to a reference
// type U.
GTEST_COMPILE_ASSERT_(
- internal::is_reference<T>::value || !internal::is_reference<U>::value,
- cannot_convert_non_referentce_arg_to_reference);
+ std::is_reference<T>::value || !std::is_reference<U>::value,
+ cannot_convert_non_reference_arg_to_reference);
// In case both T and U are arithmetic types, enforce that the
// conversion is not lossy.
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT;
@@ -677,9 +316,9 @@
namespace internal {
// If the explanation is not empty, prints it to the ostream.
-inline void PrintIfNotEmpty(const internal::string& explanation,
+inline void PrintIfNotEmpty(const std::string& explanation,
::std::ostream* os) {
- if (explanation != "" && os != NULL) {
+ if (explanation != "" && os != nullptr) {
*os << ", " << explanation;
}
}
@@ -687,11 +326,11 @@
// Returns true if the given type name is easy to read by a human.
// This is used to decide whether printing the type of a value might
// be helpful.
-inline bool IsReadableTypeName(const string& type_name) {
+inline bool IsReadableTypeName(const std::string& type_name) {
// We consider a type name readable if it's short or doesn't contain
// a template or function type.
return (type_name.length() <= 20 ||
- type_name.find_first_of("<(") == string::npos);
+ type_name.find_first_of("<(") == std::string::npos);
}
// Matches the value against the given matcher, prints the value and explains
@@ -713,7 +352,7 @@
UniversalPrint(value, listener->stream());
#if GTEST_HAS_RTTI
- const string& type_name = GetTypeName<Value>();
+ const std::string& type_name = GetTypeName<Value>();
if (IsReadableTypeName(type_name))
*listener->stream() << " (of type " << type_name << ")";
#endif
@@ -728,13 +367,13 @@
class TuplePrefix {
public:
// TuplePrefix<N>::Matches(matcher_tuple, value_tuple) returns true
- // iff the first N fields of matcher_tuple matches the first N
- // fields of value_tuple, respectively.
+ // if and only if the first N fields of matcher_tuple matches
+ // the first N fields of value_tuple, respectively.
template <typename MatcherTuple, typename ValueTuple>
static bool Matches(const MatcherTuple& matcher_tuple,
const ValueTuple& value_tuple) {
- return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple)
- && get<N - 1>(matcher_tuple).Matches(get<N - 1>(value_tuple));
+ return TuplePrefix<N - 1>::Matches(matcher_tuple, value_tuple) &&
+ std::get<N - 1>(matcher_tuple).Matches(std::get<N - 1>(value_tuple));
}
// TuplePrefix<N>::ExplainMatchFailuresTo(matchers, values, os)
@@ -750,16 +389,14 @@
// Then describes the failure (if any) in the (N - 1)-th (0-based)
// field.
- typename tuple_element<N - 1, MatcherTuple>::type matcher =
- get<N - 1>(matchers);
- typedef typename tuple_element<N - 1, ValueTuple>::type Value;
- Value value = get<N - 1>(values);
+ typename std::tuple_element<N - 1, MatcherTuple>::type matcher =
+ std::get<N - 1>(matchers);
+ typedef typename std::tuple_element<N - 1, ValueTuple>::type Value;
+ const Value& value = std::get<N - 1>(values);
StringMatchResultListener listener;
if (!matcher.MatchAndExplain(value, &listener)) {
- // TODO(wan): include in the message the name of the parameter
- // as used in MOCK_METHOD*() when possible.
*os << " Expected arg #" << N - 1 << ": ";
- get<N - 1>(matchers).DescribeTo(os);
+ std::get<N - 1>(matchers).DescribeTo(os);
*os << "\n Actual: ";
// We remove the reference in type Value to prevent the
// universal printer from printing the address of value, which
@@ -789,8 +426,8 @@
::std::ostream* /* os */) {}
};
-// TupleMatches(matcher_tuple, value_tuple) returns true iff all
-// matchers in matcher_tuple match the corresponding fields in
+// TupleMatches(matcher_tuple, value_tuple) returns true if and only if
+// all matchers in matcher_tuple match the corresponding fields in
// value_tuple. It is a compiler error if matcher_tuple and
// value_tuple have different number of fields or incompatible field
// types.
@@ -799,11 +436,11 @@
const ValueTuple& value_tuple) {
// Makes sure that matcher_tuple and value_tuple have the same
// number of fields.
- GTEST_COMPILE_ASSERT_(tuple_size<MatcherTuple>::value ==
- tuple_size<ValueTuple>::value,
+ GTEST_COMPILE_ASSERT_(std::tuple_size<MatcherTuple>::value ==
+ std::tuple_size<ValueTuple>::value,
matcher_and_value_have_different_numbers_of_fields);
- return TuplePrefix<tuple_size<ValueTuple>::value>::
- Matches(matcher_tuple, value_tuple);
+ return TuplePrefix<std::tuple_size<ValueTuple>::value>::Matches(matcher_tuple,
+ value_tuple);
}
// Describes failures in matching matchers against values. If there
@@ -812,7 +449,7 @@
void ExplainMatchFailureTupleTo(const MatcherTuple& matchers,
const ValueTuple& values,
::std::ostream* os) {
- TuplePrefix<tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(
+ TuplePrefix<std::tuple_size<MatcherTuple>::value>::ExplainMatchFailuresTo(
matchers, values, os);
}
@@ -823,7 +460,7 @@
template <typename Tuple, typename Func, typename OutIter>
class TransformTupleValuesHelper {
private:
- typedef ::testing::tuple_size<Tuple> TupleSize;
+ typedef ::std::tuple_size<Tuple> TupleSize;
public:
// For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'.
@@ -836,7 +473,7 @@
template <typename Tup, size_t kRemainingSize>
struct IterateOverTuple {
OutIter operator() (Func f, const Tup& t, OutIter out) const {
- *out++ = f(::testing::get<TupleSize::value - kRemainingSize>(t));
+ *out++ = f(::std::get<TupleSize::value - kRemainingSize>(t));
return IterateOverTuple<Tup, kRemainingSize - 1>()(f, t, out);
}
};
@@ -858,12 +495,14 @@
// Implements A<T>().
template <typename T>
-class AnyMatcherImpl : public MatcherInterface<T> {
+class AnyMatcherImpl : public MatcherInterface<const T&> {
public:
- virtual bool MatchAndExplain(
- T /* x */, MatchResultListener* /* listener */) const { return true; }
- virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; }
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ bool MatchAndExplain(const T& /* x */,
+ MatchResultListener* /* listener */) const override {
+ return true;
+ }
+ void DescribeTo(::std::ostream* os) const override { *os << "is anything"; }
+ void DescribeNegationTo(::std::ostream* os) const override {
// This is mostly for completeness' safe, as it's not very useful
// to write Not(A<bool>()). However we cannot completely rule out
// such a possibility, and it doesn't hurt to be prepared.
@@ -881,99 +520,6 @@
operator Matcher<T>() const { return A<T>(); }
};
-// Implements a matcher that compares a given value with a
-// pre-supplied value using one of the ==, <=, <, etc, operators. The
-// two values being compared don't have to have the same type.
-//
-// The matcher defined here is polymorphic (for example, Eq(5) can be
-// used to match an int, a short, a double, etc). Therefore we use
-// a template type conversion operator in the implementation.
-//
-// The following template definition assumes that the Rhs parameter is
-// a "bare" type (i.e. neither 'const T' nor 'T&').
-template <typename D, typename Rhs, typename Op>
-class ComparisonBase {
- public:
- explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
- template <typename Lhs>
- operator Matcher<Lhs>() const {
- return MakeMatcher(new Impl<Lhs>(rhs_));
- }
-
- private:
- template <typename Lhs>
- class Impl : public MatcherInterface<Lhs> {
- public:
- explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
- virtual bool MatchAndExplain(
- Lhs lhs, MatchResultListener* /* listener */) const {
- return Op()(lhs, rhs_);
- }
- virtual void DescribeTo(::std::ostream* os) const {
- *os << D::Desc() << " ";
- UniversalPrint(rhs_, os);
- }
- virtual void DescribeNegationTo(::std::ostream* os) const {
- *os << D::NegatedDesc() << " ";
- UniversalPrint(rhs_, os);
- }
- private:
- Rhs rhs_;
- GTEST_DISALLOW_ASSIGN_(Impl);
- };
- Rhs rhs_;
- GTEST_DISALLOW_ASSIGN_(ComparisonBase);
-};
-
-template <typename Rhs>
-class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
- public:
- explicit EqMatcher(const Rhs& rhs)
- : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
- static const char* Desc() { return "is equal to"; }
- static const char* NegatedDesc() { return "isn't equal to"; }
-};
-template <typename Rhs>
-class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
- public:
- explicit NeMatcher(const Rhs& rhs)
- : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
- static const char* Desc() { return "isn't equal to"; }
- static const char* NegatedDesc() { return "is equal to"; }
-};
-template <typename Rhs>
-class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
- public:
- explicit LtMatcher(const Rhs& rhs)
- : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
- static const char* Desc() { return "is <"; }
- static const char* NegatedDesc() { return "isn't <"; }
-};
-template <typename Rhs>
-class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
- public:
- explicit GtMatcher(const Rhs& rhs)
- : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
- static const char* Desc() { return "is >"; }
- static const char* NegatedDesc() { return "isn't >"; }
-};
-template <typename Rhs>
-class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
- public:
- explicit LeMatcher(const Rhs& rhs)
- : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
- static const char* Desc() { return "is <="; }
- static const char* NegatedDesc() { return "isn't <="; }
-};
-template <typename Rhs>
-class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
- public:
- explicit GeMatcher(const Rhs& rhs)
- : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
- static const char* Desc() { return "is >="; }
- static const char* NegatedDesc() { return "isn't >="; }
-};
-
// Implements the polymorphic IsNull() matcher, which matches any raw or smart
// pointer that is NULL.
class IsNullMatcher {
@@ -981,11 +527,7 @@
template <typename Pointer>
bool MatchAndExplain(const Pointer& p,
MatchResultListener* /* listener */) const {
-#if GTEST_LANG_CXX11
return p == nullptr;
-#else // GTEST_LANG_CXX11
- return GetRawPointer(p) == NULL;
-#endif // GTEST_LANG_CXX11
}
void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
@@ -1001,11 +543,7 @@
template <typename Pointer>
bool MatchAndExplain(const Pointer& p,
MatchResultListener* /* listener */) const {
-#if GTEST_LANG_CXX11
return p != nullptr;
-#else // GTEST_LANG_CXX11
- return GetRawPointer(p) != NULL;
-#endif // GTEST_LANG_CXX11
}
void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; }
@@ -1061,18 +599,18 @@
// MatchAndExplain() takes a Super& (as opposed to const Super&)
// in order to match the interface MatcherInterface<Super&>.
- virtual bool MatchAndExplain(
- Super& x, MatchResultListener* listener) const {
+ bool MatchAndExplain(Super& x,
+ MatchResultListener* listener) const override {
*listener << "which is located @" << static_cast<const void*>(&x);
return &x == &object_;
}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "references the variable ";
UniversalPrinter<Super&>::Print(object_, os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not reference the variable ";
UniversalPrinter<Super&>::Print(object_, os);
}
@@ -1131,6 +669,16 @@
bool case_sensitive)
: string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {}
+#if GTEST_HAS_ABSL
+ bool MatchAndExplain(const absl::string_view& s,
+ MatchResultListener* listener) const {
+ // This should fail to compile if absl::string_view is used with wide
+ // strings.
+ const StringType& str = std::string(s);
+ return MatchAndExplain(str, listener);
+ }
+#endif // GTEST_HAS_ABSL
+
// Accepts pointer types, particularly:
// const char*
// char*
@@ -1138,7 +686,7 @@
// wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
- if (s == NULL) {
+ if (s == nullptr) {
return !expect_eq_;
}
return MatchAndExplain(StringType(s), listener);
@@ -1147,7 +695,7 @@
// Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
- // because StringPiece has some interfering non-explicit constructors.
+ // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
@@ -1191,6 +739,16 @@
explicit HasSubstrMatcher(const StringType& substring)
: substring_(substring) {}
+#if GTEST_HAS_ABSL
+ bool MatchAndExplain(const absl::string_view& s,
+ MatchResultListener* listener) const {
+ // This should fail to compile if absl::string_view is used with wide
+ // strings.
+ const StringType& str = std::string(s);
+ return MatchAndExplain(str, listener);
+ }
+#endif // GTEST_HAS_ABSL
+
// Accepts pointer types, particularly:
// const char*
// char*
@@ -1198,13 +756,13 @@
// wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
- return s != NULL && MatchAndExplain(StringType(s), listener);
+ return s != nullptr && MatchAndExplain(StringType(s), listener);
}
// Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
- // because StringPiece has some interfering non-explicit constructors.
+ // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
@@ -1238,6 +796,16 @@
explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) {
}
+#if GTEST_HAS_ABSL
+ bool MatchAndExplain(const absl::string_view& s,
+ MatchResultListener* listener) const {
+ // This should fail to compile if absl::string_view is used with wide
+ // strings.
+ const StringType& str = std::string(s);
+ return MatchAndExplain(str, listener);
+ }
+#endif // GTEST_HAS_ABSL
+
// Accepts pointer types, particularly:
// const char*
// char*
@@ -1245,13 +813,13 @@
// wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
- return s != NULL && MatchAndExplain(StringType(s), listener);
+ return s != nullptr && MatchAndExplain(StringType(s), listener);
}
// Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
- // because StringPiece has some interfering non-explicit constructors.
+ // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
@@ -1284,6 +852,16 @@
public:
explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {}
+#if GTEST_HAS_ABSL
+ bool MatchAndExplain(const absl::string_view& s,
+ MatchResultListener* listener) const {
+ // This should fail to compile if absl::string_view is used with wide
+ // strings.
+ const StringType& str = std::string(s);
+ return MatchAndExplain(str, listener);
+ }
+#endif // GTEST_HAS_ABSL
+
// Accepts pointer types, particularly:
// const char*
// char*
@@ -1291,13 +869,13 @@
// wchar_t*
template <typename CharType>
bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
- return s != NULL && MatchAndExplain(StringType(s), listener);
+ return s != nullptr && MatchAndExplain(StringType(s), listener);
}
// Matches anything that can convert to StringType.
//
// This is a template, not just a plain function with const StringType&,
- // because StringPiece has some interfering non-explicit constructors.
+ // because absl::string_view has some interfering non-explicit constructors.
template <typename MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
@@ -1322,73 +900,24 @@
GTEST_DISALLOW_ASSIGN_(EndsWithMatcher);
};
-// Implements polymorphic matchers MatchesRegex(regex) and
-// ContainsRegex(regex), which can be used as a Matcher<T> as long as
-// T can be converted to a string.
-class MatchesRegexMatcher {
- public:
- MatchesRegexMatcher(const RE* regex, bool full_match)
- : regex_(regex), full_match_(full_match) {}
-
- // Accepts pointer types, particularly:
- // const char*
- // char*
- // const wchar_t*
- // wchar_t*
- template <typename CharType>
- bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
- return s != NULL && MatchAndExplain(internal::string(s), listener);
- }
-
- // Matches anything that can convert to internal::string.
- //
- // This is a template, not just a plain function with const internal::string&,
- // because StringPiece has some interfering non-explicit constructors.
- template <class MatcheeStringType>
- bool MatchAndExplain(const MatcheeStringType& s,
- MatchResultListener* /* listener */) const {
- const internal::string& s2(s);
- return full_match_ ? RE::FullMatch(s2, *regex_) :
- RE::PartialMatch(s2, *regex_);
- }
-
- void DescribeTo(::std::ostream* os) const {
- *os << (full_match_ ? "matches" : "contains")
- << " regular expression ";
- UniversalPrinter<internal::string>::Print(regex_->pattern(), os);
- }
-
- void DescribeNegationTo(::std::ostream* os) const {
- *os << "doesn't " << (full_match_ ? "match" : "contain")
- << " regular expression ";
- UniversalPrinter<internal::string>::Print(regex_->pattern(), os);
- }
-
- private:
- const internal::linked_ptr<const RE> regex_;
- const bool full_match_;
-
- GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher);
-};
-
// Implements a matcher that compares the two fields of a 2-tuple
// using one of the ==, <=, <, etc, operators. The two fields being
// compared don't have to have the same type.
//
// The matcher defined here is polymorphic (for example, Eq() can be
-// used to match a tuple<int, short>, a tuple<const long&, double>,
+// used to match a std::tuple<int, short>, a std::tuple<const long&, double>,
// etc). Therefore we use a template type conversion operator in the
// implementation.
template <typename D, typename Op>
class PairMatchBase {
public:
template <typename T1, typename T2>
- operator Matcher< ::testing::tuple<T1, T2> >() const {
- return MakeMatcher(new Impl< ::testing::tuple<T1, T2> >);
+ operator Matcher<::std::tuple<T1, T2>>() const {
+ return Matcher<::std::tuple<T1, T2>>(new Impl<const ::std::tuple<T1, T2>&>);
}
template <typename T1, typename T2>
- operator Matcher<const ::testing::tuple<T1, T2>&>() const {
- return MakeMatcher(new Impl<const ::testing::tuple<T1, T2>&>);
+ operator Matcher<const ::std::tuple<T1, T2>&>() const {
+ return MakeMatcher(new Impl<const ::std::tuple<T1, T2>&>);
}
private:
@@ -1399,15 +928,14 @@
template <typename Tuple>
class Impl : public MatcherInterface<Tuple> {
public:
- virtual bool MatchAndExplain(
- Tuple args,
- MatchResultListener* /* listener */) const {
- return Op()(::testing::get<0>(args), ::testing::get<1>(args));
+ bool MatchAndExplain(Tuple args,
+ MatchResultListener* /* listener */) const override {
+ return Op()(::std::get<0>(args), ::std::get<1>(args));
}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "are " << GetDesc;
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "aren't " << GetDesc;
}
};
@@ -1443,20 +971,21 @@
// will prevent different instantiations of NotMatcher from sharing
// the same NotMatcherImpl<T> class.
template <typename T>
-class NotMatcherImpl : public MatcherInterface<T> {
+class NotMatcherImpl : public MatcherInterface<const T&> {
public:
explicit NotMatcherImpl(const Matcher<T>& matcher)
: matcher_(matcher) {}
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+ bool MatchAndExplain(const T& x,
+ MatchResultListener* listener) const override {
return !matcher_.MatchAndExplain(x, listener);
}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
matcher_.DescribeNegationTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
matcher_.DescribeTo(os);
}
@@ -1491,115 +1020,62 @@
// that will prevent different instantiations of BothOfMatcher from
// sharing the same BothOfMatcherImpl<T> class.
template <typename T>
-class BothOfMatcherImpl : public MatcherInterface<T> {
+class AllOfMatcherImpl : public MatcherInterface<const T&> {
public:
- BothOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
- : matcher1_(matcher1), matcher2_(matcher2) {}
+ explicit AllOfMatcherImpl(std::vector<Matcher<T> > matchers)
+ : matchers_(std::move(matchers)) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "(";
- matcher1_.DescribeTo(os);
- *os << ") and (";
- matcher2_.DescribeTo(os);
+ for (size_t i = 0; i < matchers_.size(); ++i) {
+ if (i != 0) *os << ") and (";
+ matchers_[i].DescribeTo(os);
+ }
*os << ")";
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "(";
- matcher1_.DescribeNegationTo(os);
- *os << ") or (";
- matcher2_.DescribeNegationTo(os);
+ for (size_t i = 0; i < matchers_.size(); ++i) {
+ if (i != 0) *os << ") or (";
+ matchers_[i].DescribeNegationTo(os);
+ }
*os << ")";
}
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+ bool MatchAndExplain(const T& x,
+ MatchResultListener* listener) const override {
// If either matcher1_ or matcher2_ doesn't match x, we only need
// to explain why one of them fails.
- StringMatchResultListener listener1;
- if (!matcher1_.MatchAndExplain(x, &listener1)) {
- *listener << listener1.str();
- return false;
- }
+ std::string all_match_result;
- StringMatchResultListener listener2;
- if (!matcher2_.MatchAndExplain(x, &listener2)) {
- *listener << listener2.str();
- return false;
+ for (size_t i = 0; i < matchers_.size(); ++i) {
+ StringMatchResultListener slistener;
+ if (matchers_[i].MatchAndExplain(x, &slistener)) {
+ if (all_match_result.empty()) {
+ all_match_result = slistener.str();
+ } else {
+ std::string result = slistener.str();
+ if (!result.empty()) {
+ all_match_result += ", and ";
+ all_match_result += result;
+ }
+ }
+ } else {
+ *listener << slistener.str();
+ return false;
+ }
}
// Otherwise we need to explain why *both* of them match.
- const internal::string s1 = listener1.str();
- const internal::string s2 = listener2.str();
-
- if (s1 == "") {
- *listener << s2;
- } else {
- *listener << s1;
- if (s2 != "") {
- *listener << ", and " << s2;
- }
- }
+ *listener << all_match_result;
return true;
}
private:
- const Matcher<T> matcher1_;
- const Matcher<T> matcher2_;
+ const std::vector<Matcher<T> > matchers_;
- GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl);
-};
-
-#if GTEST_LANG_CXX11
-// MatcherList provides mechanisms for storing a variable number of matchers in
-// a list structure (ListType) and creating a combining matcher from such a
-// list.
-// The template is defined recursively using the following template paramters:
-// * kSize is the length of the MatcherList.
-// * Head is the type of the first matcher of the list.
-// * Tail denotes the types of the remaining matchers of the list.
-template <int kSize, typename Head, typename... Tail>
-struct MatcherList {
- typedef MatcherList<kSize - 1, Tail...> MatcherListTail;
- typedef ::std::pair<Head, typename MatcherListTail::ListType> ListType;
-
- // BuildList stores variadic type values in a nested pair structure.
- // Example:
- // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return
- // the corresponding result of type pair<int, pair<string, float>>.
- static ListType BuildList(const Head& matcher, const Tail&... tail) {
- return ListType(matcher, MatcherListTail::BuildList(tail...));
- }
-
- // CreateMatcher<T> creates a Matcher<T> from a given list of matchers (built
- // by BuildList()). CombiningMatcher<T> is used to combine the matchers of the
- // list. CombiningMatcher<T> must implement MatcherInterface<T> and have a
- // constructor taking two Matcher<T>s as input.
- template <typename T, template <typename /* T */> class CombiningMatcher>
- static Matcher<T> CreateMatcher(const ListType& matchers) {
- return Matcher<T>(new CombiningMatcher<T>(
- SafeMatcherCast<T>(matchers.first),
- MatcherListTail::template CreateMatcher<T, CombiningMatcher>(
- matchers.second)));
- }
-};
-
-// The following defines the base case for the recursive definition of
-// MatcherList.
-template <typename Matcher1, typename Matcher2>
-struct MatcherList<2, Matcher1, Matcher2> {
- typedef ::std::pair<Matcher1, Matcher2> ListType;
-
- static ListType BuildList(const Matcher1& matcher1,
- const Matcher2& matcher2) {
- return ::std::pair<Matcher1, Matcher2>(matcher1, matcher2);
- }
-
- template <typename T, template <typename /* T */> class CombiningMatcher>
- static Matcher<T> CreateMatcher(const ListType& matchers) {
- return Matcher<T>(new CombiningMatcher<T>(
- SafeMatcherCast<T>(matchers.first),
- SafeMatcherCast<T>(matchers.second)));
- }
+ GTEST_DISALLOW_ASSIGN_(AllOfMatcherImpl);
};
// VariadicMatcher is used for the variadic implementation of
@@ -1610,149 +1086,139 @@
class VariadicMatcher {
public:
VariadicMatcher(const Args&... matchers) // NOLINT
- : matchers_(MatcherListType::BuildList(matchers...)) {}
+ : matchers_(matchers...) {
+ static_assert(sizeof...(Args) > 0, "Must have at least one matcher.");
+ }
// This template type conversion operator allows an
// VariadicMatcher<Matcher1, Matcher2...> object to match any type that
// all of the provided matchers (Matcher1, Matcher2, ...) can match.
template <typename T>
operator Matcher<T>() const {
- return MatcherListType::template CreateMatcher<T, CombiningMatcher>(
- matchers_);
+ std::vector<Matcher<T> > values;
+ CreateVariadicMatcher<T>(&values, std::integral_constant<size_t, 0>());
+ return Matcher<T>(new CombiningMatcher<T>(std::move(values)));
}
private:
- typedef MatcherList<sizeof...(Args), Args...> MatcherListType;
+ template <typename T, size_t I>
+ void CreateVariadicMatcher(std::vector<Matcher<T> >* values,
+ std::integral_constant<size_t, I>) const {
+ values->push_back(SafeMatcherCast<T>(std::get<I>(matchers_)));
+ CreateVariadicMatcher<T>(values, std::integral_constant<size_t, I + 1>());
+ }
- const typename MatcherListType::ListType matchers_;
+ template <typename T>
+ void CreateVariadicMatcher(
+ std::vector<Matcher<T> >*,
+ std::integral_constant<size_t, sizeof...(Args)>) const {}
+
+ std::tuple<Args...> matchers_;
GTEST_DISALLOW_ASSIGN_(VariadicMatcher);
};
template <typename... Args>
-using AllOfMatcher = VariadicMatcher<BothOfMatcherImpl, Args...>;
-
-#endif // GTEST_LANG_CXX11
-
-// Used for implementing the AllOf(m_1, ..., m_n) matcher, which
-// matches a value that matches all of the matchers m_1, ..., and m_n.
-template <typename Matcher1, typename Matcher2>
-class BothOfMatcher {
- public:
- BothOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
- : matcher1_(matcher1), matcher2_(matcher2) {}
-
- // This template type conversion operator allows a
- // BothOfMatcher<Matcher1, Matcher2> object to match any type that
- // both Matcher1 and Matcher2 can match.
- template <typename T>
- operator Matcher<T>() const {
- return Matcher<T>(new BothOfMatcherImpl<T>(SafeMatcherCast<T>(matcher1_),
- SafeMatcherCast<T>(matcher2_)));
- }
-
- private:
- Matcher1 matcher1_;
- Matcher2 matcher2_;
-
- GTEST_DISALLOW_ASSIGN_(BothOfMatcher);
-};
+using AllOfMatcher = VariadicMatcher<AllOfMatcherImpl, Args...>;
// Implements the AnyOf(m1, m2) matcher for a particular argument type
// T. We do not nest it inside the AnyOfMatcher class template, as
// that will prevent different instantiations of AnyOfMatcher from
// sharing the same EitherOfMatcherImpl<T> class.
template <typename T>
-class EitherOfMatcherImpl : public MatcherInterface<T> {
+class AnyOfMatcherImpl : public MatcherInterface<const T&> {
public:
- EitherOfMatcherImpl(const Matcher<T>& matcher1, const Matcher<T>& matcher2)
- : matcher1_(matcher1), matcher2_(matcher2) {}
+ explicit AnyOfMatcherImpl(std::vector<Matcher<T> > matchers)
+ : matchers_(std::move(matchers)) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "(";
- matcher1_.DescribeTo(os);
- *os << ") or (";
- matcher2_.DescribeTo(os);
+ for (size_t i = 0; i < matchers_.size(); ++i) {
+ if (i != 0) *os << ") or (";
+ matchers_[i].DescribeTo(os);
+ }
*os << ")";
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "(";
- matcher1_.DescribeNegationTo(os);
- *os << ") and (";
- matcher2_.DescribeNegationTo(os);
+ for (size_t i = 0; i < matchers_.size(); ++i) {
+ if (i != 0) *os << ") and (";
+ matchers_[i].DescribeNegationTo(os);
+ }
*os << ")";
}
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+ bool MatchAndExplain(const T& x,
+ MatchResultListener* listener) const override {
+ std::string no_match_result;
+
// If either matcher1_ or matcher2_ matches x, we just need to
// explain why *one* of them matches.
- StringMatchResultListener listener1;
- if (matcher1_.MatchAndExplain(x, &listener1)) {
- *listener << listener1.str();
- return true;
- }
-
- StringMatchResultListener listener2;
- if (matcher2_.MatchAndExplain(x, &listener2)) {
- *listener << listener2.str();
- return true;
+ for (size_t i = 0; i < matchers_.size(); ++i) {
+ StringMatchResultListener slistener;
+ if (matchers_[i].MatchAndExplain(x, &slistener)) {
+ *listener << slistener.str();
+ return true;
+ } else {
+ if (no_match_result.empty()) {
+ no_match_result = slistener.str();
+ } else {
+ std::string result = slistener.str();
+ if (!result.empty()) {
+ no_match_result += ", and ";
+ no_match_result += result;
+ }
+ }
+ }
}
// Otherwise we need to explain why *both* of them fail.
- const internal::string s1 = listener1.str();
- const internal::string s2 = listener2.str();
-
- if (s1 == "") {
- *listener << s2;
- } else {
- *listener << s1;
- if (s2 != "") {
- *listener << ", and " << s2;
- }
- }
+ *listener << no_match_result;
return false;
}
private:
- const Matcher<T> matcher1_;
- const Matcher<T> matcher2_;
+ const std::vector<Matcher<T> > matchers_;
- GTEST_DISALLOW_ASSIGN_(EitherOfMatcherImpl);
+ GTEST_DISALLOW_ASSIGN_(AnyOfMatcherImpl);
};
-#if GTEST_LANG_CXX11
// AnyOfMatcher is used for the variadic implementation of AnyOf(m_1, m_2, ...).
template <typename... Args>
-using AnyOfMatcher = VariadicMatcher<EitherOfMatcherImpl, Args...>;
+using AnyOfMatcher = VariadicMatcher<AnyOfMatcherImpl, Args...>;
-#endif // GTEST_LANG_CXX11
-
-// Used for implementing the AnyOf(m_1, ..., m_n) matcher, which
-// matches a value that matches at least one of the matchers m_1, ...,
-// and m_n.
-template <typename Matcher1, typename Matcher2>
-class EitherOfMatcher {
+// Wrapper for implementation of Any/AllOfArray().
+template <template <class> class MatcherImpl, typename T>
+class SomeOfArrayMatcher {
public:
- EitherOfMatcher(Matcher1 matcher1, Matcher2 matcher2)
- : matcher1_(matcher1), matcher2_(matcher2) {}
+ // Constructs the matcher from a sequence of element values or
+ // element matchers.
+ template <typename Iter>
+ SomeOfArrayMatcher(Iter first, Iter last) : matchers_(first, last) {}
- // This template type conversion operator allows a
- // EitherOfMatcher<Matcher1, Matcher2> object to match any type that
- // both Matcher1 and Matcher2 can match.
- template <typename T>
- operator Matcher<T>() const {
- return Matcher<T>(new EitherOfMatcherImpl<T>(
- SafeMatcherCast<T>(matcher1_), SafeMatcherCast<T>(matcher2_)));
+ template <typename U>
+ operator Matcher<U>() const { // NOLINT
+ using RawU = typename std::decay<U>::type;
+ std::vector<Matcher<RawU>> matchers;
+ for (const auto& matcher : matchers_) {
+ matchers.push_back(MatcherCast<RawU>(matcher));
+ }
+ return Matcher<U>(new MatcherImpl<RawU>(std::move(matchers)));
}
private:
- Matcher1 matcher1_;
- Matcher2 matcher2_;
+ const ::std::vector<T> matchers_;
- GTEST_DISALLOW_ASSIGN_(EitherOfMatcher);
+ GTEST_DISALLOW_ASSIGN_(SomeOfArrayMatcher);
};
+template <typename T>
+using AllOfArrayMatcher = SomeOfArrayMatcher<AllOfMatcherImpl, T>;
+
+template <typename T>
+using AnyOfArrayMatcher = SomeOfArrayMatcher<AnyOfMatcherImpl, T>;
+
// Used for implementing Truly(pred), which turns a predicate into a
// matcher.
template <typename Predicate>
@@ -1835,7 +1301,7 @@
template <typename M>
class PredicateFormatterFromMatcher {
public:
- explicit PredicateFormatterFromMatcher(M m) : matcher_(internal::move(m)) {}
+ explicit PredicateFormatterFromMatcher(M m) : matcher_(std::move(m)) {}
// This template () operator allows a PredicateFormatterFromMatcher
// object to act as a predicate-formatter suitable for using with
@@ -1854,14 +1320,24 @@
// We don't write MatcherCast<const T&> either, as that allows
// potentially unsafe downcasting of the matcher argument.
const Matcher<const T&> matcher = SafeMatcherCast<const T&>(matcher_);
- StringMatchResultListener listener;
- if (MatchPrintAndExplain(x, matcher, &listener))
+
+ // The expected path here is that the matcher should match (i.e. that most
+ // tests pass) so optimize for this case.
+ if (matcher.Matches(x)) {
return AssertionSuccess();
+ }
::std::stringstream ss;
ss << "Value of: " << value_text << "\n"
<< "Expected: ";
matcher.DescribeTo(&ss);
+
+ // Rerun the matcher to "PrintAndExain" the failure.
+ StringMatchResultListener listener;
+ if (MatchPrintAndExplain(x, matcher, &listener)) {
+ ss << "\n The matcher failed on the initial attempt; but passed when "
+ "rerun to generate the explanation.";
+ }
ss << "\n Actual: " << listener.str();
return AssertionFailure() << ss.str();
}
@@ -1879,7 +1355,7 @@
template <typename M>
inline PredicateFormatterFromMatcher<M>
MakePredicateFormatterFromMatcher(M matcher) {
- return PredicateFormatterFromMatcher<M>(internal::move(matcher));
+ return PredicateFormatterFromMatcher<M>(std::move(matcher));
}
// Implements the polymorphic floating point equality matcher, which matches
@@ -1920,8 +1396,8 @@
nan_eq_nan_(nan_eq_nan),
max_abs_error_(max_abs_error) {}
- virtual bool MatchAndExplain(T value,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(T value,
+ MatchResultListener* listener) const override {
const FloatingPoint<FloatType> actual(value), expected(expected_);
// Compares NaNs first, if nan_eq_nan_ is true.
@@ -1955,7 +1431,7 @@
}
}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
// os->precision() returns the previously set precision, which we
// store to restore the ostream to its original configuration
// after outputting.
@@ -1976,7 +1452,7 @@
os->precision(old_precision);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
// As before, get original precision.
const ::std::streamsize old_precision = os->precision(
::std::numeric_limits<FloatType>::digits10 + 2);
@@ -2039,6 +1515,82 @@
GTEST_DISALLOW_ASSIGN_(FloatingEqMatcher);
};
+// A 2-tuple ("binary") wrapper around FloatingEqMatcher:
+// FloatingEq2Matcher() matches (x, y) by matching FloatingEqMatcher(x, false)
+// against y, and FloatingEq2Matcher(e) matches FloatingEqMatcher(x, false, e)
+// against y. The former implements "Eq", the latter "Near". At present, there
+// is no version that compares NaNs as equal.
+template <typename FloatType>
+class FloatingEq2Matcher {
+ public:
+ FloatingEq2Matcher() { Init(-1, false); }
+
+ explicit FloatingEq2Matcher(bool nan_eq_nan) { Init(-1, nan_eq_nan); }
+
+ explicit FloatingEq2Matcher(FloatType max_abs_error) {
+ Init(max_abs_error, false);
+ }
+
+ FloatingEq2Matcher(FloatType max_abs_error, bool nan_eq_nan) {
+ Init(max_abs_error, nan_eq_nan);
+ }
+
+ template <typename T1, typename T2>
+ operator Matcher<::std::tuple<T1, T2>>() const {
+ return MakeMatcher(
+ new Impl<::std::tuple<T1, T2>>(max_abs_error_, nan_eq_nan_));
+ }
+ template <typename T1, typename T2>
+ operator Matcher<const ::std::tuple<T1, T2>&>() const {
+ return MakeMatcher(
+ new Impl<const ::std::tuple<T1, T2>&>(max_abs_error_, nan_eq_nan_));
+ }
+
+ private:
+ static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT
+ return os << "an almost-equal pair";
+ }
+
+ template <typename Tuple>
+ class Impl : public MatcherInterface<Tuple> {
+ public:
+ Impl(FloatType max_abs_error, bool nan_eq_nan) :
+ max_abs_error_(max_abs_error),
+ nan_eq_nan_(nan_eq_nan) {}
+
+ bool MatchAndExplain(Tuple args,
+ MatchResultListener* listener) const override {
+ if (max_abs_error_ == -1) {
+ FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_);
+ return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(
+ ::std::get<1>(args), listener);
+ } else {
+ FloatingEqMatcher<FloatType> fm(::std::get<0>(args), nan_eq_nan_,
+ max_abs_error_);
+ return static_cast<Matcher<FloatType>>(fm).MatchAndExplain(
+ ::std::get<1>(args), listener);
+ }
+ }
+ void DescribeTo(::std::ostream* os) const override {
+ *os << "are " << GetDesc;
+ }
+ void DescribeNegationTo(::std::ostream* os) const override {
+ *os << "aren't " << GetDesc;
+ }
+
+ private:
+ FloatType max_abs_error_;
+ const bool nan_eq_nan_;
+ };
+
+ void Init(FloatType max_abs_error_val, bool nan_eq_nan_val) {
+ max_abs_error_ = max_abs_error_val;
+ nan_eq_nan_ = nan_eq_nan_val;
+ }
+ FloatType max_abs_error_;
+ bool nan_eq_nan_;
+};
+
// Implements the Pointee(m) matcher for matching a pointer whose
// pointee matches matcher m. The pointer can be either raw or smart.
template <typename InnerMatcher>
@@ -2056,7 +1608,7 @@
// enough for implementing the DescribeTo() method of Pointee().
template <typename Pointer>
operator Matcher<Pointer>() const {
- return MakeMatcher(new Impl<Pointer>(matcher_));
+ return Matcher<Pointer>(new Impl<const Pointer&>(matcher_));
}
private:
@@ -2064,26 +1616,25 @@
template <typename Pointer>
class Impl : public MatcherInterface<Pointer> {
public:
- typedef typename PointeeOf<GTEST_REMOVE_CONST_( // NOLINT
- GTEST_REMOVE_REFERENCE_(Pointer))>::type Pointee;
+ typedef typename PointeeOf<typename std::remove_const<
+ typename std::remove_reference<Pointer>::type>::type>::type Pointee;
explicit Impl(const InnerMatcher& matcher)
: matcher_(MatcherCast<const Pointee&>(matcher)) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "points to a value that ";
matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not point to a value that ";
matcher_.DescribeTo(os);
}
- virtual bool MatchAndExplain(Pointer pointer,
- MatchResultListener* listener) const {
- if (GetRawPointer(pointer) == NULL)
- return false;
+ bool MatchAndExplain(Pointer pointer,
+ MatchResultListener* listener) const override {
+ if (GetRawPointer(pointer) == nullptr) return false;
*listener << "which points to ";
return MatchPrintAndExplain(*pointer, matcher_, listener);
@@ -2100,6 +1651,7 @@
GTEST_DISALLOW_ASSIGN_(PointeeMatcher);
};
+#if GTEST_HAS_RTTI
// Implements the WhenDynamicCastTo<T>(m) matcher that matches a pointer or
// reference that matches inner_matcher when dynamic_cast<T> is applied.
// The result of dynamic_cast<To> is forwarded to the inner matcher.
@@ -2125,12 +1677,8 @@
protected:
const Matcher<To> matcher_;
- static string GetToName() {
-#if GTEST_HAS_RTTI
+ static std::string GetToName() {
return GetTypeName<To>();
-#else // GTEST_HAS_RTTI
- return "the target type";
-#endif // GTEST_HAS_RTTI
}
private:
@@ -2151,7 +1699,6 @@
template <typename From>
bool MatchAndExplain(From from, MatchResultListener* listener) const {
- // TODO(sbenza): Add more detail on failures. ie did the dyn_cast fail?
To to = dynamic_cast<To>(from);
return MatchPrintAndExplain(to, this->matcher_, listener);
}
@@ -2169,13 +1716,14 @@
bool MatchAndExplain(From& from, MatchResultListener* listener) const {
// We don't want an std::bad_cast here, so do the cast with pointers.
To* to = dynamic_cast<To*>(&from);
- if (to == NULL) {
+ if (to == nullptr) {
*listener << "which cannot be dynamic_cast to " << this->GetToName();
return false;
}
return MatchPrintAndExplain(*to, this->matcher_, listener);
}
};
+#endif // GTEST_HAS_RTTI
// Implements the Field() matcher for matching a field (i.e. member
// variable) of an object.
@@ -2184,137 +1732,144 @@
public:
FieldMatcher(FieldType Class::*field,
const Matcher<const FieldType&>& matcher)
- : field_(field), matcher_(matcher) {}
+ : field_(field), matcher_(matcher), whose_field_("whose given field ") {}
+
+ FieldMatcher(const std::string& field_name, FieldType Class::*field,
+ const Matcher<const FieldType&>& matcher)
+ : field_(field),
+ matcher_(matcher),
+ whose_field_("whose field `" + field_name + "` ") {}
void DescribeTo(::std::ostream* os) const {
- *os << "is an object whose given field ";
+ *os << "is an object " << whose_field_;
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const {
- *os << "is an object whose given field ";
+ *os << "is an object " << whose_field_;
matcher_.DescribeNegationTo(os);
}
template <typename T>
bool MatchAndExplain(const T& value, MatchResultListener* listener) const {
+ // FIXME: The dispatch on std::is_pointer was introduced as a workaround for
+ // a compiler bug, and can now be removed.
return MatchAndExplainImpl(
- typename ::testing::internal::
- is_pointer<GTEST_REMOVE_CONST_(T)>::type(),
+ typename std::is_pointer<typename std::remove_const<T>::type>::type(),
value, listener);
}
private:
- // The first argument of MatchAndExplainImpl() is needed to help
- // Symbian's C++ compiler choose which overload to use. Its type is
- // true_type iff the Field() matcher is used to match a pointer.
- bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
+ bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,
+ const Class& obj,
MatchResultListener* listener) const {
- *listener << "whose given field is ";
+ *listener << whose_field_ << "is ";
return MatchPrintAndExplain(obj.*field_, matcher_, listener);
}
- bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p,
+ bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,
MatchResultListener* listener) const {
- if (p == NULL)
- return false;
+ if (p == nullptr) return false;
*listener << "which points to an object ";
// Since *p has a field, it must be a class/struct/union type and
// thus cannot be a pointer. Therefore we pass false_type() as
// the first argument.
- return MatchAndExplainImpl(false_type(), *p, listener);
+ return MatchAndExplainImpl(std::false_type(), *p, listener);
}
const FieldType Class::*field_;
const Matcher<const FieldType&> matcher_;
+ // Contains either "whose given field " if the name of the field is unknown
+ // or "whose field `name_of_field` " if the name is known.
+ const std::string whose_field_;
+
GTEST_DISALLOW_ASSIGN_(FieldMatcher);
};
// Implements the Property() matcher for matching a property
// (i.e. return value of a getter method) of an object.
-template <typename Class, typename PropertyType>
+//
+// Property is a const-qualified member function of Class returning
+// PropertyType.
+template <typename Class, typename PropertyType, typename Property>
class PropertyMatcher {
public:
- // The property may have a reference type, so 'const PropertyType&'
- // may cause double references and fail to compile. That's why we
- // need GTEST_REFERENCE_TO_CONST, which works regardless of
- // PropertyType being a reference or not.
- typedef GTEST_REFERENCE_TO_CONST_(PropertyType) RefToConstProperty;
+ typedef const PropertyType& RefToConstProperty;
- PropertyMatcher(PropertyType (Class::*property)() const,
+ PropertyMatcher(Property property, const Matcher<RefToConstProperty>& matcher)
+ : property_(property),
+ matcher_(matcher),
+ whose_property_("whose given property ") {}
+
+ PropertyMatcher(const std::string& property_name, Property property,
const Matcher<RefToConstProperty>& matcher)
- : property_(property), matcher_(matcher) {}
+ : property_(property),
+ matcher_(matcher),
+ whose_property_("whose property `" + property_name + "` ") {}
void DescribeTo(::std::ostream* os) const {
- *os << "is an object whose given property ";
+ *os << "is an object " << whose_property_;
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const {
- *os << "is an object whose given property ";
+ *os << "is an object " << whose_property_;
matcher_.DescribeNegationTo(os);
}
template <typename T>
bool MatchAndExplain(const T&value, MatchResultListener* listener) const {
return MatchAndExplainImpl(
- typename ::testing::internal::
- is_pointer<GTEST_REMOVE_CONST_(T)>::type(),
+ typename std::is_pointer<typename std::remove_const<T>::type>::type(),
value, listener);
}
private:
- // The first argument of MatchAndExplainImpl() is needed to help
- // Symbian's C++ compiler choose which overload to use. Its type is
- // true_type iff the Property() matcher is used to match a pointer.
- bool MatchAndExplainImpl(false_type /* is_not_pointer */, const Class& obj,
+ bool MatchAndExplainImpl(std::false_type /* is_not_pointer */,
+ const Class& obj,
MatchResultListener* listener) const {
- *listener << "whose given property is ";
+ *listener << whose_property_ << "is ";
// Cannot pass the return value (for example, int) to MatchPrintAndExplain,
// which takes a non-const reference as argument.
-#if defined(_PREFAST_ ) && _MSC_VER == 1800
- // Workaround bug in VC++ 2013's /analyze parser.
- // https://connect.microsoft.com/VisualStudio/feedback/details/1106363/internal-compiler-error-with-analyze-due-to-failure-to-infer-move
- posix::Abort(); // To make sure it is never run.
- return false;
-#else
RefToConstProperty result = (obj.*property_)();
return MatchPrintAndExplain(result, matcher_, listener);
-#endif
}
- bool MatchAndExplainImpl(true_type /* is_pointer */, const Class* p,
+ bool MatchAndExplainImpl(std::true_type /* is_pointer */, const Class* p,
MatchResultListener* listener) const {
- if (p == NULL)
- return false;
+ if (p == nullptr) return false;
*listener << "which points to an object ";
// Since *p has a property method, it must be a class/struct/union
// type and thus cannot be a pointer. Therefore we pass
// false_type() as the first argument.
- return MatchAndExplainImpl(false_type(), *p, listener);
+ return MatchAndExplainImpl(std::false_type(), *p, listener);
}
- PropertyType (Class::*property_)() const;
+ Property property_;
const Matcher<RefToConstProperty> matcher_;
+ // Contains either "whose given property " if the name of the property is
+ // unknown or "whose property `name_of_property` " if the name is known.
+ const std::string whose_property_;
+
GTEST_DISALLOW_ASSIGN_(PropertyMatcher);
};
// Type traits specifying various features of different functors for ResultOf.
// The default template specifies features for functor objects.
-// Functor classes have to typedef argument_type and result_type
-// to be compatible with ResultOf.
template <typename Functor>
struct CallableTraits {
- typedef typename Functor::result_type ResultType;
typedef Functor StorageType;
static void CheckIsValid(Functor /* functor */) {}
+
template <typename T>
- static ResultType Invoke(Functor f, T arg) { return f(arg); }
+ static auto Invoke(Functor f, const T& arg) -> decltype(f(arg)) {
+ return f(arg);
+ }
};
// Specialization for function pointers.
@@ -2324,7 +1879,7 @@
typedef ResType(*StorageType)(ArgType);
static void CheckIsValid(ResType(*f)(ArgType)) {
- GTEST_CHECK_(f != NULL)
+ GTEST_CHECK_(f != nullptr)
<< "NULL function pointer is passed into ResultOf().";
}
template <typename T>
@@ -2335,19 +1890,17 @@
// Implements the ResultOf() matcher for matching a return value of a
// unary function of an object.
-template <typename Callable>
+template <typename Callable, typename InnerMatcher>
class ResultOfMatcher {
public:
- typedef typename CallableTraits<Callable>::ResultType ResultType;
-
- ResultOfMatcher(Callable callable, const Matcher<ResultType>& matcher)
- : callable_(callable), matcher_(matcher) {
+ ResultOfMatcher(Callable callable, InnerMatcher matcher)
+ : callable_(std::move(callable)), matcher_(std::move(matcher)) {
CallableTraits<Callable>::CheckIsValid(callable_);
}
template <typename T>
operator Matcher<T>() const {
- return Matcher<T>(new Impl<T>(callable_, matcher_));
+ return Matcher<T>(new Impl<const T&>(callable_, matcher_));
}
private:
@@ -2355,24 +1908,30 @@
template <typename T>
class Impl : public MatcherInterface<T> {
- public:
- Impl(CallableStorageType callable, const Matcher<ResultType>& matcher)
- : callable_(callable), matcher_(matcher) {}
+ using ResultType = decltype(CallableTraits<Callable>::template Invoke<T>(
+ std::declval<CallableStorageType>(), std::declval<T>()));
- virtual void DescribeTo(::std::ostream* os) const {
+ public:
+ template <typename M>
+ Impl(const CallableStorageType& callable, const M& matcher)
+ : callable_(callable), matcher_(MatcherCast<ResultType>(matcher)) {}
+
+ void DescribeTo(::std::ostream* os) const override {
*os << "is mapped by the given callable to a value that ";
matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "is mapped by the given callable to a value that ";
matcher_.DescribeNegationTo(os);
}
- virtual bool MatchAndExplain(T obj, MatchResultListener* listener) const {
+ bool MatchAndExplain(T obj, MatchResultListener* listener) const override {
*listener << "which is mapped by the given callable to ";
- // Cannot pass the return value (for example, int) to
- // MatchPrintAndExplain, which takes a non-const reference as argument.
+ // Cannot pass the return value directly to MatchPrintAndExplain, which
+ // takes a non-const reference as argument.
+ // Also, specifying template argument explicitly is needed because T could
+ // be a non-const reference (e.g. Matcher<Uncopyable&>).
ResultType result =
CallableTraits<Callable>::template Invoke<T>(callable_, obj);
return MatchPrintAndExplain(result, matcher_, listener);
@@ -2380,9 +1939,9 @@
private:
// Functors often define operator() as non-const method even though
- // they are actualy stateless. But we need to use them even when
+ // they are actually stateless. But we need to use them even when
// 'this' is a const pointer. It's the user's responsibility not to
- // use stateful callables with ResultOf(), which does't guarantee
+ // use stateful callables with ResultOf(), which doesn't guarantee
// how many times the callable will be invoked.
mutable CallableStorageType callable_;
const Matcher<ResultType> matcher_;
@@ -2391,7 +1950,7 @@
}; // class Impl
const CallableStorageType callable_;
- const Matcher<ResultType> matcher_;
+ const InnerMatcher matcher_;
GTEST_DISALLOW_ASSIGN_(ResultOfMatcher);
};
@@ -2406,29 +1965,27 @@
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(new Impl<Container>(size_matcher_));
+ return Matcher<Container>(new Impl<const Container&>(size_matcher_));
}
template <typename Container>
class Impl : public MatcherInterface<Container> {
public:
- typedef internal::StlContainerView<
- GTEST_REMOVE_REFERENCE_AND_CONST_(Container)> ContainerView;
- typedef typename ContainerView::type::size_type SizeType;
+ using SizeType = decltype(std::declval<Container>().size());
explicit Impl(const SizeMatcher& size_matcher)
: size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "size ";
size_matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "size ";
size_matcher_.DescribeNegationTo(os);
}
- virtual bool MatchAndExplain(Container container,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(Container container,
+ MatchResultListener* listener) const override {
SizeType size = container.size();
StringMatchResultListener size_listener;
const bool result = size_matcher_.MatchAndExplain(size, &size_listener);
@@ -2458,12 +2015,12 @@
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(new Impl<Container>(distance_matcher_));
+ return Matcher<Container>(new Impl<const Container&>(distance_matcher_));
}
template <typename Container>
class Impl : public MatcherInterface<Container> {
- public:
+ public:
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef internal::StlContainerView<RawContainer> View;
typedef typename View::type StlContainer;
@@ -2475,24 +2032,20 @@
explicit Impl(const DistanceMatcher& distance_matcher)
: distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "distance between begin() and end() ";
distance_matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "distance between begin() and end() ";
distance_matcher_.DescribeNegationTo(os);
}
- virtual bool MatchAndExplain(Container container,
- MatchResultListener* listener) const {
-#if GTEST_HAS_STD_BEGIN_AND_END_
+ bool MatchAndExplain(Container container,
+ MatchResultListener* listener) const override {
using std::begin;
using std::end;
DistanceType distance = std::distance(begin(container), end(container));
-#else
- DistanceType distance = std::distance(container.begin(), container.end());
-#endif
StringMatchResultListener distance_listener;
const bool result =
distance_matcher_.MatchAndExplain(distance, &distance_listener);
@@ -2529,15 +2082,15 @@
typedef typename View::type StlContainer;
typedef typename View::const_reference StlContainerReference;
+ static_assert(!std::is_const<Container>::value,
+ "Container type must not be const");
+ static_assert(!std::is_reference<Container>::value,
+ "Container type must not be a reference");
+
// We make a copy of expected in case the elements in it are modified
// after this matcher is created.
explicit ContainerEqMatcher(const Container& expected)
- : expected_(View::Copy(expected)) {
- // Makes sure the user doesn't instantiate this class template
- // with a const or reference type.
- (void)testing::StaticAssertTypeEq<Container,
- GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>();
- }
+ : expected_(View::Copy(expected)) {}
void DescribeTo(::std::ostream* os) const {
*os << "equals ";
@@ -2551,9 +2104,8 @@
template <typename LhsContainer>
bool MatchAndExplain(const LhsContainer& lhs,
MatchResultListener* listener) const {
- // GTEST_REMOVE_CONST_() is needed to work around an MSVC 8.0 bug
- // that causes LhsContainer to be a const type sometimes.
- typedef internal::StlContainerView<GTEST_REMOVE_CONST_(LhsContainer)>
+ typedef internal::StlContainerView<
+ typename std::remove_const<LhsContainer>::type>
LhsView;
typedef typename LhsView::type LhsStlContainer;
StlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
@@ -2561,7 +2113,7 @@
return true;
::std::ostream* const os = listener->stream();
- if (os != NULL) {
+ if (os != nullptr) {
// Something is different. Check for extra values first.
bool printed_header = false;
for (typename LhsStlContainer::const_iterator it =
@@ -2641,18 +2193,18 @@
Impl(const Comparator& comparator, const ContainerMatcher& matcher)
: comparator_(comparator), matcher_(matcher) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "(when sorted) ";
matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "(when sorted) ";
matcher_.DescribeNegationTo(os);
}
- virtual bool MatchAndExplain(LhsContainer lhs,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(LhsContainer lhs,
+ MatchResultListener* listener) const override {
LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
::std::vector<LhsValue> sorted_container(lhs_stl_container.begin(),
lhs_stl_container.end());
@@ -2691,29 +2243,38 @@
};
// Implements Pointwise(tuple_matcher, rhs_container). tuple_matcher
-// must be able to be safely cast to Matcher<tuple<const T1&, const
+// must be able to be safely cast to Matcher<std::tuple<const T1&, const
// T2&> >, where T1 and T2 are the types of elements in the LHS
// container and the RHS container respectively.
template <typename TupleMatcher, typename RhsContainer>
class PointwiseMatcher {
+ GTEST_COMPILE_ASSERT_(
+ !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>::value,
+ use_UnorderedPointwise_with_hash_tables);
+
public:
typedef internal::StlContainerView<RhsContainer> RhsView;
typedef typename RhsView::type RhsStlContainer;
typedef typename RhsStlContainer::value_type RhsValue;
+ static_assert(!std::is_const<RhsContainer>::value,
+ "RhsContainer type must not be const");
+ static_assert(!std::is_reference<RhsContainer>::value,
+ "RhsContainer type must not be a reference");
+
// Like ContainerEq, we make a copy of rhs in case the elements in
// it are modified after this matcher is created.
PointwiseMatcher(const TupleMatcher& tuple_matcher, const RhsContainer& rhs)
- : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {
- // Makes sure the user doesn't instantiate this class template
- // with a const or reference type.
- (void)testing::StaticAssertTypeEq<RhsContainer,
- GTEST_REMOVE_REFERENCE_AND_CONST_(RhsContainer)>();
- }
+ : tuple_matcher_(tuple_matcher), rhs_(RhsView::Copy(rhs)) {}
template <typename LhsContainer>
operator Matcher<LhsContainer>() const {
- return MakeMatcher(new Impl<LhsContainer>(tuple_matcher_, rhs_));
+ GTEST_COMPILE_ASSERT_(
+ !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(LhsContainer)>::value,
+ use_UnorderedPointwise_with_hash_tables);
+
+ return Matcher<LhsContainer>(
+ new Impl<const LhsContainer&>(tuple_matcher_, rhs_));
}
template <typename LhsContainer>
@@ -2728,21 +2289,21 @@
// reference, as they may be expensive to copy. We must use tuple
// instead of pair here, as a pair cannot hold references (C++ 98,
// 20.2.2 [lib.pairs]).
- typedef ::testing::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;
+ typedef ::std::tuple<const LhsValue&, const RhsValue&> InnerMatcherArg;
Impl(const TupleMatcher& tuple_matcher, const RhsStlContainer& rhs)
// mono_tuple_matcher_ holds a monomorphic version of the tuple matcher.
: mono_tuple_matcher_(SafeMatcherCast<InnerMatcherArg>(tuple_matcher)),
rhs_(rhs) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "contains " << rhs_.size()
<< " values, where each value and its corresponding value in ";
UniversalPrinter<RhsStlContainer>::Print(rhs_, os);
*os << " ";
mono_tuple_matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't contain exactly " << rhs_.size()
<< " values, or contains a value x at some index i"
<< " where x and the i-th value of ";
@@ -2751,8 +2312,8 @@
mono_tuple_matcher_.DescribeNegationTo(os);
}
- virtual bool MatchAndExplain(LhsContainer lhs,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(LhsContainer lhs,
+ MatchResultListener* listener) const override {
LhsStlContainerReference lhs_stl_container = LhsView::ConstReference(lhs);
const size_t actual_size = lhs_stl_container.size();
if (actual_size != rhs_.size()) {
@@ -2763,12 +2324,15 @@
typename LhsStlContainer::const_iterator left = lhs_stl_container.begin();
typename RhsStlContainer::const_iterator right = rhs_.begin();
for (size_t i = 0; i != actual_size; ++i, ++left, ++right) {
- const InnerMatcherArg value_pair(*left, *right);
-
if (listener->IsInterested()) {
StringMatchResultListener inner_listener;
+ // Create InnerMatcherArg as a temporarily object to avoid it outlives
+ // *left and *right. Dereference or the conversion to `const T&` may
+ // return temp objects, e.g for vector<bool>.
if (!mono_tuple_matcher_.MatchAndExplain(
- value_pair, &inner_listener)) {
+ InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
+ ImplicitCast_<const RhsValue&>(*right)),
+ &inner_listener)) {
*listener << "where the value pair (";
UniversalPrint(*left, listener->stream());
*listener << ", ";
@@ -2778,7 +2342,9 @@
return false;
}
} else {
- if (!mono_tuple_matcher_.Matches(value_pair))
+ if (!mono_tuple_matcher_.Matches(
+ InnerMatcherArg(ImplicitCast_<const LhsValue&>(*left),
+ ImplicitCast_<const RhsValue&>(*right))))
return false;
}
}
@@ -2854,18 +2420,18 @@
: QuantifierMatcherImpl<Container>(inner_matcher) {}
// Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "contains at least one element that ";
this->inner_matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't contain any element that ";
this->inner_matcher_.DescribeTo(os);
}
- virtual bool MatchAndExplain(Container container,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(Container container,
+ MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(false, container, listener);
}
@@ -2883,18 +2449,18 @@
: QuantifierMatcherImpl<Container>(inner_matcher) {}
// Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "only contains elements that ";
this->inner_matcher_.DescribeTo(os);
}
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "contains some element that ";
this->inner_matcher_.DescribeNegationTo(os);
}
- virtual bool MatchAndExplain(Container container,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(Container container,
+ MatchResultListener* listener) const override {
return this->MatchAndExplainImpl(true, container, listener);
}
@@ -2910,7 +2476,8 @@
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(new ContainsMatcherImpl<Container>(inner_matcher_));
+ return Matcher<Container>(
+ new ContainsMatcherImpl<const Container&>(inner_matcher_));
}
private:
@@ -2927,7 +2494,8 @@
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(new EachMatcherImpl<Container>(inner_matcher_));
+ return Matcher<Container>(
+ new EachMatcherImpl<const Container&>(inner_matcher_));
}
private:
@@ -2936,6 +2504,30 @@
GTEST_DISALLOW_ASSIGN_(EachMatcher);
};
+struct Rank1 {};
+struct Rank0 : Rank1 {};
+
+namespace pair_getters {
+using std::get;
+template <typename T>
+auto First(T& x, Rank1) -> decltype(get<0>(x)) { // NOLINT
+ return get<0>(x);
+}
+template <typename T>
+auto First(T& x, Rank0) -> decltype((x.first)) { // NOLINT
+ return x.first;
+}
+
+template <typename T>
+auto Second(T& x, Rank1) -> decltype(get<1>(x)) { // NOLINT
+ return get<1>(x);
+}
+template <typename T>
+auto Second(T& x, Rank0) -> decltype((x.second)) { // NOLINT
+ return x.second;
+}
+} // namespace pair_getters
+
// Implements Key(inner_matcher) for the given argument pair type.
// Key(inner_matcher) matches an std::pair whose 'first' field matches
// inner_matcher. For example, Contains(Key(Ge(5))) can be used to match an
@@ -2952,13 +2544,14 @@
testing::SafeMatcherCast<const KeyType&>(inner_matcher)) {
}
- // Returns true iff 'key_value.first' (the key) matches the inner matcher.
- virtual bool MatchAndExplain(PairType key_value,
- MatchResultListener* listener) const {
+ // Returns true if and only if 'key_value.first' (the key) matches the inner
+ // matcher.
+ bool MatchAndExplain(PairType key_value,
+ MatchResultListener* listener) const override {
StringMatchResultListener inner_listener;
- const bool match = inner_matcher_.MatchAndExplain(key_value.first,
- &inner_listener);
- const internal::string explanation = inner_listener.str();
+ const bool match = inner_matcher_.MatchAndExplain(
+ pair_getters::First(key_value, Rank0()), &inner_listener);
+ const std::string explanation = inner_listener.str();
if (explanation != "") {
*listener << "whose first field is a value " << explanation;
}
@@ -2966,13 +2559,13 @@
}
// Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "has a key that ";
inner_matcher_.DescribeTo(os);
}
// Describes what the negation of this matcher does.
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't have a key that ";
inner_matcher_.DescribeTo(os);
}
@@ -2991,7 +2584,8 @@
template <typename PairType>
operator Matcher<PairType>() const {
- return MakeMatcher(new KeyMatcherImpl<PairType>(matcher_for_key_));
+ return Matcher<PairType>(
+ new KeyMatcherImpl<const PairType&>(matcher_for_key_));
}
private:
@@ -3018,7 +2612,7 @@
}
// Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "has a first field that ";
first_matcher_.DescribeTo(os);
*os << ", and has a second field that ";
@@ -3026,32 +2620,32 @@
}
// Describes what the negation of this matcher does.
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
*os << "has a first field that ";
first_matcher_.DescribeNegationTo(os);
*os << ", or has a second field that ";
second_matcher_.DescribeNegationTo(os);
}
- // Returns true iff 'a_pair.first' matches first_matcher and 'a_pair.second'
- // matches second_matcher.
- virtual bool MatchAndExplain(PairType a_pair,
- MatchResultListener* listener) const {
+ // Returns true if and only if 'a_pair.first' matches first_matcher and
+ // 'a_pair.second' matches second_matcher.
+ bool MatchAndExplain(PairType a_pair,
+ MatchResultListener* listener) const override {
if (!listener->IsInterested()) {
// If the listener is not interested, we don't need to construct the
// explanation.
- return first_matcher_.Matches(a_pair.first) &&
- second_matcher_.Matches(a_pair.second);
+ return first_matcher_.Matches(pair_getters::First(a_pair, Rank0())) &&
+ second_matcher_.Matches(pair_getters::Second(a_pair, Rank0()));
}
StringMatchResultListener first_inner_listener;
- if (!first_matcher_.MatchAndExplain(a_pair.first,
+ if (!first_matcher_.MatchAndExplain(pair_getters::First(a_pair, Rank0()),
&first_inner_listener)) {
*listener << "whose first field does not match";
PrintIfNotEmpty(first_inner_listener.str(), listener->stream());
return false;
}
StringMatchResultListener second_inner_listener;
- if (!second_matcher_.MatchAndExplain(a_pair.second,
+ if (!second_matcher_.MatchAndExplain(pair_getters::Second(a_pair, Rank0()),
&second_inner_listener)) {
*listener << "whose second field does not match";
PrintIfNotEmpty(second_inner_listener.str(), listener->stream());
@@ -3063,8 +2657,8 @@
}
private:
- void ExplainSuccess(const internal::string& first_explanation,
- const internal::string& second_explanation,
+ void ExplainSuccess(const std::string& first_explanation,
+ const std::string& second_explanation,
MatchResultListener* listener) const {
*listener << "whose both fields match";
if (first_explanation != "") {
@@ -3096,9 +2690,8 @@
template <typename PairType>
operator Matcher<PairType> () const {
- return MakeMatcher(
- new PairMatcherImpl<PairType>(
- first_matcher_, second_matcher_));
+ return Matcher<PairType>(
+ new PairMatcherImpl<const PairType&>(first_matcher_, second_matcher_));
}
private:
@@ -3118,9 +2711,8 @@
typedef typename View::const_reference StlContainerReference;
typedef decltype(std::begin(
std::declval<StlContainerReference>())) StlContainerConstIterator;
- typedef std::remove_reference_t<decltype(
- *std::declval<StlContainerConstIterator &>())>
- Element;
+ typedef typename std::remove_reference<
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element;
// Constructs the matcher from a sequence of element values or
// element matchers.
@@ -3132,7 +2724,7 @@
}
// Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
if (count() == 0) {
*os << "is empty";
} else if (count() == 1) {
@@ -3151,7 +2743,7 @@
}
// Describes what the negation of this matcher does.
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
if (count() == 0) {
*os << "isn't empty";
return;
@@ -3167,15 +2759,15 @@
}
}
- virtual bool MatchAndExplain(Container container,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(Container container,
+ MatchResultListener* listener) const override {
// To work with stream-like "containers", we must only walk
// through the elements in one pass.
const bool listener_interested = listener->IsInterested();
// explanations[i] is the explanation of the element at index i.
- ::std::vector<internal::string> explanations(count());
+ ::std::vector<std::string> explanations(count());
StlContainerReference stl_container = View::ConstReference(container);
StlContainerConstIterator it = stl_container.begin();
size_t exam_pos = 0;
@@ -3234,7 +2826,7 @@
if (listener_interested) {
bool reason_printed = false;
for (size_t i = 0; i != count(); ++i) {
- const internal::string& s = explanations[i];
+ const std::string& s = explanations[i];
if (!s.empty()) {
if (reason_printed) {
*listener << ",\nand ";
@@ -3287,7 +2879,7 @@
void Randomize();
- string DebugString() const;
+ std::string DebugString() const;
private:
size_t SpaceIndex(size_t ilhs, size_t irhs) const {
@@ -3311,14 +2903,23 @@
GTEST_API_ ElementMatcherPairs
FindMaxBipartiteMatching(const MatchMatrix& g);
-GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
- MatchResultListener* listener);
+struct UnorderedMatcherRequire {
+ enum Flags {
+ Superset = 1 << 0,
+ Subset = 1 << 1,
+ ExactMatch = Superset | Subset,
+ };
+};
// Untyped base class for implementing UnorderedElementsAre. By
// putting logic that's not specific to the element type here, we
// reduce binary bloat and increase compilation speed.
class GTEST_API_ UnorderedElementsAreMatcherImplBase {
protected:
+ explicit UnorderedElementsAreMatcherImplBase(
+ UnorderedMatcherRequire::Flags matcher_flags)
+ : match_flags_(matcher_flags) {}
+
// A vector of matcher describers, one for each element matcher.
// Does not own the describers (and thus can be used only when the
// element matchers are alive).
@@ -3330,10 +2931,12 @@
// Describes the negation of this UnorderedElementsAre matcher.
void DescribeNegationToImpl(::std::ostream* os) const;
- bool VerifyAllElementsAndMatchersAreMatched(
- const ::std::vector<string>& element_printouts,
- const MatchMatrix& matrix,
- MatchResultListener* listener) const;
+ bool VerifyMatchMatrix(const ::std::vector<std::string>& element_printouts,
+ const MatchMatrix& matrix,
+ MatchResultListener* listener) const;
+
+ bool FindPairing(const MatchMatrix& matrix,
+ MatchResultListener* listener) const;
MatcherDescriberVec& matcher_describers() {
return matcher_describers_;
@@ -3343,13 +2946,17 @@
return Message() << n << " element" << (n == 1 ? "" : "s");
}
+ UnorderedMatcherRequire::Flags match_flags() const { return match_flags_; }
+
private:
+ UnorderedMatcherRequire::Flags match_flags_;
MatcherDescriberVec matcher_describers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImplBase);
};
-// Implements unordered ElementsAre and unordered ElementsAreArray.
+// Implements UnorderedElementsAre, UnorderedElementsAreArray, IsSubsetOf, and
+// IsSupersetOf.
template <typename Container>
class UnorderedElementsAreMatcherImpl
: public MatcherInterface<Container>,
@@ -3361,14 +2968,13 @@
typedef typename View::const_reference StlContainerReference;
typedef decltype(std::begin(
std::declval<StlContainerReference>())) StlContainerConstIterator;
- typedef std::remove_reference_t<decltype(
- *std::declval<StlContainerConstIterator &>())>
- Element;
+ typedef typename std::remove_reference<
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element;
- // Constructs the matcher from a sequence of element values or
- // element matchers.
template <typename InputIter>
- UnorderedElementsAreMatcherImpl(InputIter first, InputIter last) {
+ UnorderedElementsAreMatcherImpl(UnorderedMatcherRequire::Flags matcher_flags,
+ InputIter first, InputIter last)
+ : UnorderedElementsAreMatcherImplBase(matcher_flags) {
for (; first != last; ++first) {
matchers_.push_back(MatcherCast<const Element&>(*first));
matcher_describers().push_back(matchers_.back().GetDescriber());
@@ -3376,50 +2982,48 @@
}
// Describes what this matcher does.
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
return UnorderedElementsAreMatcherImplBase::DescribeToImpl(os);
}
// Describes what the negation of this matcher does.
- virtual void DescribeNegationTo(::std::ostream* os) const {
+ void DescribeNegationTo(::std::ostream* os) const override {
return UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(os);
}
- virtual bool MatchAndExplain(Container container,
- MatchResultListener* listener) const {
+ bool MatchAndExplain(Container container,
+ MatchResultListener* listener) const override {
StlContainerReference stl_container = View::ConstReference(container);
- ::std::vector<string> element_printouts;
- MatchMatrix matrix = AnalyzeElements(stl_container.begin(),
- stl_container.end(),
- &element_printouts,
- listener);
+ ::std::vector<std::string> element_printouts;
+ MatchMatrix matrix =
+ AnalyzeElements(stl_container.begin(), stl_container.end(),
+ &element_printouts, listener);
- const size_t actual_count = matrix.LhsSize();
- if (actual_count == 0 && matchers_.empty()) {
+ if (matrix.LhsSize() == 0 && matrix.RhsSize() == 0) {
return true;
}
- if (actual_count != matchers_.size()) {
- // The element count doesn't match. If the container is empty,
- // there's no need to explain anything as Google Mock already
- // prints the empty container. Otherwise we just need to show
- // how many elements there actually are.
- if (actual_count != 0 && listener->IsInterested()) {
- *listener << "which has " << Elements(actual_count);
+
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ if (matrix.LhsSize() != matrix.RhsSize()) {
+ // The element count doesn't match. If the container is empty,
+ // there's no need to explain anything as Google Mock already
+ // prints the empty container. Otherwise we just need to show
+ // how many elements there actually are.
+ if (matrix.LhsSize() != 0 && listener->IsInterested()) {
+ *listener << "which has " << Elements(matrix.LhsSize());
+ }
+ return false;
}
- return false;
}
- return VerifyAllElementsAndMatchersAreMatched(element_printouts,
- matrix, listener) &&
+ return VerifyMatchMatrix(element_printouts, matrix, listener) &&
FindPairing(matrix, listener);
}
private:
- typedef ::std::vector<Matcher<const Element&> > MatcherVec;
-
template <typename ElementIter>
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
- ::std::vector<string>* element_printouts,
+ ::std::vector<std::string>* element_printouts,
MatchResultListener* listener) const {
element_printouts->clear();
::std::vector<char> did_match;
@@ -3443,7 +3047,7 @@
return matrix;
}
- MatcherVec matchers_;
+ ::std::vector<Matcher<const Element&> > matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreMatcherImpl);
};
@@ -3472,16 +3076,17 @@
typedef typename View::const_reference StlContainerReference;
typedef decltype(std::begin(
std::declval<StlContainerReference>())) StlContainerConstIterator;
- typedef std::remove_reference_t<decltype(
- *std::declval<StlContainerConstIterator &>())>
- Element;
+ typedef typename std::remove_reference<
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element;
typedef ::std::vector<Matcher<const Element&> > MatcherVec;
MatcherVec matchers;
- matchers.reserve(::testing::tuple_size<MatcherTuple>::value);
+ matchers.reserve(::std::tuple_size<MatcherTuple>::value);
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers));
- return MakeMatcher(new UnorderedElementsAreMatcherImpl<Container>(
- matchers.begin(), matchers.end()));
+ return Matcher<Container>(
+ new UnorderedElementsAreMatcherImpl<const Container&>(
+ UnorderedMatcherRequire::ExactMatch, matchers.begin(),
+ matchers.end()));
}
private:
@@ -3497,21 +3102,25 @@
template <typename Container>
operator Matcher<Container>() const {
+ GTEST_COMPILE_ASSERT_(
+ !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value ||
+ ::std::tuple_size<MatcherTuple>::value < 2,
+ use_UnorderedElementsAre_with_hash_tables);
+
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef internal::StlContainerView<RawContainer> View;
typedef typename View::const_reference StlContainerReference;
typedef decltype(std::begin(
std::declval<StlContainerReference>())) StlContainerConstIterator;
- typedef std::remove_reference_t<decltype(
- *std::declval<StlContainerConstIterator &>())>
- Element;
+ typedef typename std::remove_reference<
+ decltype(*std::declval<StlContainerConstIterator &>())>::type Element;
typedef ::std::vector<Matcher<const Element&> > MatcherVec;
MatcherVec matchers;
- matchers.reserve(::testing::tuple_size<MatcherTuple>::value);
+ matchers.reserve(::std::tuple_size<MatcherTuple>::value);
TransformTupleValues(CastAndAppendTransform<const Element&>(), matchers_,
::std::back_inserter(matchers));
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(
- matchers.begin(), matchers.end()));
+ return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
+ matchers.begin(), matchers.end()));
}
private:
@@ -3519,24 +3128,24 @@
GTEST_DISALLOW_ASSIGN_(ElementsAreMatcher);
};
-// Implements UnorderedElementsAreArray().
+// Implements UnorderedElementsAreArray(), IsSubsetOf(), and IsSupersetOf().
template <typename T>
class UnorderedElementsAreArrayMatcher {
public:
- UnorderedElementsAreArrayMatcher() {}
-
template <typename Iter>
- UnorderedElementsAreArrayMatcher(Iter first, Iter last)
- : matchers_(first, last) {}
+ UnorderedElementsAreArrayMatcher(UnorderedMatcherRequire::Flags match_flags,
+ Iter first, Iter last)
+ : match_flags_(match_flags), matchers_(first, last) {}
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(
- new UnorderedElementsAreMatcherImpl<Container>(matchers_.begin(),
- matchers_.end()));
+ return Matcher<Container>(
+ new UnorderedElementsAreMatcherImpl<const Container&>(
+ match_flags_, matchers_.begin(), matchers_.end()));
}
private:
+ UnorderedMatcherRequire::Flags match_flags_;
::std::vector<T> matchers_;
GTEST_DISALLOW_ASSIGN_(UnorderedElementsAreArrayMatcher);
@@ -3551,7 +3160,11 @@
template <typename Container>
operator Matcher<Container>() const {
- return MakeMatcher(new ElementsAreMatcherImpl<Container>(
+ GTEST_COMPILE_ASSERT_(
+ !IsHashTable<GTEST_REMOVE_REFERENCE_AND_CONST_(Container)>::value,
+ use_UnorderedElementsAreArray_with_hash_tables);
+
+ return Matcher<Container>(new ElementsAreMatcherImpl<const Container&>(
matchers_.begin(), matchers_.end()));
}
@@ -3563,8 +3176,8 @@
// Given a 2-tuple matcher tm of type Tuple2Matcher and a value second
// of type Second, BoundSecondMatcher<Tuple2Matcher, Second>(tm,
-// second) is a polymorphic matcher that matches a value x iff tm
-// matches tuple (x, second). Useful for implementing
+// second) is a polymorphic matcher that matches a value x if and only if
+// tm matches tuple (x, second). Useful for implementing
// UnorderedPointwise() in terms of UnorderedElementsAreArray().
//
// BoundSecondMatcher is copyable and assignable, as we need to put
@@ -3593,26 +3206,24 @@
GTEST_LOG_(FATAL) << "BoundSecondMatcher should never be assigned.";
}
- BoundSecondMatcher(const BoundSecondMatcher &) = default;
-
private:
template <typename T>
class Impl : public MatcherInterface<T> {
public:
- typedef ::testing::tuple<T, Second> ArgTuple;
+ typedef ::std::tuple<T, Second> ArgTuple;
Impl(const Tuple2Matcher& tm, const Second& second)
: mono_tuple2_matcher_(SafeMatcherCast<const ArgTuple&>(tm)),
second_value_(second) {}
- virtual void DescribeTo(::std::ostream* os) const {
+ void DescribeTo(::std::ostream* os) const override {
*os << "and ";
UniversalPrint(second_value_, os);
*os << " ";
mono_tuple2_matcher_.DescribeTo(os);
}
- virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+ bool MatchAndExplain(T x, MatchResultListener* listener) const override {
return mono_tuple2_matcher_.MatchAndExplain(ArgTuple(x, second_value_),
listener);
}
@@ -3630,8 +3241,8 @@
// Given a 2-tuple matcher tm and a value second,
// MatcherBindSecond(tm, second) returns a matcher that matches a
-// value x iff tm matches tuple (x, second). Useful for implementing
-// UnorderedPointwise() in terms of UnorderedElementsAreArray().
+// value x if and only if tm matches tuple (x, second). Useful for
+// implementing UnorderedPointwise() in terms of UnorderedElementsAreArray().
template <typename Tuple2Matcher, typename Second>
BoundSecondMatcher<Tuple2Matcher, Second> MatcherBindSecond(
const Tuple2Matcher& tm, const Second& second) {
@@ -3643,13 +3254,264 @@
// 'negation' is false; otherwise returns the description of the
// negation of the matcher. 'param_values' contains a list of strings
// that are the print-out of the matcher's parameters.
-GTEST_API_ string FormatMatcherDescription(bool negation,
- const char* matcher_name,
- const Strings& param_values);
+GTEST_API_ std::string FormatMatcherDescription(bool negation,
+ const char* matcher_name,
+ const Strings& param_values);
+
+// Implements a matcher that checks the value of a optional<> type variable.
+template <typename ValueMatcher>
+class OptionalMatcher {
+ public:
+ explicit OptionalMatcher(const ValueMatcher& value_matcher)
+ : value_matcher_(value_matcher) {}
+
+ template <typename Optional>
+ operator Matcher<Optional>() const {
+ return Matcher<Optional>(new Impl<const Optional&>(value_matcher_));
+ }
+
+ template <typename Optional>
+ class Impl : public MatcherInterface<Optional> {
+ public:
+ typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Optional) OptionalView;
+ typedef typename OptionalView::value_type ValueType;
+ explicit Impl(const ValueMatcher& value_matcher)
+ : value_matcher_(MatcherCast<ValueType>(value_matcher)) {}
+
+ void DescribeTo(::std::ostream* os) const override {
+ *os << "value ";
+ value_matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const override {
+ *os << "value ";
+ value_matcher_.DescribeNegationTo(os);
+ }
+
+ bool MatchAndExplain(Optional optional,
+ MatchResultListener* listener) const override {
+ if (!optional) {
+ *listener << "which is not engaged";
+ return false;
+ }
+ const ValueType& value = *optional;
+ StringMatchResultListener value_listener;
+ const bool match = value_matcher_.MatchAndExplain(value, &value_listener);
+ *listener << "whose value " << PrintToString(value)
+ << (match ? " matches" : " doesn't match");
+ PrintIfNotEmpty(value_listener.str(), listener->stream());
+ return match;
+ }
+
+ private:
+ const Matcher<ValueType> value_matcher_;
+ GTEST_DISALLOW_ASSIGN_(Impl);
+ };
+
+ private:
+ const ValueMatcher value_matcher_;
+ GTEST_DISALLOW_ASSIGN_(OptionalMatcher);
+};
+
+namespace variant_matcher {
+// Overloads to allow VariantMatcher to do proper ADL lookup.
+template <typename T>
+void holds_alternative() {}
+template <typename T>
+void get() {}
+
+// Implements a matcher that checks the value of a variant<> type variable.
+template <typename T>
+class VariantMatcher {
+ public:
+ explicit VariantMatcher(::testing::Matcher<const T&> matcher)
+ : matcher_(std::move(matcher)) {}
+
+ template <typename Variant>
+ bool MatchAndExplain(const Variant& value,
+ ::testing::MatchResultListener* listener) const {
+ using std::get;
+ if (!listener->IsInterested()) {
+ return holds_alternative<T>(value) && matcher_.Matches(get<T>(value));
+ }
+
+ if (!holds_alternative<T>(value)) {
+ *listener << "whose value is not of type '" << GetTypeName() << "'";
+ return false;
+ }
+
+ const T& elem = get<T>(value);
+ StringMatchResultListener elem_listener;
+ const bool match = matcher_.MatchAndExplain(elem, &elem_listener);
+ *listener << "whose value " << PrintToString(elem)
+ << (match ? " matches" : " doesn't match");
+ PrintIfNotEmpty(elem_listener.str(), listener->stream());
+ return match;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "is a variant<> with value of type '" << GetTypeName()
+ << "' and the value ";
+ matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const {
+ *os << "is a variant<> with value of type other than '" << GetTypeName()
+ << "' or the value ";
+ matcher_.DescribeNegationTo(os);
+ }
+
+ private:
+ static std::string GetTypeName() {
+#if GTEST_HAS_RTTI
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
+ return internal::GetTypeName<T>());
+#endif
+ return "the element type";
+ }
+
+ const ::testing::Matcher<const T&> matcher_;
+};
+
+} // namespace variant_matcher
+
+namespace any_cast_matcher {
+
+// Overloads to allow AnyCastMatcher to do proper ADL lookup.
+template <typename T>
+void any_cast() {}
+
+// Implements a matcher that any_casts the value.
+template <typename T>
+class AnyCastMatcher {
+ public:
+ explicit AnyCastMatcher(const ::testing::Matcher<const T&>& matcher)
+ : matcher_(matcher) {}
+
+ template <typename AnyType>
+ bool MatchAndExplain(const AnyType& value,
+ ::testing::MatchResultListener* listener) const {
+ if (!listener->IsInterested()) {
+ const T* ptr = any_cast<T>(&value);
+ return ptr != nullptr && matcher_.Matches(*ptr);
+ }
+
+ const T* elem = any_cast<T>(&value);
+ if (elem == nullptr) {
+ *listener << "whose value is not of type '" << GetTypeName() << "'";
+ return false;
+ }
+
+ StringMatchResultListener elem_listener;
+ const bool match = matcher_.MatchAndExplain(*elem, &elem_listener);
+ *listener << "whose value " << PrintToString(*elem)
+ << (match ? " matches" : " doesn't match");
+ PrintIfNotEmpty(elem_listener.str(), listener->stream());
+ return match;
+ }
+
+ void DescribeTo(std::ostream* os) const {
+ *os << "is an 'any' type with value of type '" << GetTypeName()
+ << "' and the value ";
+ matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(std::ostream* os) const {
+ *os << "is an 'any' type with value of type other than '" << GetTypeName()
+ << "' or the value ";
+ matcher_.DescribeNegationTo(os);
+ }
+
+ private:
+ static std::string GetTypeName() {
+#if GTEST_HAS_RTTI
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(
+ return internal::GetTypeName<T>());
+#endif
+ return "the element type";
+ }
+
+ const ::testing::Matcher<const T&> matcher_;
+};
+
+} // namespace any_cast_matcher
+
+// Implements the Args() matcher.
+template <class ArgsTuple, size_t... k>
+class ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
+ public:
+ using RawArgsTuple = typename std::decay<ArgsTuple>::type;
+ using SelectedArgs =
+ std::tuple<typename std::tuple_element<k, RawArgsTuple>::type...>;
+ using MonomorphicInnerMatcher = Matcher<const SelectedArgs&>;
+
+ template <typename InnerMatcher>
+ explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher)
+ : inner_matcher_(SafeMatcherCast<const SelectedArgs&>(inner_matcher)) {}
+
+ bool MatchAndExplain(ArgsTuple args,
+ MatchResultListener* listener) const override {
+ // Workaround spurious C4100 on MSVC<=15.7 when k is empty.
+ (void)args;
+ const SelectedArgs& selected_args =
+ std::forward_as_tuple(std::get<k>(args)...);
+ if (!listener->IsInterested()) return inner_matcher_.Matches(selected_args);
+
+ PrintIndices(listener->stream());
+ *listener << "are " << PrintToString(selected_args);
+
+ StringMatchResultListener inner_listener;
+ const bool match =
+ inner_matcher_.MatchAndExplain(selected_args, &inner_listener);
+ PrintIfNotEmpty(inner_listener.str(), listener->stream());
+ return match;
+ }
+
+ void DescribeTo(::std::ostream* os) const override {
+ *os << "are a tuple ";
+ PrintIndices(os);
+ inner_matcher_.DescribeTo(os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const override {
+ *os << "are a tuple ";
+ PrintIndices(os);
+ inner_matcher_.DescribeNegationTo(os);
+ }
+
+ private:
+ // Prints the indices of the selected fields.
+ static void PrintIndices(::std::ostream* os) {
+ *os << "whose fields (";
+ const char* sep = "";
+ // Workaround spurious C4189 on MSVC<=15.7 when k is empty.
+ (void)sep;
+ const char* dummy[] = {"", (*os << sep << "#" << k, sep = ", ")...};
+ (void)dummy;
+ *os << ") ";
+ }
+
+ MonomorphicInnerMatcher inner_matcher_;
+};
+
+template <class InnerMatcher, size_t... k>
+class ArgsMatcher {
+ public:
+ explicit ArgsMatcher(InnerMatcher inner_matcher)
+ : inner_matcher_(std::move(inner_matcher)) {}
+
+ template <typename ArgsTuple>
+ operator Matcher<ArgsTuple>() const { // NOLINT
+ return MakeMatcher(new ArgsMatcherImpl<ArgsTuple, k...>(inner_matcher_));
+ }
+
+ private:
+ InnerMatcher inner_matcher_;
+};
} // namespace internal
-// ElementsAreArray(first, last)
+// ElementsAreArray(iterator_first, iterator_last)
// ElementsAreArray(pointer, count)
// ElementsAreArray(array)
// ElementsAreArray(container)
@@ -3690,28 +3552,32 @@
return ElementsAreArray(container.begin(), container.end());
}
-#if GTEST_HAS_STD_INITIALIZER_LIST_
template <typename T>
inline internal::ElementsAreArrayMatcher<T>
ElementsAreArray(::std::initializer_list<T> xs) {
return ElementsAreArray(xs.begin(), xs.end());
}
-#endif
-// UnorderedElementsAreArray(first, last)
+// UnorderedElementsAreArray(iterator_first, iterator_last)
// UnorderedElementsAreArray(pointer, count)
// UnorderedElementsAreArray(array)
// UnorderedElementsAreArray(container)
// UnorderedElementsAreArray({ e1, e2, ..., en })
//
-// The UnorderedElementsAreArray() functions are like
-// ElementsAreArray(...), but allow matching the elements in any order.
+// UnorderedElementsAreArray() verifies that a bijective mapping onto a
+// collection of matchers exists.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
template <typename Iter>
inline internal::UnorderedElementsAreArrayMatcher<
typename ::std::iterator_traits<Iter>::value_type>
UnorderedElementsAreArray(Iter first, Iter last) {
typedef typename ::std::iterator_traits<Iter>::value_type T;
- return internal::UnorderedElementsAreArrayMatcher<T>(first, last);
+ return internal::UnorderedElementsAreArrayMatcher<T>(
+ internal::UnorderedMatcherRequire::ExactMatch, first, last);
}
template <typename T>
@@ -3733,13 +3599,11 @@
return UnorderedElementsAreArray(container.begin(), container.end());
}
-#if GTEST_HAS_STD_INITIALIZER_LIST_
template <typename T>
inline internal::UnorderedElementsAreArrayMatcher<T>
UnorderedElementsAreArray(::std::initializer_list<T> xs) {
return UnorderedElementsAreArray(xs.begin(), xs.end());
}
-#endif
// _ is a matcher that matches anything of any type.
//
@@ -3753,66 +3617,19 @@
const internal::AnythingMatcher _ = {};
// Creates a matcher that matches any value of the given type T.
template <typename T>
-inline Matcher<T> A() { return MakeMatcher(new internal::AnyMatcherImpl<T>()); }
+inline Matcher<T> A() {
+ return Matcher<T>(new internal::AnyMatcherImpl<T>());
+}
// Creates a matcher that matches any value of the given type T.
template <typename T>
inline Matcher<T> An() { return A<T>(); }
-// Creates a polymorphic matcher that matches anything equal to x.
-// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
-// wouldn't compile.
-template <typename T>
-inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
-
-// Constructs a Matcher<T> from a 'value' of type T. The constructed
-// matcher matches any value that's equal to 'value'.
-template <typename T>
-Matcher<T>::Matcher(T value) { *this = Eq(value); }
-
-// Creates a monomorphic matcher that matches anything with type Lhs
-// and equal to rhs. A user may need to use this instead of Eq(...)
-// in order to resolve an overloading ambiguity.
-//
-// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
-// or Matcher<T>(x), but more readable than the latter.
-//
-// We could define similar monomorphic matchers for other comparison
-// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
-// it yet as those are used much less than Eq() in practice. A user
-// can always write Matcher<T>(Lt(5)) to be explicit about the type,
-// for example.
-template <typename Lhs, typename Rhs>
-inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
-
-// Creates a polymorphic matcher that matches anything >= x.
-template <typename Rhs>
-inline internal::GeMatcher<Rhs> Ge(Rhs x) {
- return internal::GeMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything > x.
-template <typename Rhs>
-inline internal::GtMatcher<Rhs> Gt(Rhs x) {
- return internal::GtMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything <= x.
-template <typename Rhs>
-inline internal::LeMatcher<Rhs> Le(Rhs x) {
- return internal::LeMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything < x.
-template <typename Rhs>
-inline internal::LtMatcher<Rhs> Lt(Rhs x) {
- return internal::LtMatcher<Rhs>(x);
-}
-
-// Creates a polymorphic matcher that matches anything != x.
-template <typename Rhs>
-inline internal::NeMatcher<Rhs> Ne(Rhs x) {
- return internal::NeMatcher<Rhs>(x);
+template <typename T, typename M>
+Matcher<T> internal::MatcherCastImpl<T, M>::CastImpl(
+ const M& value, std::false_type /* convertible_to_matcher */,
+ std::false_type /* convertible_to_T */) {
+ return Eq(value);
}
// Creates a polymorphic matcher that matches any NULL pointer.
@@ -3898,6 +3715,7 @@
return internal::PointeeMatcher<InnerMatcher>(inner_matcher);
}
+#if GTEST_HAS_RTTI
// Creates a matcher that matches a pointer or reference that matches
// inner_matcher when dynamic_cast<To> is applied.
// The result of dynamic_cast<To> is forwarded to the inner matcher.
@@ -3910,11 +3728,12 @@
return MakePolymorphicMatcher(
internal::WhenDynamicCastToMatcher<To>(inner_matcher));
}
+#endif // GTEST_HAS_RTTI
// Creates a matcher that matches an object whose given field matches
// 'matcher'. For example,
// Field(&Foo::number, Ge(5))
-// matches a Foo object x iff x.number >= 5.
+// matches a Foo object x if and only if x.number >= 5.
template <typename Class, typename FieldType, typename FieldMatcher>
inline PolymorphicMatcher<
internal::FieldMatcher<Class, FieldType> > Field(
@@ -3928,178 +3747,194 @@
// to compile where bar is an int32 and m is a matcher for int64.
}
+// Same as Field() but also takes the name of the field to provide better error
+// messages.
+template <typename Class, typename FieldType, typename FieldMatcher>
+inline PolymorphicMatcher<internal::FieldMatcher<Class, FieldType> > Field(
+ const std::string& field_name, FieldType Class::*field,
+ const FieldMatcher& matcher) {
+ return MakePolymorphicMatcher(internal::FieldMatcher<Class, FieldType>(
+ field_name, field, MatcherCast<const FieldType&>(matcher)));
+}
+
// Creates a matcher that matches an object whose given property
// matches 'matcher'. For example,
// Property(&Foo::str, StartsWith("hi"))
-// matches a Foo object x iff x.str() starts with "hi".
+// matches a Foo object x if and only if x.str() starts with "hi".
template <typename Class, typename PropertyType, typename PropertyMatcher>
-inline PolymorphicMatcher<
- internal::PropertyMatcher<Class, PropertyType> > Property(
- PropertyType (Class::*property)() const, const PropertyMatcher& matcher) {
+inline PolymorphicMatcher<internal::PropertyMatcher<
+ Class, PropertyType, PropertyType (Class::*)() const> >
+Property(PropertyType (Class::*property)() const,
+ const PropertyMatcher& matcher) {
return MakePolymorphicMatcher(
- internal::PropertyMatcher<Class, PropertyType>(
- property,
- MatcherCast<GTEST_REFERENCE_TO_CONST_(PropertyType)>(matcher)));
+ internal::PropertyMatcher<Class, PropertyType,
+ PropertyType (Class::*)() const>(
+ property, MatcherCast<const PropertyType&>(matcher)));
// The call to MatcherCast() is required for supporting inner
// matchers of compatible types. For example, it allows
// Property(&Foo::bar, m)
// to compile where bar() returns an int32 and m is a matcher for int64.
}
-// Creates a matcher that matches an object iff the result of applying
-// a callable to x matches 'matcher'.
-// For example,
+// Same as Property() above, but also takes the name of the property to provide
+// better error messages.
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+ Class, PropertyType, PropertyType (Class::*)() const> >
+Property(const std::string& property_name,
+ PropertyType (Class::*property)() const,
+ const PropertyMatcher& matcher) {
+ return MakePolymorphicMatcher(
+ internal::PropertyMatcher<Class, PropertyType,
+ PropertyType (Class::*)() const>(
+ property_name, property, MatcherCast<const PropertyType&>(matcher)));
+}
+
+// The same as above but for reference-qualified member functions.
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+ Class, PropertyType, PropertyType (Class::*)() const &> >
+Property(PropertyType (Class::*property)() const &,
+ const PropertyMatcher& matcher) {
+ return MakePolymorphicMatcher(
+ internal::PropertyMatcher<Class, PropertyType,
+ PropertyType (Class::*)() const&>(
+ property, MatcherCast<const PropertyType&>(matcher)));
+}
+
+// Three-argument form for reference-qualified member functions.
+template <typename Class, typename PropertyType, typename PropertyMatcher>
+inline PolymorphicMatcher<internal::PropertyMatcher<
+ Class, PropertyType, PropertyType (Class::*)() const &> >
+Property(const std::string& property_name,
+ PropertyType (Class::*property)() const &,
+ const PropertyMatcher& matcher) {
+ return MakePolymorphicMatcher(
+ internal::PropertyMatcher<Class, PropertyType,
+ PropertyType (Class::*)() const&>(
+ property_name, property, MatcherCast<const PropertyType&>(matcher)));
+}
+
+// Creates a matcher that matches an object if and only if the result of
+// applying a callable to x matches 'matcher'. For example,
// ResultOf(f, StartsWith("hi"))
-// matches a Foo object x iff f(x) starts with "hi".
-// callable parameter can be a function, function pointer, or a functor.
-// Callable has to satisfy the following conditions:
-// * It is required to keep no state affecting the results of
-// the calls on it and make no assumptions about how many calls
-// will be made. Any state it keeps must be protected from the
-// concurrent access.
-// * If it is a function object, it has to define type result_type.
-// We recommend deriving your functor classes from std::unary_function.
-template <typename Callable, typename ResultOfMatcher>
-internal::ResultOfMatcher<Callable> ResultOf(
- Callable callable, const ResultOfMatcher& matcher) {
- return internal::ResultOfMatcher<Callable>(
- callable,
- MatcherCast<typename internal::CallableTraits<Callable>::ResultType>(
- matcher));
- // The call to MatcherCast() is required for supporting inner
- // matchers of compatible types. For example, it allows
- // ResultOf(Function, m)
- // to compile where Function() returns an int32 and m is a matcher for int64.
+// matches a Foo object x if and only if f(x) starts with "hi".
+// `callable` parameter can be a function, function pointer, or a functor. It is
+// required to keep no state affecting the results of the calls on it and make
+// no assumptions about how many calls will be made. Any state it keeps must be
+// protected from the concurrent access.
+template <typename Callable, typename InnerMatcher>
+internal::ResultOfMatcher<Callable, InnerMatcher> ResultOf(
+ Callable callable, InnerMatcher matcher) {
+ return internal::ResultOfMatcher<Callable, InnerMatcher>(
+ std::move(callable), std::move(matcher));
}
// String matchers.
// Matches a string equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
- StrEq(const internal::string& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
- str, true, true));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrEq(
+ const std::string& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::string>(str, true, true));
}
// Matches a string not equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
- StrNe(const internal::string& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
- str, false, true));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrNe(
+ const std::string& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::string>(str, false, true));
}
// Matches a string equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
- StrCaseEq(const internal::string& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
- str, true, false));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseEq(
+ const std::string& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::string>(str, true, false));
}
// Matches a string not equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::string> >
- StrCaseNe(const internal::string& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::string>(
- str, false, false));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::string> > StrCaseNe(
+ const std::string& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::string>(str, false, false));
}
// Creates a matcher that matches any string, std::string, or C string
// that contains the given substring.
-inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::string> >
- HasSubstr(const internal::string& substring) {
- return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::string>(
- substring));
+inline PolymorphicMatcher<internal::HasSubstrMatcher<std::string> > HasSubstr(
+ const std::string& substring) {
+ return MakePolymorphicMatcher(
+ internal::HasSubstrMatcher<std::string>(substring));
}
// Matches a string that starts with 'prefix' (case-sensitive).
-inline PolymorphicMatcher<internal::StartsWithMatcher<internal::string> >
- StartsWith(const internal::string& prefix) {
- return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::string>(
- prefix));
+inline PolymorphicMatcher<internal::StartsWithMatcher<std::string> > StartsWith(
+ const std::string& prefix) {
+ return MakePolymorphicMatcher(
+ internal::StartsWithMatcher<std::string>(prefix));
}
// Matches a string that ends with 'suffix' (case-sensitive).
-inline PolymorphicMatcher<internal::EndsWithMatcher<internal::string> >
- EndsWith(const internal::string& suffix) {
- return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::string>(
- suffix));
+inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
+ const std::string& suffix) {
+ return MakePolymorphicMatcher(internal::EndsWithMatcher<std::string>(suffix));
}
-// Matches a string that fully matches regular expression 'regex'.
-// The matcher takes ownership of 'regex'.
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
- const internal::RE* regex) {
- return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
-}
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
- const internal::string& regex) {
- return MatchesRegex(new internal::RE(regex));
-}
-
-// Matches a string that contains regular expression 'regex'.
-// The matcher takes ownership of 'regex'.
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
- const internal::RE* regex) {
- return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
-}
-inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
- const internal::string& regex) {
- return ContainsRegex(new internal::RE(regex));
-}
-
-#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
+#if GTEST_HAS_STD_WSTRING
// Wide string matchers.
// Matches a string equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
- StrEq(const internal::wstring& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
- str, true, true));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrEq(
+ const std::wstring& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::wstring>(str, true, true));
}
// Matches a string not equal to str.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
- StrNe(const internal::wstring& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
- str, false, true));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> > StrNe(
+ const std::wstring& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::wstring>(str, false, true));
}
// Matches a string equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
- StrCaseEq(const internal::wstring& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
- str, true, false));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
+StrCaseEq(const std::wstring& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::wstring>(str, true, false));
}
// Matches a string not equal to str, ignoring case.
-inline PolymorphicMatcher<internal::StrEqualityMatcher<internal::wstring> >
- StrCaseNe(const internal::wstring& str) {
- return MakePolymorphicMatcher(internal::StrEqualityMatcher<internal::wstring>(
- str, false, false));
+inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring> >
+StrCaseNe(const std::wstring& str) {
+ return MakePolymorphicMatcher(
+ internal::StrEqualityMatcher<std::wstring>(str, false, false));
}
-// Creates a matcher that matches any wstring, std::wstring, or C wide string
+// Creates a matcher that matches any ::wstring, std::wstring, or C wide string
// that contains the given substring.
-inline PolymorphicMatcher<internal::HasSubstrMatcher<internal::wstring> >
- HasSubstr(const internal::wstring& substring) {
- return MakePolymorphicMatcher(internal::HasSubstrMatcher<internal::wstring>(
- substring));
+inline PolymorphicMatcher<internal::HasSubstrMatcher<std::wstring> > HasSubstr(
+ const std::wstring& substring) {
+ return MakePolymorphicMatcher(
+ internal::HasSubstrMatcher<std::wstring>(substring));
}
// Matches a string that starts with 'prefix' (case-sensitive).
-inline PolymorphicMatcher<internal::StartsWithMatcher<internal::wstring> >
- StartsWith(const internal::wstring& prefix) {
- return MakePolymorphicMatcher(internal::StartsWithMatcher<internal::wstring>(
- prefix));
+inline PolymorphicMatcher<internal::StartsWithMatcher<std::wstring> >
+StartsWith(const std::wstring& prefix) {
+ return MakePolymorphicMatcher(
+ internal::StartsWithMatcher<std::wstring>(prefix));
}
// Matches a string that ends with 'suffix' (case-sensitive).
-inline PolymorphicMatcher<internal::EndsWithMatcher<internal::wstring> >
- EndsWith(const internal::wstring& suffix) {
- return MakePolymorphicMatcher(internal::EndsWithMatcher<internal::wstring>(
- suffix));
+inline PolymorphicMatcher<internal::EndsWithMatcher<std::wstring> > EndsWith(
+ const std::wstring& suffix) {
+ return MakePolymorphicMatcher(
+ internal::EndsWithMatcher<std::wstring>(suffix));
}
-#endif // GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
+#endif // GTEST_HAS_STD_WSTRING
// Creates a polymorphic matcher that matches a 2-tuple where the
// first field == the second field.
@@ -4125,6 +3960,58 @@
// first field != the second field.
inline internal::Ne2Matcher Ne() { return internal::Ne2Matcher(); }
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatEq(first field) matches the second field.
+inline internal::FloatingEq2Matcher<float> FloatEq() {
+ return internal::FloatingEq2Matcher<float>();
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleEq(first field) matches the second field.
+inline internal::FloatingEq2Matcher<double> DoubleEq() {
+ return internal::FloatingEq2Matcher<double>();
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatEq(first field) matches the second field with NaN equality.
+inline internal::FloatingEq2Matcher<float> NanSensitiveFloatEq() {
+ return internal::FloatingEq2Matcher<float>(true);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleEq(first field) matches the second field with NaN equality.
+inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleEq() {
+ return internal::FloatingEq2Matcher<double>(true);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatNear(first field, max_abs_error) matches the second field.
+inline internal::FloatingEq2Matcher<float> FloatNear(float max_abs_error) {
+ return internal::FloatingEq2Matcher<float>(max_abs_error);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleNear(first field, max_abs_error) matches the second field.
+inline internal::FloatingEq2Matcher<double> DoubleNear(double max_abs_error) {
+ return internal::FloatingEq2Matcher<double>(max_abs_error);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// FloatNear(first field, max_abs_error) matches the second field with NaN
+// equality.
+inline internal::FloatingEq2Matcher<float> NanSensitiveFloatNear(
+ float max_abs_error) {
+ return internal::FloatingEq2Matcher<float>(max_abs_error, true);
+}
+
+// Creates a polymorphic matcher that matches a 2-tuple where
+// DoubleNear(first field, max_abs_error) matches the second field with NaN
+// equality.
+inline internal::FloatingEq2Matcher<double> NanSensitiveDoubleNear(
+ double max_abs_error) {
+ return internal::FloatingEq2Matcher<double>(max_abs_error, true);
+}
+
// Creates a matcher that matches any value of type T that m doesn't
// match.
template <typename InnerMatcher>
@@ -4169,12 +4056,12 @@
// values that are included in one container but not the other. (Duplicate
// values and order differences are not explained.)
template <typename Container>
-inline PolymorphicMatcher<internal::ContainerEqMatcher< // NOLINT
- GTEST_REMOVE_CONST_(Container)> >
- ContainerEq(const Container& rhs) {
+inline PolymorphicMatcher<internal::ContainerEqMatcher<
+ typename std::remove_const<Container>::type>>
+ContainerEq(const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0,
// which causes Container to be a const type sometimes.
- typedef GTEST_REMOVE_CONST_(Container) RawContainer;
+ typedef typename std::remove_const<Container>::type RawContainer;
return MakePolymorphicMatcher(
internal::ContainerEqMatcher<RawContainer>(rhs));
}
@@ -4202,22 +4089,21 @@
// Matches an STL-style container or a native array that contains the
// same number of elements as in rhs, where its i-th element and rhs's
// i-th element (as a pair) satisfy the given pair matcher, for all i.
-// TupleMatcher must be able to be safely cast to Matcher<tuple<const
+// TupleMatcher must be able to be safely cast to Matcher<std::tuple<const
// T1&, const T2&> >, where T1 and T2 are the types of elements in the
// LHS container and the RHS container respectively.
template <typename TupleMatcher, typename Container>
inline internal::PointwiseMatcher<TupleMatcher,
- GTEST_REMOVE_CONST_(Container)>
+ typename std::remove_const<Container>::type>
Pointwise(const TupleMatcher& tuple_matcher, const Container& rhs) {
// This following line is for working around a bug in MSVC 8.0,
// which causes Container to be a const type sometimes (e.g. when
// rhs is a const int[])..
- typedef GTEST_REMOVE_CONST_(Container) RawContainer;
+ typedef typename std::remove_const<Container>::type RawContainer;
return internal::PointwiseMatcher<TupleMatcher, RawContainer>(
tuple_matcher, rhs);
}
-#if GTEST_HAS_STD_INITIALIZER_LIST_
// Supports the Pointwise(m, {a, b, c}) syntax.
template <typename TupleMatcher, typename T>
@@ -4226,14 +4112,13 @@
return Pointwise(tuple_matcher, std::vector<T>(rhs));
}
-#endif // GTEST_HAS_STD_INITIALIZER_LIST_
// UnorderedPointwise(pair_matcher, rhs) matches an STL-style
// container or a native array that contains the same number of
// elements as in rhs, where in some permutation of the container, its
// i-th element and rhs's i-th element (as a pair) satisfy the given
// pair matcher, for all i. Tuple2Matcher must be able to be safely
-// cast to Matcher<tuple<const T1&, const T2&> >, where T1 and T2 are
+// cast to Matcher<std::tuple<const T1&, const T2&> >, where T1 and T2 are
// the types of elements in the LHS container and the RHS container
// respectively.
//
@@ -4242,14 +4127,15 @@
template <typename Tuple2Matcher, typename RhsContainer>
inline internal::UnorderedElementsAreArrayMatcher<
typename internal::BoundSecondMatcher<
- Tuple2Matcher, typename internal::StlContainerView<GTEST_REMOVE_CONST_(
- RhsContainer)>::type::value_type> >
+ Tuple2Matcher,
+ typename internal::StlContainerView<
+ typename std::remove_const<RhsContainer>::type>::type::value_type>>
UnorderedPointwise(const Tuple2Matcher& tuple2_matcher,
const RhsContainer& rhs_container) {
// This following line is for working around a bug in MSVC 8.0,
// which causes RhsContainer to be a const type sometimes (e.g. when
// rhs_container is a const int[]).
- typedef GTEST_REMOVE_CONST_(RhsContainer) RawRhsContainer;
+ typedef typename std::remove_const<RhsContainer>::type RawRhsContainer;
// RhsView allows the same code to handle RhsContainer being a
// STL-style container and it being a native C-style array.
@@ -4271,7 +4157,6 @@
return UnorderedElementsAreArray(matchers);
}
-#if GTEST_HAS_STD_INITIALIZER_LIST_
// Supports the UnorderedPointwise(m, {a, b, c}) syntax.
template <typename Tuple2Matcher, typename T>
@@ -4282,7 +4167,6 @@
return UnorderedPointwise(tuple2_matcher, std::vector<T>(rhs));
}
-#endif // GTEST_HAS_STD_INITIALIZER_LIST_
// Matches an STL-style container or a native array that contains at
// least one element matching the given value or matcher.
@@ -4307,6 +4191,124 @@
return internal::ContainsMatcher<M>(matcher);
}
+// IsSupersetOf(iterator_first, iterator_last)
+// IsSupersetOf(pointer, count)
+// IsSupersetOf(array)
+// IsSupersetOf(container)
+// IsSupersetOf({e1, e2, ..., en})
+//
+// IsSupersetOf() verifies that a surjective partial mapping onto a collection
+// of matchers exists. In other words, a container matches
+// IsSupersetOf({e1, ..., en}) if and only if there is a permutation
+// {y1, ..., yn} of some of the container's elements where y1 matches e1,
+// ..., and yn matches en. Obviously, the size of the container must be >= n
+// in order to have a match. Examples:
+//
+// - {1, 2, 3} matches IsSupersetOf({Ge(3), Ne(0)}), as 3 matches Ge(3) and
+// 1 matches Ne(0).
+// - {1, 2} doesn't match IsSupersetOf({Eq(1), Lt(2)}), even though 1 matches
+// both Eq(1) and Lt(2). The reason is that different matchers must be used
+// for elements in different slots of the container.
+// - {1, 1, 2} matches IsSupersetOf({Eq(1), Lt(2)}), as (the first) 1 matches
+// Eq(1) and (the second) 1 matches Lt(2).
+// - {1, 2, 3} matches IsSupersetOf(Gt(1), Gt(1)), as 2 matches (the first)
+// Gt(1) and 3 matches (the second) Gt(1).
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>
+IsSupersetOf(Iter first, Iter last) {
+ typedef typename ::std::iterator_traits<Iter>::value_type T;
+ return internal::UnorderedElementsAreArrayMatcher<T>(
+ internal::UnorderedMatcherRequire::Superset, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+ const T* pointer, size_t count) {
+ return IsSupersetOf(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+ const T (&array)[N]) {
+ return IsSupersetOf(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename Container::value_type>
+IsSupersetOf(const Container& container) {
+ return IsSupersetOf(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSupersetOf(
+ ::std::initializer_list<T> xs) {
+ return IsSupersetOf(xs.begin(), xs.end());
+}
+
+// IsSubsetOf(iterator_first, iterator_last)
+// IsSubsetOf(pointer, count)
+// IsSubsetOf(array)
+// IsSubsetOf(container)
+// IsSubsetOf({e1, e2, ..., en})
+//
+// IsSubsetOf() verifies that an injective mapping onto a collection of matchers
+// exists. In other words, a container matches IsSubsetOf({e1, ..., en}) if and
+// only if there is a subset of matchers {m1, ..., mk} which would match the
+// container using UnorderedElementsAre. Obviously, the size of the container
+// must be <= n in order to have a match. Examples:
+//
+// - {1} matches IsSubsetOf({Gt(0), Lt(0)}), as 1 matches Gt(0).
+// - {1, -1} matches IsSubsetOf({Lt(0), Gt(0)}), as 1 matches Gt(0) and -1
+// matches Lt(0).
+// - {1, 2} doesn't matches IsSubsetOf({Gt(0), Lt(0)}), even though 1 and 2 both
+// match Gt(0). The reason is that different matchers must be used for
+// elements in different slots of the container.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>
+IsSubsetOf(Iter first, Iter last) {
+ typedef typename ::std::iterator_traits<Iter>::value_type T;
+ return internal::UnorderedElementsAreArrayMatcher<T>(
+ internal::UnorderedMatcherRequire::Subset, first, last);
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+ const T* pointer, size_t count) {
+ return IsSubsetOf(pointer, pointer + count);
+}
+
+template <typename T, size_t N>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+ const T (&array)[N]) {
+ return IsSubsetOf(array, N);
+}
+
+template <typename Container>
+inline internal::UnorderedElementsAreArrayMatcher<
+ typename Container::value_type>
+IsSubsetOf(const Container& container) {
+ return IsSubsetOf(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::UnorderedElementsAreArrayMatcher<T> IsSubsetOf(
+ ::std::initializer_list<T> xs) {
+ return IsSubsetOf(xs.begin(), xs.end());
+}
+
// Matches an STL-style container or a native array that contains only
// elements matching the given value or matcher.
//
@@ -4366,7 +4368,7 @@
return internal::MatcherAsPredicate<M>(matcher);
}
-// Returns true iff the value matches the matcher.
+// Returns true if and only if the value matches the matcher.
template <typename T, typename M>
inline bool Value(const T& value, M matcher) {
return testing::Matches(matcher)(value);
@@ -4380,20 +4382,152 @@
return SafeMatcherCast<const T&>(matcher).MatchAndExplain(value, listener);
}
-#if GTEST_LANG_CXX11
-// Define variadic matcher versions. They are overloaded in
-// gmock-generated-matchers.h for the cases supported by pre C++11 compilers.
-template <typename... Args>
-inline internal::AllOfMatcher<Args...> AllOf(const Args&... matchers) {
- return internal::AllOfMatcher<Args...>(matchers...);
+// Returns a string representation of the given matcher. Useful for description
+// strings of matchers defined using MATCHER_P* macros that accept matchers as
+// their arguments. For example:
+//
+// MATCHER_P(XAndYThat, matcher,
+// "X that " + DescribeMatcher<int>(matcher, negation) +
+// " and Y that " + DescribeMatcher<double>(matcher, negation)) {
+// return ExplainMatchResult(matcher, arg.x(), result_listener) &&
+// ExplainMatchResult(matcher, arg.y(), result_listener);
+// }
+template <typename T, typename M>
+std::string DescribeMatcher(const M& matcher, bool negation = false) {
+ ::std::stringstream ss;
+ Matcher<T> monomorphic_matcher = SafeMatcherCast<T>(matcher);
+ if (negation) {
+ monomorphic_matcher.DescribeNegationTo(&ss);
+ } else {
+ monomorphic_matcher.DescribeTo(&ss);
+ }
+ return ss.str();
}
template <typename... Args>
-inline internal::AnyOfMatcher<Args...> AnyOf(const Args&... matchers) {
- return internal::AnyOfMatcher<Args...>(matchers...);
+internal::ElementsAreMatcher<
+ std::tuple<typename std::decay<const Args&>::type...>>
+ElementsAre(const Args&... matchers) {
+ return internal::ElementsAreMatcher<
+ std::tuple<typename std::decay<const Args&>::type...>>(
+ std::make_tuple(matchers...));
}
-#endif // GTEST_LANG_CXX11
+template <typename... Args>
+internal::UnorderedElementsAreMatcher<
+ std::tuple<typename std::decay<const Args&>::type...>>
+UnorderedElementsAre(const Args&... matchers) {
+ return internal::UnorderedElementsAreMatcher<
+ std::tuple<typename std::decay<const Args&>::type...>>(
+ std::make_tuple(matchers...));
+}
+
+// Define variadic matcher versions.
+template <typename... Args>
+internal::AllOfMatcher<typename std::decay<const Args&>::type...> AllOf(
+ const Args&... matchers) {
+ return internal::AllOfMatcher<typename std::decay<const Args&>::type...>(
+ matchers...);
+}
+
+template <typename... Args>
+internal::AnyOfMatcher<typename std::decay<const Args&>::type...> AnyOf(
+ const Args&... matchers) {
+ return internal::AnyOfMatcher<typename std::decay<const Args&>::type...>(
+ matchers...);
+}
+
+// AnyOfArray(array)
+// AnyOfArray(pointer, count)
+// AnyOfArray(container)
+// AnyOfArray({ e1, e2, ..., en })
+// AnyOfArray(iterator_first, iterator_last)
+//
+// AnyOfArray() verifies whether a given value matches any member of a
+// collection of matchers.
+//
+// AllOfArray(array)
+// AllOfArray(pointer, count)
+// AllOfArray(container)
+// AllOfArray({ e1, e2, ..., en })
+// AllOfArray(iterator_first, iterator_last)
+//
+// AllOfArray() verifies whether a given value matches all members of a
+// collection of matchers.
+//
+// The matchers can be specified as an array, a pointer and count, a container,
+// an initializer list, or an STL iterator range. In each of these cases, the
+// underlying matchers can be either values or matchers.
+
+template <typename Iter>
+inline internal::AnyOfArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>
+AnyOfArray(Iter first, Iter last) {
+ return internal::AnyOfArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>(first, last);
+}
+
+template <typename Iter>
+inline internal::AllOfArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>
+AllOfArray(Iter first, Iter last) {
+ return internal::AllOfArrayMatcher<
+ typename ::std::iterator_traits<Iter>::value_type>(first, last);
+}
+
+template <typename T>
+inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T* ptr, size_t count) {
+ return AnyOfArray(ptr, ptr + count);
+}
+
+template <typename T>
+inline internal::AllOfArrayMatcher<T> AllOfArray(const T* ptr, size_t count) {
+ return AllOfArray(ptr, ptr + count);
+}
+
+template <typename T, size_t N>
+inline internal::AnyOfArrayMatcher<T> AnyOfArray(const T (&array)[N]) {
+ return AnyOfArray(array, N);
+}
+
+template <typename T, size_t N>
+inline internal::AllOfArrayMatcher<T> AllOfArray(const T (&array)[N]) {
+ return AllOfArray(array, N);
+}
+
+template <typename Container>
+inline internal::AnyOfArrayMatcher<typename Container::value_type> AnyOfArray(
+ const Container& container) {
+ return AnyOfArray(container.begin(), container.end());
+}
+
+template <typename Container>
+inline internal::AllOfArrayMatcher<typename Container::value_type> AllOfArray(
+ const Container& container) {
+ return AllOfArray(container.begin(), container.end());
+}
+
+template <typename T>
+inline internal::AnyOfArrayMatcher<T> AnyOfArray(
+ ::std::initializer_list<T> xs) {
+ return AnyOfArray(xs.begin(), xs.end());
+}
+
+template <typename T>
+inline internal::AllOfArrayMatcher<T> AllOfArray(
+ ::std::initializer_list<T> xs) {
+ return AllOfArray(xs.begin(), xs.end());
+}
+
+// Args<N1, N2, ..., Nk>(a_matcher) matches a tuple if the selected
+// fields of it matches a_matcher. C++ doesn't support default
+// arguments for function templates, so we have to overload it.
+template <size_t... k, typename InnerMatcher>
+internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...> Args(
+ InnerMatcher&& matcher) {
+ return internal::ArgsMatcher<typename std::decay<InnerMatcher>::type, k...>(
+ std::forward<InnerMatcher>(matcher));
+}
// AllArgs(m) is a synonym of m. This is useful in
//
@@ -4405,10 +4539,43 @@
template <typename InnerMatcher>
inline InnerMatcher AllArgs(const InnerMatcher& matcher) { return matcher; }
+// Returns a matcher that matches the value of an optional<> type variable.
+// The matcher implementation only uses '!arg' and requires that the optional<>
+// type has a 'value_type' member type and that '*arg' is of type 'value_type'
+// and is printable using 'PrintToString'. It is compatible with
+// std::optional/std::experimental::optional.
+// Note that to compare an optional type variable against nullopt you should
+// use Eq(nullopt) and not Optional(Eq(nullopt)). The latter implies that the
+// optional value contains an optional itself.
+template <typename ValueMatcher>
+inline internal::OptionalMatcher<ValueMatcher> Optional(
+ const ValueMatcher& value_matcher) {
+ return internal::OptionalMatcher<ValueMatcher>(value_matcher);
+}
+
+// Returns a matcher that matches the value of a absl::any type variable.
+template <typename T>
+PolymorphicMatcher<internal::any_cast_matcher::AnyCastMatcher<T> > AnyWith(
+ const Matcher<const T&>& matcher) {
+ return MakePolymorphicMatcher(
+ internal::any_cast_matcher::AnyCastMatcher<T>(matcher));
+}
+
+// Returns a matcher that matches the value of a variant<> type variable.
+// The matcher implementation uses ADL to find the holds_alternative and get
+// functions.
+// It is compatible with std::variant.
+template <typename T>
+PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
+ const Matcher<const T&>& matcher) {
+ return MakePolymorphicMatcher(
+ internal::variant_matcher::VariantMatcher<T>(matcher));
+}
+
// These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
-// succeed iff the value matches the matcher. If the assertion fails,
-// the value and the description of the matcher will be printed.
+// succeed if and only if the value matches the matcher. If the assertion
+// fails, the value and the description of the matcher will be printed.
#define ASSERT_THAT(value, matcher) ASSERT_PRED_FORMAT1(\
::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
#define EXPECT_THAT(value, matcher) EXPECT_PRED_FORMAT1(\
@@ -4416,8 +4583,17 @@
} // namespace testing
+#ifdef __clang__
+#if __has_warning("-Wdeprecated-copy")
+#pragma clang diagnostic pop
+#endif
+#endif
+
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
+
// Include any custom callback matchers added by the local installation.
// We must include this header at the end to make sure it can use the
// declarations from this file.
#include "gmock/internal/custom/gmock-matchers.h"
+
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-actions.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-actions.h
index a3e463d..56de2d1 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-actions.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-actions.h
@@ -26,72 +26,27 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
// This file implements some actions that depend on gmock-generated-actions.h.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include <algorithm>
+#include <type_traits>
#include "gmock/gmock-generated-actions.h"
namespace testing {
namespace internal {
-// Implements the Invoke(f) action. The template argument
-// FunctionImpl is the implementation type of f, which can be either a
-// function pointer or a functor. Invoke(f) can be used as an
-// Action<F> as long as f's type is compatible with F (i.e. f can be
-// assigned to a tr1::function<F>).
-template <typename FunctionImpl>
-class InvokeAction {
- public:
- // The c'tor makes a copy of function_impl (either a function
- // pointer or a functor).
- explicit InvokeAction(FunctionImpl function_impl)
- : function_impl_(function_impl) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) {
- return InvokeHelper<Result, ArgumentTuple>::Invoke(function_impl_, args);
- }
-
- private:
- FunctionImpl function_impl_;
-
- GTEST_DISALLOW_ASSIGN_(InvokeAction);
-};
-
-// Implements the Invoke(object_ptr, &Class::Method) action.
-template <class Class, typename MethodPtr>
-class InvokeMethodAction {
- public:
- InvokeMethodAction(Class* obj_ptr, MethodPtr method_ptr)
- : method_ptr_(method_ptr), obj_ptr_(obj_ptr) {}
-
- template <typename Result, typename ArgumentTuple>
- Result Perform(const ArgumentTuple& args) const {
- return InvokeHelper<Result, ArgumentTuple>::InvokeMethod(
- obj_ptr_, method_ptr_, args);
- }
-
- private:
- // The order of these members matters. Reversing the order can trigger
- // warning C4121 in MSVC (see
- // http://computer-programming-forum.com/7-vc.net/6fbc30265f860ad1.htm ).
- const MethodPtr method_ptr_;
- Class* const obj_ptr_;
-
- GTEST_DISALLOW_ASSIGN_(InvokeMethodAction);
-};
-
// An internal replacement for std::copy which mimics its behavior. This is
// necessary because Visual Studio deprecates ::std::copy, issuing warning 4996.
// However Visual Studio 2010 and later do not honor #pragmas which disable that
@@ -110,45 +65,6 @@
// Various overloads for Invoke().
-// Creates an action that invokes 'function_impl' with the mock
-// function's arguments.
-template <typename FunctionImpl>
-PolymorphicAction<internal::InvokeAction<FunctionImpl> > Invoke(
- FunctionImpl function_impl) {
- return MakePolymorphicAction(
- internal::InvokeAction<FunctionImpl>(function_impl));
-}
-
-// Creates an action that invokes the given method on the given object
-// with the mock function's arguments.
-template <class Class, typename MethodPtr>
-PolymorphicAction<internal::InvokeMethodAction<Class, MethodPtr> > Invoke(
- Class* obj_ptr, MethodPtr method_ptr) {
- return MakePolymorphicAction(
- internal::InvokeMethodAction<Class, MethodPtr>(obj_ptr, method_ptr));
-}
-
-// WithoutArgs(inner_action) can be used in a mock function with a
-// non-empty argument list to perform inner_action, which takes no
-// argument. In other words, it adapts an action accepting no
-// argument to one that accepts (and ignores) arguments.
-template <typename InnerAction>
-inline internal::WithArgsAction<InnerAction>
-WithoutArgs(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction>(action);
-}
-
-// WithArg<k>(an_action) creates an action that passes the k-th
-// (0-based) argument of the mock function to an_action and performs
-// it. It adapts an action accepting one argument to one that accepts
-// multiple arguments. For convenience, we also provide
-// WithArgs<k>(an_action) (defined below) as a synonym.
-template <int k, typename InnerAction>
-inline internal::WithArgsAction<InnerAction, k>
-WithArg(const InnerAction& action) {
- return internal::WithArgsAction<InnerAction, k>(action);
-}
-
// The ACTION*() macros trigger warning C4100 (unreferenced formal
// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in
// the macro definition, as the warnings are generated when the macro
@@ -163,7 +79,7 @@
ACTION_TEMPLATE(ReturnArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
- return ::testing::get<k>(args);
+ return ::std::get<k>(args);
}
// Action SaveArg<k>(pointer) saves the k-th (0-based) argument of the
@@ -171,7 +87,7 @@
ACTION_TEMPLATE(SaveArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
- *pointer = ::testing::get<k>(args);
+ *pointer = ::std::get<k>(args);
}
// Action SaveArgPointee<k>(pointer) saves the value pointed to
@@ -179,7 +95,7 @@
ACTION_TEMPLATE(SaveArgPointee,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
- *pointer = *::testing::get<k>(args);
+ *pointer = *::std::get<k>(args);
}
// Action SetArgReferee<k>(value) assigns 'value' to the variable
@@ -187,13 +103,13 @@
ACTION_TEMPLATE(SetArgReferee,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(value)) {
- typedef typename ::testing::tuple_element<k, args_type>::type argk_type;
+ typedef typename ::std::tuple_element<k, args_type>::type argk_type;
// Ensures that argument #k is a reference. If you get a compiler
// error on the next line, you are using SetArgReferee<k>(value) in
// a mock function whose k-th (0-based) argument is not a reference.
- GTEST_COMPILE_ASSERT_(internal::is_reference<argk_type>::value,
+ GTEST_COMPILE_ASSERT_(std::is_reference<argk_type>::value,
SetArgReferee_must_be_used_with_a_reference_argument);
- ::testing::get<k>(args) = value;
+ ::std::get<k>(args) = value;
}
// Action SetArrayArgument<k>(first, last) copies the elements in
@@ -206,9 +122,9 @@
AND_2_VALUE_PARAMS(first, last)) {
// Visual Studio deprecates ::std::copy, so we use our own copy in that case.
#ifdef _MSC_VER
- internal::CopyElements(first, last, ::testing::get<k>(args));
+ internal::CopyElements(first, last, ::std::get<k>(args));
#else
- ::std::copy(first, last, ::testing::get<k>(args));
+ ::std::copy(first, last, ::std::get<k>(args));
#endif
}
@@ -217,7 +133,7 @@
ACTION_TEMPLATE(DeleteArg,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_0_VALUE_PARAMS()) {
- delete ::testing::get<k>(args);
+ delete ::std::get<k>(args);
}
// This action returns the value pointed to by 'pointer'.
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-matchers.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-matchers.h
index 6a060f3..5b29a9d 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-matchers.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-more-matchers.h
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Marcus Boerger)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -36,15 +35,29 @@
// Note that tests are implemented in gmock-matchers_test.cc rather than
// gmock-more-matchers-test.cc.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
-#ifndef GMOCK_GMOCK_MORE_MATCHERS_H_
-#define GMOCK_GMOCK_MORE_MATCHERS_H_
+#ifndef GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
#include "gmock/gmock-generated-matchers.h"
namespace testing {
+// Silence C4100 (unreferenced formal
+// parameter) for MSVC
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4100)
+#if (_MSC_VER == 1900)
+// and silence C4800 (C4800: 'int *const ': forcing value
+// to bool 'true' or 'false') for MSVC 14
+# pragma warning(disable:4800)
+ #endif
+#endif
+
// Defines a matcher that matches an empty container. The container must
// support both size() and empty(), which all STL-like containers provide.
MATCHER(IsEmpty, negation ? "isn't empty" : "is empty") {
@@ -55,6 +68,27 @@
return false;
}
+// Define a matcher that matches a value that evaluates in boolean
+// context to true. Useful for types that define "explicit operator
+// bool" operators and so can't be compared for equality with true
+// and false.
+MATCHER(IsTrue, negation ? "is false" : "is true") {
+ return static_cast<bool>(arg);
+}
+
+// Define a matcher that matches a value that evaluates in boolean
+// context to false. Useful for types that define "explicit operator
+// bool" operators and so can't be compared for equality with true
+// and false.
+MATCHER(IsFalse, negation ? "is true" : "is false") {
+ return !static_cast<bool>(arg);
+}
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+
} // namespace testing
-#endif // GMOCK_GMOCK_MORE_MATCHERS_H_
+#endif // GMOCK_INCLUDE_GMOCK_MORE_MATCHERS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-nice-strict.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-nice-strict.h
new file mode 100644
index 0000000..5495a98
--- /dev/null
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-nice-strict.h
@@ -0,0 +1,215 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+// Implements class templates NiceMock, NaggyMock, and StrictMock.
+//
+// Given a mock class MockFoo that is created using Google Mock,
+// NiceMock<MockFoo> is a subclass of MockFoo that allows
+// uninteresting calls (i.e. calls to mock methods that have no
+// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo
+// that prints a warning when an uninteresting call occurs, and
+// StrictMock<MockFoo> is a subclass of MockFoo that treats all
+// uninteresting calls as errors.
+//
+// Currently a mock is naggy by default, so MockFoo and
+// NaggyMock<MockFoo> behave like the same. However, we will soon
+// switch the default behavior of mocks to be nice, as that in general
+// leads to more maintainable tests. When that happens, MockFoo will
+// stop behaving like NaggyMock<MockFoo> and start behaving like
+// NiceMock<MockFoo>.
+//
+// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of
+// their respective base class. Therefore you can write
+// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo
+// has a constructor that accepts (int, const char*), for example.
+//
+// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,
+// and StrictMock<MockFoo> only works for mock methods defined using
+// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.
+// If a mock method is defined in a base class of MockFoo, the "nice"
+// or "strict" modifier may not affect it, depending on the compiler.
+// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT
+// supported.
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
+#define GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
+
+#include "gmock/gmock-spec-builders.h"
+#include "gmock/internal/gmock-port.h"
+
+namespace testing {
+
+template <class MockClass>
+class NiceMock : public MockClass {
+ public:
+ NiceMock() : MockClass() {
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ // Ideally, we would inherit base class's constructors through a using
+ // declaration, which would preserve their visibility. However, many existing
+ // tests rely on the fact that current implementation reexports protected
+ // constructors as public. These tests would need to be cleaned up first.
+
+ // Single argument constructor is special-cased so that it can be
+ // made explicit.
+ template <typename A>
+ explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename... An>
+ NiceMock(A1&& arg1, A2&& arg2, An&&... args)
+ : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
+ std::forward<An>(args)...) {
+ ::testing::Mock::AllowUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ ~NiceMock() { // NOLINT
+ ::testing::Mock::UnregisterCallReaction(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock);
+};
+
+template <class MockClass>
+class NaggyMock : public MockClass {
+ public:
+ NaggyMock() : MockClass() {
+ ::testing::Mock::WarnUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ // Ideally, we would inherit base class's constructors through a using
+ // declaration, which would preserve their visibility. However, many existing
+ // tests rely on the fact that current implementation reexports protected
+ // constructors as public. These tests would need to be cleaned up first.
+
+ // Single argument constructor is special-cased so that it can be
+ // made explicit.
+ template <typename A>
+ explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+ ::testing::Mock::WarnUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename... An>
+ NaggyMock(A1&& arg1, A2&& arg2, An&&... args)
+ : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
+ std::forward<An>(args)...) {
+ ::testing::Mock::WarnUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ ~NaggyMock() { // NOLINT
+ ::testing::Mock::UnregisterCallReaction(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock);
+};
+
+template <class MockClass>
+class StrictMock : public MockClass {
+ public:
+ StrictMock() : MockClass() {
+ ::testing::Mock::FailUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ // Ideally, we would inherit base class's constructors through a using
+ // declaration, which would preserve their visibility. However, many existing
+ // tests rely on the fact that current implementation reexports protected
+ // constructors as public. These tests would need to be cleaned up first.
+
+ // Single argument constructor is special-cased so that it can be
+ // made explicit.
+ template <typename A>
+ explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {
+ ::testing::Mock::FailUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ template <typename A1, typename A2, typename... An>
+ StrictMock(A1&& arg1, A2&& arg2, An&&... args)
+ : MockClass(std::forward<A1>(arg1), std::forward<A2>(arg2),
+ std::forward<An>(args)...) {
+ ::testing::Mock::FailUninterestingCalls(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ ~StrictMock() { // NOLINT
+ ::testing::Mock::UnregisterCallReaction(
+ internal::ImplicitCast_<MockClass*>(this));
+ }
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock);
+};
+
+// The following specializations catch some (relatively more common)
+// user errors of nesting nice and strict mocks. They do NOT catch
+// all possible errors.
+
+// These specializations are declared but not defined, as NiceMock,
+// NaggyMock, and StrictMock cannot be nested.
+
+template <typename MockClass>
+class NiceMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class NiceMock<NaggyMock<MockClass> >;
+template <typename MockClass>
+class NiceMock<StrictMock<MockClass> >;
+
+template <typename MockClass>
+class NaggyMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class NaggyMock<NaggyMock<MockClass> >;
+template <typename MockClass>
+class NaggyMock<StrictMock<MockClass> >;
+
+template <typename MockClass>
+class StrictMock<NiceMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<NaggyMock<MockClass> >;
+template <typename MockClass>
+class StrictMock<StrictMock<MockClass> >;
+
+} // namespace testing
+
+#endif // GMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-spec-builders.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-spec-builders.h
index cafd943..4fc4a54 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-spec-builders.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock-spec-builders.h
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -57,21 +56,22 @@
// where all clauses are optional, and .InSequence()/.After()/
// .WillOnce() can appear any number of times.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
+#include <functional>
#include <map>
+#include <memory>
#include <set>
#include <sstream>
#include <string>
+#include <type_traits>
+#include <utility>
#include <vector>
-
-#if GTEST_HAS_EXCEPTIONS
-# include <stdexcept> // NOLINT
-#endif
-
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-matchers.h"
@@ -79,6 +79,13 @@
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
+#if GTEST_HAS_EXCEPTIONS
+# include <stdexcept> // NOLINT
+#endif
+
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
namespace testing {
// An abstract handle of an expectation.
@@ -103,9 +110,6 @@
// Helper class for testing the Expectation class template.
class ExpectationTester;
-// Base class for function mockers.
-template <typename F> class FunctionMockerBase;
-
// Protects the mock object registry (in class Mock), all function
// mockers, and all expectations.
//
@@ -122,9 +126,9 @@
// Untyped base class for ActionResultHolder<R>.
class UntypedActionResultHolderBase;
-// Abstract base class of FunctionMockerBase. This is the
+// Abstract base class of FunctionMocker. This is the
// type-agnostic part of the function mocker interface. Its pure
-// virtual methods are implemented by FunctionMockerBase.
+// virtual methods are implemented by FunctionMocker.
class GTEST_API_ UntypedFunctionMockerBase {
public:
UntypedFunctionMockerBase();
@@ -150,15 +154,13 @@
// action fails.
// L = *
virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
- const void* untyped_args,
- const string& call_description) const = 0;
+ void* untyped_args, const std::string& call_description) const = 0;
// Performs the given action with the given arguments and returns
// the action's result.
// L = *
virtual UntypedActionResultHolderBase* UntypedPerformAction(
- const void* untyped_action,
- const void* untyped_args) const = 0;
+ const void* untyped_action, void* untyped_args) const = 0;
// Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given
@@ -188,7 +190,6 @@
// this information in the global mock registry. Will be called
// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock
// method.
- // TODO([email protected]): rename to SetAndRegisterOwner().
void RegisterOwner(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
@@ -213,15 +214,13 @@
// arguments. This function can be safely called from multiple
// threads concurrently. The caller is responsible for deleting the
// result.
- UntypedActionResultHolderBase* UntypedInvokeWith(
- const void* untyped_args)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
+ UntypedActionResultHolderBase* UntypedInvokeWith(void* untyped_args)
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex);
protected:
typedef std::vector<const void*> UntypedOnCallSpecs;
- typedef std::vector<internal::linked_ptr<ExpectationBase> >
- UntypedExpectations;
+ using UntypedExpectations = std::vector<std::shared_ptr<ExpectationBase>>;
// Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function.
@@ -240,6 +239,14 @@
UntypedOnCallSpecs untyped_on_call_specs_;
// All expectations for this function mocker.
+ //
+ // It's undefined behavior to interleave expectations (EXPECT_CALLs
+ // or ON_CALLs) and mock function calls. Also, the order of
+ // expectations is important. Therefore it's a logic race condition
+ // to read/write untyped_expectations_ concurrently. In order for
+ // tools like tsan to catch concurrent read/write accesses to
+ // untyped_expectations, we deliberately leave accesses to it
+ // unprotected.
UntypedExpectations untyped_expectations_;
}; // class UntypedFunctionMockerBase
@@ -265,12 +272,14 @@
};
// Asserts that the ON_CALL() statement has a certain property.
- void AssertSpecProperty(bool property, const string& failure_message) const {
+ void AssertSpecProperty(bool property,
+ const std::string& failure_message) const {
Assert(property, file_, line_, failure_message);
}
// Expects that the ON_CALL() statement has a certain property.
- void ExpectSpecProperty(bool property, const string& failure_message) const {
+ void ExpectSpecProperty(bool property,
+ const std::string& failure_message) const {
Expect(property, file_, line_, failure_message);
}
@@ -296,11 +305,9 @@
: UntypedOnCallSpecBase(a_file, a_line),
matchers_(matchers),
// By default, extra_matcher_ should match anything. However,
- // we cannot initialize it with _ as that triggers a compiler
- // bug in Symbian's C++ compiler (cannot decide between two
- // overloaded constructors of Matcher<const ArgumentTuple&>).
- extra_matcher_(A<const ArgumentTuple&>()) {
- }
+ // we cannot initialize it with _ as that causes ambiguity between
+ // Matcher's copy and move constructor for some argument types.
+ extra_matcher_(A<const ArgumentTuple&>()) {}
// Implements the .With() clause.
OnCallSpec& With(const Matcher<const ArgumentTuple&>& m) {
@@ -327,7 +334,7 @@
return *this;
}
- // Returns true iff the given arguments match the matchers.
+ // Returns true if and only if the given arguments match the matchers.
bool Matches(const ArgumentTuple& args) const {
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
}
@@ -364,7 +371,6 @@
kAllow,
kWarn,
kFail,
- kDefault = kWarn // By default, warn about uninteresting calls.
};
} // namespace internal
@@ -386,18 +392,28 @@
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Verifies all expectations on the given mock object and clears its
- // default actions and expectations. Returns true iff the
+ // default actions and expectations. Returns true if and only if the
// verification was successful.
static bool VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+ // Returns whether the mock was created as a naggy mock (default)
+ static bool IsNaggy(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+ // Returns whether the mock was created as a nice mock
+ static bool IsNice(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+ // Returns whether the mock was created as a strict mock
+ static bool IsStrict(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
+
private:
friend class internal::UntypedFunctionMockerBase;
// Needed for a function mocker to register itself (so that we know
// how to clear a mock object).
template <typename F>
- friend class internal::FunctionMockerBase;
+ friend class internal::FunctionMocker;
template <typename M>
friend class NiceMock;
@@ -460,7 +476,7 @@
// Unregisters a mock method; removes the owning mock object from
// the registry when the last mock method associated with it has
// been unregistered. This is called only in the destructor of
- // FunctionMockerBase.
+ // FunctionMocker.
static void UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex);
}; // class Mock
@@ -480,12 +496,7 @@
// - Constness is shallow: a const Expectation object itself cannot
// be modified, but the mutable methods of the ExpectationBase
// object it references can be called via expectation_base().
-// - The constructors and destructor are defined out-of-line because
-// the Symbian WINSCW compiler wants to otherwise instantiate them
-// when it sees this class definition, at which point it doesn't have
-// ExpectationBase available yet, leading to incorrect destruction
-// in the linked_ptr (or compilation errors if using a checking
-// linked_ptr).
+
class GTEST_API_ Expectation {
public:
// Constructs a null object that doesn't reference any expectation.
@@ -507,7 +518,8 @@
// The compiler-generated copy ctor and operator= work exactly as
// intended, so we don't need to define our own.
- // Returns true iff rhs references the same expectation as this object does.
+ // Returns true if and only if rhs references the same expectation as this
+ // object does.
bool operator==(const Expectation& rhs) const {
return expectation_base_ == rhs.expectation_base_;
}
@@ -521,7 +533,7 @@
friend class ::testing::internal::UntypedFunctionMockerBase;
template <typename F>
- friend class ::testing::internal::FunctionMockerBase;
+ friend class ::testing::internal::FunctionMocker;
template <typename F>
friend class ::testing::internal::TypedExpectation;
@@ -537,16 +549,15 @@
typedef ::std::set<Expectation, Less> Set;
Expectation(
- const internal::linked_ptr<internal::ExpectationBase>& expectation_base);
+ const std::shared_ptr<internal::ExpectationBase>& expectation_base);
// Returns the expectation this object references.
- const internal::linked_ptr<internal::ExpectationBase>&
- expectation_base() const {
+ const std::shared_ptr<internal::ExpectationBase>& expectation_base() const {
return expectation_base_;
}
- // A linked_ptr that co-owns the expectation this handle references.
- internal::linked_ptr<internal::ExpectationBase> expectation_base_;
+ // A shared_ptr that co-owns the expectation this handle references.
+ std::shared_ptr<internal::ExpectationBase> expectation_base_;
};
// A set of expectation handles. Useful in the .After() clause of
@@ -590,8 +601,8 @@
// The compiler-generator ctor and operator= works exactly as
// intended, so we don't need to define our own.
- // Returns true iff rhs contains the same set of Expectation objects
- // as this does.
+ // Returns true if and only if rhs contains the same set of Expectation
+ // objects as this does.
bool operator==(const ExpectationSet& rhs) const {
return expectations_ == rhs.expectations_;
}
@@ -628,11 +639,8 @@
void AddExpectation(const Expectation& expectation) const;
private:
- // The last expectation in this sequence. We use a linked_ptr here
- // because Sequence objects are copyable and we want the copies to
- // be aliases. The linked_ptr allows the copies to co-own and share
- // the same Expectation object.
- internal::linked_ptr<Expectation> last_expectation_;
+ // The last expectation in this sequence.
+ std::shared_ptr<Expectation> last_expectation_;
}; // class Sequence
// An object of this type causes all EXPECT_CALL() statements
@@ -692,7 +700,7 @@
class GTEST_API_ ExpectationBase {
public:
// source_text is the EXPECT_CALL(...) source that created this Expectation.
- ExpectationBase(const char* file, int line, const string& source_text);
+ ExpectationBase(const char* file, int line, const std::string& source_text);
virtual ~ExpectationBase();
@@ -740,12 +748,14 @@
virtual Expectation GetHandle() = 0;
// Asserts that the EXPECT_CALL() statement has the given property.
- void AssertSpecProperty(bool property, const string& failure_message) const {
+ void AssertSpecProperty(bool property,
+ const std::string& failure_message) const {
Assert(property, file_, line_, failure_message);
}
// Expects that the EXPECT_CALL() statement has the given property.
- void ExpectSpecProperty(bool property, const string& failure_message) const {
+ void ExpectSpecProperty(bool property,
+ const std::string& failure_message) const {
Expect(property, file_, line_, failure_message);
}
@@ -753,8 +763,8 @@
// by the subclasses to implement the .Times() clause.
void SpecifyCardinality(const Cardinality& cardinality);
- // Returns true iff the user specified the cardinality explicitly
- // using a .Times().
+ // Returns true if and only if the user specified the cardinality
+ // explicitly using a .Times().
bool cardinality_specified() const { return cardinality_specified_; }
// Sets the cardinality of this expectation spec.
@@ -770,7 +780,7 @@
void RetireAllPreRequisites()
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
- // Returns true iff this expectation is retired.
+ // Returns true if and only if this expectation is retired.
bool is_retired() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
@@ -784,28 +794,29 @@
retired_ = true;
}
- // Returns true iff this expectation is satisfied.
+ // Returns true if and only if this expectation is satisfied.
bool IsSatisfied() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return cardinality().IsSatisfiedByCallCount(call_count_);
}
- // Returns true iff this expectation is saturated.
+ // Returns true if and only if this expectation is saturated.
bool IsSaturated() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return cardinality().IsSaturatedByCallCount(call_count_);
}
- // Returns true iff this expectation is over-saturated.
+ // Returns true if and only if this expectation is over-saturated.
bool IsOverSaturated() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return cardinality().IsOverSaturatedByCallCount(call_count_);
}
- // Returns true iff all pre-requisites of this expectation are satisfied.
+ // Returns true if and only if all pre-requisites of this expectation are
+ // satisfied.
bool AllPrerequisitesAreSatisfied() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex);
@@ -847,13 +858,13 @@
// an EXPECT_CALL() statement finishes.
const char* file_; // The file that contains the expectation.
int line_; // The line number of the expectation.
- const string source_text_; // The EXPECT_CALL(...) source text.
- // True iff the cardinality is specified explicitly.
+ const std::string source_text_; // The EXPECT_CALL(...) source text.
+ // True if and only if the cardinality is specified explicitly.
bool cardinality_specified_;
Cardinality cardinality_; // The cardinality of the expectation.
// The immediate pre-requisites (i.e. expectations that must be
// satisfied before this expectation can be matched) of this
- // expectation. We use linked_ptr in the set because we want an
+ // expectation. We use std::shared_ptr in the set because we want an
// Expectation object to be co-owned by its FunctionMocker and its
// successors. This allows multiple mock objects to be deleted at
// different times.
@@ -862,7 +873,7 @@
// This group of fields are the current state of the expectation,
// and can change as the mock function is called.
int call_count_; // How many times this expectation has been invoked.
- bool retired_; // True iff this expectation has retired.
+ bool retired_; // True if and only if this expectation has retired.
UntypedActions untyped_actions_;
bool extra_matcher_specified_;
bool repeated_action_specified_; // True if a WillRepeatedly() was specified.
@@ -882,20 +893,19 @@
typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
typedef typename Function<F>::Result Result;
- TypedExpectation(FunctionMockerBase<F>* owner,
- const char* a_file, int a_line, const string& a_source_text,
+ TypedExpectation(FunctionMocker<F>* owner, const char* a_file, int a_line,
+ const std::string& a_source_text,
const ArgumentMatcherTuple& m)
: ExpectationBase(a_file, a_line, a_source_text),
owner_(owner),
matchers_(m),
// By default, extra_matcher_ should match anything. However,
- // we cannot initialize it with _ as that triggers a compiler
- // bug in Symbian's C++ compiler (cannot decide between two
- // overloaded constructors of Matcher<const ArgumentTuple&>).
+ // we cannot initialize it with _ as that causes ambiguity between
+ // Matcher's copy and move constructor for some argument types.
extra_matcher_(A<const ArgumentTuple&>()),
repeated_action_(DoDefault()) {}
- virtual ~TypedExpectation() {
+ ~TypedExpectation() override {
// Check the validity of the action count if it hasn't been done
// yet (for example, if the expectation was never used).
CheckActionCountIfNotDone();
@@ -1061,7 +1071,7 @@
// If this mock method has an extra matcher (i.e. .With(matcher)),
// describes it to the ostream.
- virtual void MaybeDescribeExtraMatcherTo(::std::ostream* os) {
+ void MaybeDescribeExtraMatcherTo(::std::ostream* os) override {
if (extra_matcher_specified_) {
*os << " Expected args: ";
extra_matcher_.DescribeTo(os);
@@ -1071,26 +1081,25 @@
private:
template <typename Function>
- friend class FunctionMockerBase;
+ friend class FunctionMocker;
// Returns an Expectation object that references and co-owns this
// expectation.
- virtual Expectation GetHandle() {
- return owner_->GetHandleOf(this);
- }
+ Expectation GetHandle() override { return owner_->GetHandleOf(this); }
// The following methods will be called only after the EXPECT_CALL()
// statement finishes and when the current thread holds
// g_gmock_mutex.
- // Returns true iff this expectation matches the given arguments.
+ // Returns true if and only if this expectation matches the given arguments.
bool Matches(const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
return TupleMatches(matchers_, args) && extra_matcher_.Matches(args);
}
- // Returns true iff this expectation should handle the given arguments.
+ // Returns true if and only if this expectation should handle the given
+ // arguments.
bool ShouldHandleArguments(const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
@@ -1150,10 +1159,9 @@
}
// Returns the action that should be taken for the current invocation.
- const Action<F>& GetCurrentAction(
- const FunctionMockerBase<F>* mocker,
- const ArgumentTuple& args) const
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ const Action<F>& GetCurrentAction(const FunctionMocker<F>* mocker,
+ const ArgumentTuple& args) const
+ GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
const int count = call_count();
Assert(count >= 1, __FILE__, __LINE__,
@@ -1175,9 +1183,10 @@
Log(kWarning, ss.str(), 1);
}
- return count <= action_count ?
- *static_cast<const Action<F>*>(untyped_actions_[count - 1]) :
- repeated_action();
+ return count <= action_count
+ ? *static_cast<const Action<F>*>(
+ untyped_actions_[static_cast<size_t>(count - 1)])
+ : repeated_action();
}
// Given the arguments of a mock function call, if the call will
@@ -1187,12 +1196,11 @@
// Mock does it to 'why'. This method is not const as it calls
// IncrementCallCount(). A return value of NULL means the default
// action.
- const Action<F>* GetActionForArguments(
- const FunctionMockerBase<F>* mocker,
- const ArgumentTuple& args,
- ::std::ostream* what,
- ::std::ostream* why)
- GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
+ const Action<F>* GetActionForArguments(const FunctionMocker<F>* mocker,
+ const ArgumentTuple& args,
+ ::std::ostream* what,
+ ::std::ostream* why)
+ GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
if (IsSaturated()) {
// We have an excessive call.
@@ -1201,10 +1209,7 @@
mocker->DescribeDefaultActionTo(args, what);
DescribeCallCountTo(why);
- // TODO([email protected]): allow the user to control whether
- // unexpected calls should fail immediately or continue using a
- // flag --gmock_unexpected_calls_are_fatal.
- return NULL;
+ return nullptr;
}
IncrementCallCount();
@@ -1221,7 +1226,7 @@
// All the fields below won't change once the EXPECT_CALL()
// statement finishes.
- FunctionMockerBase<F>* const owner_;
+ FunctionMocker<F>* const owner_;
ArgumentMatcherTuple matchers_;
Matcher<const ArgumentTuple&> extra_matcher_;
Action<F> repeated_action_;
@@ -1242,7 +1247,7 @@
// Logs a message including file and line number information.
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
- const string& message);
+ const std::string& message);
template <typename F>
class MockSpec {
@@ -1253,15 +1258,16 @@
// Constructs a MockSpec object, given the function mocker object
// that the spec is associated with.
- explicit MockSpec(internal::FunctionMockerBase<F>* function_mocker)
- : function_mocker_(function_mocker) {}
+ MockSpec(internal::FunctionMocker<F>* function_mocker,
+ const ArgumentMatcherTuple& matchers)
+ : function_mocker_(function_mocker), matchers_(matchers) {}
// Adds a new default action spec to the function mocker and returns
// the newly created spec.
internal::OnCallSpec<F>& InternalDefaultActionSetAt(
const char* file, int line, const char* obj, const char* call) {
LogWithLocation(internal::kInfo, file, line,
- string("ON_CALL(") + obj + ", " + call + ") invoked");
+ std::string("ON_CALL(") + obj + ", " + call + ") invoked");
return function_mocker_->AddNewOnCallSpec(file, line, matchers_);
}
@@ -1269,26 +1275,28 @@
// the newly created spec.
internal::TypedExpectation<F>& InternalExpectedAt(
const char* file, int line, const char* obj, const char* call) {
- const string source_text(string("EXPECT_CALL(") + obj + ", " + call + ")");
+ const std::string source_text(std::string("EXPECT_CALL(") + obj + ", " +
+ call + ")");
LogWithLocation(internal::kInfo, file, line, source_text + " invoked");
return function_mocker_->AddNewExpectation(
file, line, source_text, matchers_);
}
+ // This operator overload is used to swallow the superfluous parameter list
+ // introduced by the ON/EXPECT_CALL macros. See the macro comments for more
+ // explanation.
+ MockSpec<F>& operator()(const internal::WithoutMatchers&, void* const) {
+ return *this;
+ }
+
private:
template <typename Function>
friend class internal::FunctionMocker;
- void SetMatchers(const ArgumentMatcherTuple& matchers) {
- matchers_ = matchers;
- }
-
// The function mocker that owns this spec.
- internal::FunctionMockerBase<F>* const function_mocker_;
+ internal::FunctionMocker<F>* const function_mocker_;
// The argument matchers specified in the spec.
ArgumentMatcherTuple matchers_;
-
- GTEST_DISALLOW_ASSIGN_(MockSpec);
}; // class MockSpec
// Wrapper type for generically holding an ordinary value or lvalue reference.
@@ -1305,18 +1313,18 @@
public:
// Constructs a wrapper from the given value/reference.
explicit ReferenceOrValueWrapper(T value)
- : value_(::testing::internal::move(value)) {
+ : value_(std::move(value)) {
}
// Unwraps and returns the underlying value/reference, exactly as
// originally passed. The behavior of calling this more than once on
// the same object is unspecified.
- T Unwrap() { return ::testing::internal::move(value_); }
+ T Unwrap() { return std::move(value_); }
// Provides nondestructive access to the underlying value/reference.
// Always returns a const reference (more precisely,
- // const RemoveReference<T>&). The behavior of calling this after
- // calling Unwrap on the same object is unspecified.
+ // const std::add_lvalue_reference<T>::type). The behavior of calling this
+ // after calling Unwrap on the same object is unspecified.
const T& Peek() const {
return value_;
}
@@ -1346,11 +1354,7 @@
// we need to temporarily disable the warning. We have to do it for
// the entire class to suppress the warning, even though it's about
// the constructor only.
-
-#ifdef _MSC_VER
-# pragma warning(push) // Saves the current warning state.
-# pragma warning(disable:4355) // Temporarily disables warning 4355.
-#endif // _MSV_VER
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355)
// C++ treats the void type specially. For example, you cannot define
// a void-typed variable or pass a void value to a function.
@@ -1379,7 +1383,7 @@
}
// Prints the held value as an action's result to os.
- virtual void PrintAsActionResult(::std::ostream* os) const {
+ void PrintAsActionResult(::std::ostream* os) const override {
*os << "\n Returns: ";
// T may be a reference type, so we don't use UniversalPrint().
UniversalPrinter<T>::Print(result_.Peek(), os);
@@ -1389,27 +1393,27 @@
// result in a new-ed ActionResultHolder.
template <typename F>
static ActionResultHolder* PerformDefaultAction(
- const FunctionMockerBase<F>* func_mocker,
- const typename Function<F>::ArgumentTuple& args,
- const string& call_description) {
- return new ActionResultHolder(Wrapper(
- func_mocker->PerformDefaultAction(args, call_description)));
+ const FunctionMocker<F>* func_mocker,
+ typename Function<F>::ArgumentTuple&& args,
+ const std::string& call_description) {
+ return new ActionResultHolder(Wrapper(func_mocker->PerformDefaultAction(
+ std::move(args), call_description)));
}
// Performs the given action and returns the result in a new-ed
// ActionResultHolder.
template <typename F>
- static ActionResultHolder*
- PerformAction(const Action<F>& action,
- const typename Function<F>::ArgumentTuple& args) {
- return new ActionResultHolder(Wrapper(action.Perform(args)));
+ static ActionResultHolder* PerformAction(
+ const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
+ return new ActionResultHolder(
+ Wrapper(action.Perform(std::move(args))));
}
private:
typedef ReferenceOrValueWrapper<T> Wrapper;
explicit ActionResultHolder(Wrapper result)
- : result_(::testing::internal::move(result)) {
+ : result_(std::move(result)) {
}
Wrapper result_;
@@ -1423,16 +1427,16 @@
public:
void Unwrap() { }
- virtual void PrintAsActionResult(::std::ostream* /* os */) const {}
+ void PrintAsActionResult(::std::ostream* /* os */) const override {}
// Performs the given mock function's default action and returns ownership
// of an empty ActionResultHolder*.
template <typename F>
static ActionResultHolder* PerformDefaultAction(
- const FunctionMockerBase<F>* func_mocker,
- const typename Function<F>::ArgumentTuple& args,
- const string& call_description) {
- func_mocker->PerformDefaultAction(args, call_description);
+ const FunctionMocker<F>* func_mocker,
+ typename Function<F>::ArgumentTuple&& args,
+ const std::string& call_description) {
+ func_mocker->PerformDefaultAction(std::move(args), call_description);
return new ActionResultHolder;
}
@@ -1440,9 +1444,8 @@
// ActionResultHolder*.
template <typename F>
static ActionResultHolder* PerformAction(
- const Action<F>& action,
- const typename Function<F>::ArgumentTuple& args) {
- action.Perform(args);
+ const Action<F>& action, typename Function<F>::ArgumentTuple&& args) {
+ action.Perform(std::move(args));
return new ActionResultHolder;
}
@@ -1451,23 +1454,39 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionResultHolder);
};
-// The base of the function mocker class for the given function type.
-// We put the methods in this class instead of its child to avoid code
-// bloat.
template <typename F>
-class FunctionMockerBase : public UntypedFunctionMockerBase {
- public:
- typedef typename Function<F>::Result Result;
- typedef typename Function<F>::ArgumentTuple ArgumentTuple;
- typedef typename Function<F>::ArgumentMatcherTuple ArgumentMatcherTuple;
+class FunctionMocker;
- FunctionMockerBase() : current_spec_(this) {}
+template <typename R, typename... Args>
+class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
+ using F = R(Args...);
+
+ public:
+ using Result = R;
+ using ArgumentTuple = std::tuple<Args...>;
+ using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
+
+ FunctionMocker() {}
+
+ // There is no generally useful and implementable semantics of
+ // copying a mock object, so copying a mock is usually a user error.
+ // Thus we disallow copying function mockers. If the user really
+ // wants to copy a mock object, they should implement their own copy
+ // operation, for example:
+ //
+ // class MockFoo : public Foo {
+ // public:
+ // // Defines a copy constructor explicitly.
+ // MockFoo(const MockFoo& src) {}
+ // ...
+ // };
+ FunctionMocker(const FunctionMocker&) = delete;
+ FunctionMocker& operator=(const FunctionMocker&) = delete;
// The destructor verifies that all expectations on this mock
// function have been satisfied. If not, it will report Google Test
// non-fatal failures for the violations.
- virtual ~FunctionMockerBase()
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ ~FunctionMocker() override GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
MutexLock l(&g_gmock_mutex);
VerifyAndClearExpectationsLocked();
Mock::UnregisterLocked(this);
@@ -1487,7 +1506,7 @@
return spec;
}
- return NULL;
+ return nullptr;
}
// Performs the default action of this mock function on the given
@@ -1497,14 +1516,15 @@
// mutable state of this object, and thus can be called concurrently
// without locking.
// L = *
- Result PerformDefaultAction(const ArgumentTuple& args,
- const string& call_description) const {
+ Result PerformDefaultAction(ArgumentTuple&& args,
+ const std::string& call_description) const {
const OnCallSpec<F>* const spec =
this->FindOnCallSpec(args);
- if (spec != NULL) {
- return spec->GetAction().Perform(args);
+ if (spec != nullptr) {
+ return spec->GetAction().Perform(std::move(args));
}
- const string message = call_description +
+ const std::string message =
+ call_description +
"\n The mock function has no default action "
"set, and its return type has no default value set.";
#if GTEST_HAS_EXCEPTIONS
@@ -1522,31 +1542,30 @@
// the error message to describe the call in the case the default
// action fails. The caller is responsible for deleting the result.
// L = *
- virtual UntypedActionResultHolderBase* UntypedPerformDefaultAction(
- const void* untyped_args, // must point to an ArgumentTuple
- const string& call_description) const {
- const ArgumentTuple& args =
- *static_cast<const ArgumentTuple*>(untyped_args);
- return ResultHolder::PerformDefaultAction(this, args, call_description);
+ UntypedActionResultHolderBase* UntypedPerformDefaultAction(
+ void* untyped_args, // must point to an ArgumentTuple
+ const std::string& call_description) const override {
+ ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
+ return ResultHolder::PerformDefaultAction(this, std::move(*args),
+ call_description);
}
// Performs the given action with the given arguments and returns
// the action's result. The caller is responsible for deleting the
// result.
// L = *
- virtual UntypedActionResultHolderBase* UntypedPerformAction(
- const void* untyped_action, const void* untyped_args) const {
+ UntypedActionResultHolderBase* UntypedPerformAction(
+ const void* untyped_action, void* untyped_args) const override {
// Make a copy of the action before performing it, in case the
// action deletes the mock object (and thus deletes itself).
const Action<F> action = *static_cast<const Action<F>*>(untyped_action);
- const ArgumentTuple& args =
- *static_cast<const ArgumentTuple*>(untyped_args);
- return ResultHolder::PerformAction(action, args);
+ ArgumentTuple* args = static_cast<ArgumentTuple*>(untyped_args);
+ return ResultHolder::PerformAction(action, std::move(*args));
}
// Implements UntypedFunctionMockerBase::ClearDefaultActionsLocked():
// clears the ON_CALL()s set on this mock function.
- virtual void ClearDefaultActionsLocked()
+ void ClearDefaultActionsLocked() override
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
@@ -1572,22 +1591,26 @@
g_gmock_mutex.Lock();
}
+ // Returns the result of invoking this mock function with the given
+ // arguments. This function can be safely called from multiple
+ // threads concurrently.
+ Result Invoke(Args... args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ ArgumentTuple tuple(std::forward<Args>(args)...);
+ std::unique_ptr<ResultHolder> holder(DownCast_<ResultHolder*>(
+ this->UntypedInvokeWith(static_cast<void*>(&tuple))));
+ return holder->Unwrap();
+ }
+
+ MockSpec<F> With(Matcher<Args>... m) {
+ return MockSpec<F>(this, ::std::make_tuple(std::move(m)...));
+ }
+
protected:
template <typename Function>
friend class MockSpec;
typedef ActionResultHolder<Result> ResultHolder;
- // Returns the result of invoking this mock function with the given
- // arguments. This function can be safely called from multiple
- // threads concurrently.
- Result InvokeWith(const ArgumentTuple& args)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
- scoped_ptr<ResultHolder> holder(
- DownCast_<ResultHolder*>(this->UntypedInvokeWith(&args)));
- return holder->Unwrap();
- }
-
// Adds and returns a default action spec for this mock function.
OnCallSpec<F>& AddNewOnCallSpec(
const char* file, int line,
@@ -1600,31 +1623,27 @@
}
// Adds and returns an expectation spec for this mock function.
- TypedExpectation<F>& AddNewExpectation(
- const char* file,
- int line,
- const string& source_text,
- const ArgumentMatcherTuple& m)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ TypedExpectation<F>& AddNewExpectation(const char* file, int line,
+ const std::string& source_text,
+ const ArgumentMatcherTuple& m)
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
Mock::RegisterUseByOnCallOrExpectCall(MockObject(), file, line);
TypedExpectation<F>* const expectation =
new TypedExpectation<F>(this, file, line, source_text, m);
- const linked_ptr<ExpectationBase> untyped_expectation(expectation);
+ const std::shared_ptr<ExpectationBase> untyped_expectation(expectation);
+ // See the definition of untyped_expectations_ for why access to
+ // it is unprotected here.
untyped_expectations_.push_back(untyped_expectation);
// Adds this expectation into the implicit sequence if there is one.
Sequence* const implicit_sequence = g_gmock_implicit_sequence.get();
- if (implicit_sequence != NULL) {
+ if (implicit_sequence != nullptr) {
implicit_sequence->AddExpectation(Expectation(untyped_expectation));
}
return *expectation;
}
- // The current spec (either default action spec or expectation spec)
- // being described on this function mocker.
- MockSpec<F>& current_spec() { return current_spec_; }
-
private:
template <typename Func> friend class TypedExpectation;
@@ -1637,10 +1656,9 @@
::std::ostream* os) const {
const OnCallSpec<F>* const spec = FindOnCallSpec(args);
- if (spec == NULL) {
- *os << (internal::type_equals<Result, void>::value ?
- "returning directly.\n" :
- "returning default value.\n");
+ if (spec == nullptr) {
+ *os << (std::is_void<Result>::value ? "returning directly.\n"
+ : "returning default value.\n");
} else {
*os << "taking default action specified at:\n"
<< FormatFileLocation(spec->file(), spec->line()) << "\n";
@@ -1650,10 +1668,9 @@
// Writes a message that the call is uninteresting (i.e. neither
// explicitly expected nor explicitly unexpected) to the given
// ostream.
- virtual void UntypedDescribeUninterestingCall(
- const void* untyped_args,
- ::std::ostream* os) const
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ void UntypedDescribeUninterestingCall(const void* untyped_args,
+ ::std::ostream* os) const override
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args);
*os << "Uninteresting mock function call - ";
@@ -1678,18 +1695,17 @@
// section. The reason is that we have no control on what the
// action does (it can invoke an arbitrary user function or even a
// mock function) and excessive locking could cause a dead lock.
- virtual const ExpectationBase* UntypedFindMatchingExpectation(
- const void* untyped_args,
- const void** untyped_action, bool* is_excessive,
- ::std::ostream* what, ::std::ostream* why)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ const ExpectationBase* UntypedFindMatchingExpectation(
+ const void* untyped_args, const void** untyped_action, bool* is_excessive,
+ ::std::ostream* what, ::std::ostream* why) override
+ GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args);
MutexLock l(&g_gmock_mutex);
TypedExpectation<F>* exp = this->FindMatchingExpectationLocked(args);
- if (exp == NULL) { // A match wasn't found.
+ if (exp == nullptr) { // A match wasn't found.
this->FormatUnexpectedCallMessageLocked(args, what, why);
- return NULL;
+ return nullptr;
}
// This line must be done before calling GetActionForArguments(),
@@ -1697,15 +1713,15 @@
// its saturation status.
*is_excessive = exp->IsSaturated();
const Action<F>* action = exp->GetActionForArguments(this, args, what, why);
- if (action != NULL && action->IsDoDefault())
- action = NULL; // Normalize "do default" to NULL.
+ if (action != nullptr && action->IsDoDefault())
+ action = nullptr; // Normalize "do default" to NULL.
*untyped_action = action;
return exp;
}
// Prints the given function arguments to the ostream.
- virtual void UntypedPrintArgs(const void* untyped_args,
- ::std::ostream* os) const {
+ void UntypedPrintArgs(const void* untyped_args,
+ ::std::ostream* os) const override {
const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args);
UniversalPrint(args, os);
@@ -1717,6 +1733,8 @@
const ArgumentTuple& args) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
+ // See the definition of untyped_expectations_ for why access to
+ // it is unprotected here.
for (typename UntypedExpectations::const_reverse_iterator it =
untyped_expectations_.rbegin();
it != untyped_expectations_.rend(); ++it) {
@@ -1726,7 +1744,7 @@
return exp;
}
}
- return NULL;
+ return nullptr;
}
// Returns a message that the arguments don't match any expectation.
@@ -1748,12 +1766,12 @@
::std::ostream* why) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
- const int count = static_cast<int>(untyped_expectations_.size());
+ const size_t count = untyped_expectations_.size();
*why << "Google Mock tried the following " << count << " "
<< (count == 1 ? "expectation, but it didn't match" :
"expectations, but none matched")
<< ":\n";
- for (int i = 0; i < count; i++) {
+ for (size_t i = 0; i < count; i++) {
TypedExpectation<F>* const expectation =
static_cast<TypedExpectation<F>*>(untyped_expectations_[i].get());
*why << "\n";
@@ -1766,42 +1784,98 @@
expectation->DescribeCallCountTo(why);
}
}
+}; // class FunctionMocker
- // The current spec (either default action spec or expectation spec)
- // being described on this function mocker.
- MockSpec<F> current_spec_;
-
- // There is no generally useful and implementable semantics of
- // copying a mock object, so copying a mock is usually a user error.
- // Thus we disallow copying function mockers. If the user really
- // wants to copy a mock object, he should implement his own copy
- // operation, for example:
- //
- // class MockFoo : public Foo {
- // public:
- // // Defines a copy constructor explicitly.
- // MockFoo(const MockFoo& src) {}
- // ...
- // };
- GTEST_DISALLOW_COPY_AND_ASSIGN_(FunctionMockerBase);
-}; // class FunctionMockerBase
-
-#ifdef _MSC_VER
-# pragma warning(pop) // Restores the warning state.
-#endif // _MSV_VER
-
-// Implements methods of FunctionMockerBase.
-
-// Verifies that all expectations on this mock function have been
-// satisfied. Reports one or more Google Test non-fatal failures and
-// returns false if not.
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4355
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
-void ReportUninterestingCall(CallReaction reaction, const string& msg);
+void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
} // namespace internal
+// A MockFunction<F> class has one mock method whose type is F. It is
+// useful when you just want your test code to emit some messages and
+// have Google Mock verify the right messages are sent (and perhaps at
+// the right times). For example, if you are exercising code:
+//
+// Foo(1);
+// Foo(2);
+// Foo(3);
+//
+// and want to verify that Foo(1) and Foo(3) both invoke
+// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write:
+//
+// TEST(FooTest, InvokesBarCorrectly) {
+// MyMock mock;
+// MockFunction<void(string check_point_name)> check;
+// {
+// InSequence s;
+//
+// EXPECT_CALL(mock, Bar("a"));
+// EXPECT_CALL(check, Call("1"));
+// EXPECT_CALL(check, Call("2"));
+// EXPECT_CALL(mock, Bar("a"));
+// }
+// Foo(1);
+// check.Call("1");
+// Foo(2);
+// check.Call("2");
+// Foo(3);
+// }
+//
+// The expectation spec says that the first Bar("a") must happen
+// before check point "1", the second Bar("a") must happen after check
+// point "2", and nothing should happen between the two check
+// points. The explicit check points make it easy to tell which
+// Bar("a") is called by which call to Foo().
+//
+// MockFunction<F> can also be used to exercise code that accepts
+// std::function<F> callbacks. To do so, use AsStdFunction() method
+// to create std::function proxy forwarding to original object's Call.
+// Example:
+//
+// TEST(FooTest, RunsCallbackWithBarArgument) {
+// MockFunction<int(string)> callback;
+// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
+// Foo(callback.AsStdFunction());
+// }
+template <typename F>
+class MockFunction;
+
+template <typename R, typename... Args>
+class MockFunction<R(Args...)> {
+ public:
+ MockFunction() {}
+ MockFunction(const MockFunction&) = delete;
+ MockFunction& operator=(const MockFunction&) = delete;
+
+ std::function<R(Args...)> AsStdFunction() {
+ return [this](Args... args) -> R {
+ return this->Call(std::forward<Args>(args)...);
+ };
+ }
+
+ // Implementation detail: the expansion of the MOCK_METHOD macro.
+ R Call(Args... args) {
+ mock_.SetOwnerAndName(this, "Call");
+ return mock_.Invoke(std::forward<Args>(args)...);
+ }
+
+ internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
+ mock_.RegisterOwner(this);
+ return mock_.With(std::move(m)...);
+ }
+
+ internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
+ R (*)(Args...)) {
+ return this->gmock_Call(::testing::A<Args>()...);
+ }
+
+ private:
+ internal::FunctionMocker<R(Args...)> mock_;
+};
+
// The style guide prohibits "using" statements in a namespace scope
// inside a header file. However, the MockSpec class template is
// meant to be defined in the ::testing namespace. The following line
@@ -1833,17 +1907,79 @@
} // namespace testing
-// A separate macro is required to avoid compile errors when the name
-// of the method used in call is a result of macro expansion.
-// See CompilesWithMethodNameExpandedFromMacro tests in
-// internal/gmock-spec-builders_test.cc for more details.
-#define GMOCK_ON_CALL_IMPL_(obj, call) \
- ((obj).gmock_##call).InternalDefaultActionSetAt(__FILE__, __LINE__, \
- #obj, #call)
-#define ON_CALL(obj, call) GMOCK_ON_CALL_IMPL_(obj, call)
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
-#define GMOCK_EXPECT_CALL_IMPL_(obj, call) \
- ((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
-#define EXPECT_CALL(obj, call) GMOCK_EXPECT_CALL_IMPL_(obj, call)
+// Implementation for ON_CALL and EXPECT_CALL macros. A separate macro is
+// required to avoid compile errors when the name of the method used in call is
+// a result of macro expansion. See CompilesWithMethodNameExpandedFromMacro
+// tests in internal/gmock-spec-builders_test.cc for more details.
+//
+// This macro supports statements both with and without parameter matchers. If
+// the parameter list is omitted, gMock will accept any parameters, which allows
+// tests to be written that don't need to encode the number of method
+// parameter. This technique may only be used for non-overloaded methods.
+//
+// // These are the same:
+// ON_CALL(mock, NoArgsMethod()).WillByDefault(...);
+// ON_CALL(mock, NoArgsMethod).WillByDefault(...);
+//
+// // As are these:
+// ON_CALL(mock, TwoArgsMethod(_, _)).WillByDefault(...);
+// ON_CALL(mock, TwoArgsMethod).WillByDefault(...);
+//
+// // Can also specify args if you want, of course:
+// ON_CALL(mock, TwoArgsMethod(_, 45)).WillByDefault(...);
+//
+// // Overloads work as long as you specify parameters:
+// ON_CALL(mock, OverloadedMethod(_)).WillByDefault(...);
+// ON_CALL(mock, OverloadedMethod(_, _)).WillByDefault(...);
+//
+// // Oops! Which overload did you want?
+// ON_CALL(mock, OverloadedMethod).WillByDefault(...);
+// => ERROR: call to member function 'gmock_OverloadedMethod' is ambiguous
+//
+// How this works: The mock class uses two overloads of the gmock_Method
+// expectation setter method plus an operator() overload on the MockSpec object.
+// In the matcher list form, the macro expands to:
+//
+// // This statement:
+// ON_CALL(mock, TwoArgsMethod(_, 45))...
+//
+// // ...expands to:
+// mock.gmock_TwoArgsMethod(_, 45)(WithoutMatchers(), nullptr)...
+// |-------------v---------------||------------v-------------|
+// invokes first overload swallowed by operator()
+//
+// // ...which is essentially:
+// mock.gmock_TwoArgsMethod(_, 45)...
+//
+// Whereas the form without a matcher list:
+//
+// // This statement:
+// ON_CALL(mock, TwoArgsMethod)...
+//
+// // ...expands to:
+// mock.gmock_TwoArgsMethod(WithoutMatchers(), nullptr)...
+// |-----------------------v--------------------------|
+// invokes second overload
+//
+// // ...which is essentially:
+// mock.gmock_TwoArgsMethod(_, _)...
+//
+// The WithoutMatchers() argument is used to disambiguate overloads and to
+// block the caller from accidentally invoking the second overload directly. The
+// second argument is an internal type derived from the method signature. The
+// failure to disambiguate two overloads of this method in the ON_CALL statement
+// is how we block callers from setting expectations on overloaded methods.
+#define GMOCK_ON_CALL_IMPL_(mock_expr, Setter, call) \
+ ((mock_expr).gmock_##call)(::testing::internal::GetWithoutMatchers(), \
+ nullptr) \
+ .Setter(__FILE__, __LINE__, #mock_expr, #call)
+
+#define ON_CALL(obj, call) \
+ GMOCK_ON_CALL_IMPL_(obj, InternalDefaultActionSetAt, call)
+
+#define EXPECT_CALL(obj, call) \
+ GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call)
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock.h
index 6735c71..45645ff 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/gmock.h
@@ -26,26 +26,27 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
// This is the main header file a user should include.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
// This file implements the following syntax:
//
-// ON_CALL(mock_object.Method(...))
+// ON_CALL(mock_object, Method(...))
// .With(...) ?
// .WillByDefault(...);
//
// where With() is optional and WillByDefault() must appear exactly
// once.
//
-// EXPECT_CALL(mock_object.Method(...))
+// EXPECT_CALL(mock_object, Method(...))
// .With(...) ?
// .Times(...) ?
// .InSequence(...) *
@@ -57,20 +58,29 @@
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
+#include "gmock/gmock-function-mocker.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-generated-function-mockers.h"
-#include "gmock/gmock-generated-nice-strict.h"
#include "gmock/gmock-generated-matchers.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
+#include "gmock/gmock-nice-strict.h"
#include "gmock/internal/gmock-internal-utils.h"
+#ifdef __clang__
+#if __has_warning("-Wdeprecated-copy")
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-copy"
+#endif
+#endif
+
namespace testing {
// Declares Google Mock flags that we want a user to use programmatically.
GMOCK_DECLARE_bool_(catch_leaked_mocks);
GMOCK_DECLARE_string_(verbose);
+GMOCK_DECLARE_int32_(default_mock_behavior);
// Initializes Google Mock. This must be called before running the
// tests. In particular, it parses the command line for the flags
@@ -89,6 +99,16 @@
// UNICODE mode.
GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv);
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleMock();
+
} // namespace testing
+#ifdef __clang__
+#if __has_warning("-Wdeprecated-copy")
+#pragma clang diagnostic pop
+#endif
+#endif
+
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
index 7dc3b1a..92d910c 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-generated-actions.h
@@ -2,6 +2,8 @@
// pump.py gmock-generated-actions.h.pump
// DO NOT EDIT BY HAND!!!
+// GOOGLETEST_CM0002 DO NOT DELETE
+
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-matchers.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-matchers.h
index f2efef9..14aafaa 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-matchers.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-matchers.h
@@ -27,13 +27,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// ============================================================
-// An installation-specific extension point for gmock-matchers.h.
-// ============================================================
+// Injection point for custom user configurations. See README for details
//
-// Adds google3 callback support to CallableTraits.
-//
-#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
-#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
+// GOOGLETEST_CM0002 DO NOT DELETE
-#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_CALLBACK_MATCHERS_H_
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-port.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-port.h
index 9ce8bfe..0030fe9 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-port.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/custom/gmock-port.h
@@ -27,19 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Injection point for custom user configurations.
-// The following macros can be defined:
-//
-// Flag related macros:
-// GMOCK_DECLARE_bool_(name)
-// GMOCK_DECLARE_int32_(name)
-// GMOCK_DECLARE_string_(name)
-// GMOCK_DEFINE_bool_(name, default_val, doc)
-// GMOCK_DEFINE_int32_(name, default_val, doc)
-// GMOCK_DEFINE_string_(name, default_val, doc)
+// Injection point for custom user configurations. See README for details
//
// ** Custom implementation starts here **
+// GOOGLETEST_CM0002 DO NOT DELETE
+
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
deleted file mode 100644
index ff69b7f..0000000
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-generated-internal-utils.h
+++ /dev/null
@@ -1,281 +0,0 @@
-// This file was GENERATED by command:
-// pump.py gmock-generated-internal-utils.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 2007, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
-
-// Google Mock - a framework for writing C++ mock classes.
-//
-// This file contains template meta-programming utility classes needed
-// for implementing Google Mock.
-
-// IWYU pragma: private, include "gmock/gmock.h"
-
-#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
-
-#include "gmock/internal/gmock-port.h"
-
-namespace testing {
-
-template <typename T>
-class Matcher;
-
-namespace internal {
-
-// An IgnoredValue object can be implicitly constructed from ANY value.
-// This is used in implementing the IgnoreResult(a) action.
-class IgnoredValue {
- public:
- // This constructor template allows any value to be implicitly
- // converted to IgnoredValue. The object has no data member and
- // doesn't try to remember anything about the argument. We
- // deliberately omit the 'explicit' keyword in order to allow the
- // conversion to be implicit.
- template <typename T>
- IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
-};
-
-// MatcherTuple<T>::type is a tuple type where each field is a Matcher
-// for the corresponding field in tuple type T.
-template <typename Tuple>
-struct MatcherTuple;
-
-template <>
-struct MatcherTuple< ::testing::tuple<> > {
- typedef ::testing::tuple< > type;
-};
-
-template <typename A1>
-struct MatcherTuple< ::testing::tuple<A1> > {
- typedef ::testing::tuple<Matcher<A1> > type;
-};
-
-template <typename A1, typename A2>
-struct MatcherTuple< ::testing::tuple<A1, A2> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2> > type;
-};
-
-template <typename A1, typename A2, typename A3>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>,
- Matcher<A4> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9> > type;
-};
-
-template <typename A1, typename A2, typename A3, typename A4, typename A5,
- typename A6, typename A7, typename A8, typename A9, typename A10>
-struct MatcherTuple< ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
- A10> > {
- typedef ::testing::tuple<Matcher<A1>, Matcher<A2>, Matcher<A3>, Matcher<A4>,
- Matcher<A5>, Matcher<A6>, Matcher<A7>, Matcher<A8>, Matcher<A9>,
- Matcher<A10> > type;
-};
-
-// Template struct Function<F>, where F must be a function type, contains
-// the following typedefs:
-//
-// Result: the function's return type.
-// ArgumentN: the type of the N-th argument, where N starts with 1.
-// ArgumentTuple: the tuple type consisting of all parameters of F.
-// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
-// parameters of F.
-// MakeResultVoid: the function type obtained by substituting void
-// for the return type of F.
-// MakeResultIgnoredValue:
-// the function type obtained by substituting Something
-// for the return type of F.
-template <typename F>
-struct Function;
-
-template <typename R>
-struct Function<R()> {
- typedef R Result;
- typedef ::testing::tuple<> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid();
- typedef IgnoredValue MakeResultIgnoredValue();
-};
-
-template <typename R, typename A1>
-struct Function<R(A1)>
- : Function<R()> {
- typedef A1 Argument1;
- typedef ::testing::tuple<A1> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1);
- typedef IgnoredValue MakeResultIgnoredValue(A1);
-};
-
-template <typename R, typename A1, typename A2>
-struct Function<R(A1, A2)>
- : Function<R(A1)> {
- typedef A2 Argument2;
- typedef ::testing::tuple<A1, A2> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2);
-};
-
-template <typename R, typename A1, typename A2, typename A3>
-struct Function<R(A1, A2, A3)>
- : Function<R(A1, A2)> {
- typedef A3 Argument3;
- typedef ::testing::tuple<A1, A2, A3> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4>
-struct Function<R(A1, A2, A3, A4)>
- : Function<R(A1, A2, A3)> {
- typedef A4 Argument4;
- typedef ::testing::tuple<A1, A2, A3, A4> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5>
-struct Function<R(A1, A2, A3, A4, A5)>
- : Function<R(A1, A2, A3, A4)> {
- typedef A5 Argument5;
- typedef ::testing::tuple<A1, A2, A3, A4, A5> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4, A5);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6>
-struct Function<R(A1, A2, A3, A4, A5, A6)>
- : Function<R(A1, A2, A3, A4, A5)> {
- typedef A6 Argument6;
- typedef ::testing::tuple<A1, A2, A3, A4, A5, A6> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7)>
- : Function<R(A1, A2, A3, A4, A5, A6)> {
- typedef A7 Argument7;
- typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8)>
- : Function<R(A1, A2, A3, A4, A5, A6, A7)> {
- typedef A8 Argument8;
- typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
- : Function<R(A1, A2, A3, A4, A5, A6, A7, A8)> {
- typedef A9 Argument9;
- typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
- A9);
-};
-
-template <typename R, typename A1, typename A2, typename A3, typename A4,
- typename A5, typename A6, typename A7, typename A8, typename A9,
- typename A10>
-struct Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
- : Function<R(A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
- typedef A10 Argument10;
- typedef ::testing::tuple<A1, A2, A3, A4, A5, A6, A7, A8, A9,
- A10> ArgumentTuple;
- typedef typename MatcherTuple<ArgumentTuple>::type ArgumentMatcherTuple;
- typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
- typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8,
- A9, A10);
-};
-
-} // namespace internal
-
-} // namespace testing
-
-#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-internal-utils.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-internal-utils.h
index 6572617..b953350 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-internal-utils.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-internal-utils.h
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -35,6 +34,8 @@
// Mock. They are subject to change without notice, so please DO NOT
// USE THEM IN USER CODE.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
@@ -43,19 +44,34 @@
#include <stdio.h>
#include <ostream> // NOLINT
#include <string>
-
-#include "gmock/internal/gmock-generated-internal-utils.h"
+#include <type_traits>
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"
namespace testing {
+
+template <typename>
+class Matcher;
+
namespace internal {
+// Silence MSVC C4100 (unreferenced formal parameter) and
+// C4805('==': unsafe mix of type 'const int' and type 'const bool')
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4100)
+# pragma warning(disable:4805)
+#endif
+
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields);
+
// Converts an identifier name to a space-separated list of lower-case
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123".
-GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name);
+GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name);
// PointeeOf<Pointer>::type is the type of a value pointed to by a
// Pointer, which can be either a smart pointer or a raw pointer. The
@@ -82,44 +98,16 @@
template <typename Element>
inline Element* GetRawPointer(Element* p) { return p; }
-// This comparator allows linked_ptr to be stored in sets.
-template <typename T>
-struct LinkedPtrLessThan {
- bool operator()(const ::testing::internal::linked_ptr<T>& lhs,
- const ::testing::internal::linked_ptr<T>& rhs) const {
- return lhs.get() < rhs.get();
- }
-};
-
-// Symbian compilation can be done with wchar_t being either a native
-// type or a typedef. Using Google Mock with OpenC without wchar_t
-// should require the definition of _STLP_NO_WCHAR_T.
-//
// MSVC treats wchar_t as a native type usually, but treats it as the
// same as unsigned short when the compiler option /Zc:wchar_t- is
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
// is a native type.
-#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \
- (defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED))
+#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
// wchar_t is a typedef.
#else
# define GMOCK_WCHAR_T_IS_NATIVE_ 1
#endif
-// signed wchar_t and unsigned wchar_t are NOT in the C++ standard.
-// Using them is a bad practice and not portable. So DON'T use them.
-//
-// Still, Google Mock is designed to work even if the user uses signed
-// wchar_t or unsigned wchar_t (obviously, assuming the compiler
-// supports them).
-//
-// To gcc,
-// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int
-#ifdef __GNUC__
-// signed/unsigned wchar_t are valid types.
-# define GMOCK_HAS_SIGNED_WCHAR_T_ 1
-#endif
-
// In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type,
// or none of them. This categorization is useful for determining
@@ -171,11 +159,11 @@
static_cast< ::testing::internal::TypeKind>( \
::testing::internal::KindOf<type>::value)
-// Evaluates to true iff integer type T is signed.
+// Evaluates to true if and only if integer type T is signed.
#define GMOCK_IS_SIGNED_(T) (static_cast<T>(-1) < 0)
// LosslessArithmeticConvertibleImpl<kFromKind, From, kToKind, To>::value
-// is true iff arithmetic type From can be losslessly converted to
+// is true if and only if arithmetic type From can be losslessly converted to
// arithmetic type To.
//
// It's the user's responsibility to ensure that both From and To are
@@ -184,30 +172,30 @@
// From, and kToKind is the kind of To; the value is
// implementation-defined when the above pre-condition is violated.
template <TypeKind kFromKind, typename From, TypeKind kToKind, typename To>
-struct LosslessArithmeticConvertibleImpl : public false_type {};
+struct LosslessArithmeticConvertibleImpl : public std::false_type {};
// Converting bool to bool is lossless.
template <>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kBool, bool>
- : public true_type {}; // NOLINT
+ : public std::true_type {};
// Converting bool to any integer type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kInteger, To>
- : public true_type {}; // NOLINT
+ : public std::true_type {};
// Converting bool to any floating-point type is lossless.
template <typename To>
struct LosslessArithmeticConvertibleImpl<kBool, bool, kFloatingPoint, To>
- : public true_type {}; // NOLINT
+ : public std::true_type {};
// Converting an integer to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kBool, bool>
- : public false_type {}; // NOLINT
+ : public std::false_type {};
-// Converting an integer to another non-bool integer is lossless iff
-// the target type's range encloses the source type's range.
+// Converting an integer to another non-bool integer is lossless
+// if and only if the target type's range encloses the source type's range.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kInteger, To>
: public bool_constant<
@@ -225,27 +213,27 @@
// the format of a floating-point number is implementation-defined.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kInteger, From, kFloatingPoint, To>
- : public false_type {}; // NOLINT
+ : public std::false_type {};
// Converting a floating-point to bool is lossy.
template <typename From>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kBool, bool>
- : public false_type {}; // NOLINT
+ : public std::false_type {};
// Converting a floating-point to an integer is lossy.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<kFloatingPoint, From, kInteger, To>
- : public false_type {}; // NOLINT
+ : public std::false_type {};
// Converting a floating-point to another floating-point is lossless
-// iff the target type is at least as big as the source type.
+// if and only if the target type is at least as big as the source type.
template <typename From, typename To>
struct LosslessArithmeticConvertibleImpl<
kFloatingPoint, From, kFloatingPoint, To>
: public bool_constant<sizeof(From) <= sizeof(To)> {}; // NOLINT
-// LosslessArithmeticConvertible<From, To>::value is true iff arithmetic
-// type From can be losslessly converted to arithmetic type To.
+// LosslessArithmeticConvertible<From, To>::value is true if and only if
+// arithmetic type From can be losslessly converted to arithmetic type To.
//
// It's the user's responsibility to ensure that both From and To are
// raw (i.e. has no CV modifier, is not a pointer, and is not a
@@ -269,7 +257,7 @@
// Reports a failure that occurred at the given source file location.
virtual void ReportFailure(FailureType type, const char* file, int line,
- const string& message) = 0;
+ const std::string& message) = 0;
};
// Returns the failure reporter used by Google Mock.
@@ -281,7 +269,7 @@
// inline this function to prevent it from showing up in the stack
// trace.
inline void Assert(bool condition, const char* file, int line,
- const string& msg) {
+ const std::string& msg) {
if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal,
file, line, msg);
@@ -294,7 +282,7 @@
// Verifies that condition is true; generates a non-fatal failure if
// condition is false.
inline void Expect(bool condition, const char* file, int line,
- const string& msg) {
+ const std::string& msg) {
if (!condition) {
GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal,
file, line, msg);
@@ -319,50 +307,37 @@
// No logs are printed.
const char kErrorVerbosity[] = "error";
-// Returns true iff a log with the given severity is visible according
-// to the --gmock_verbose flag.
+// Returns true if and only if a log with the given severity is visible
+// according to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity);
-// Prints the given message to stdout iff 'severity' >= the level
+// Prints the given message to stdout if and only if 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames. In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
-GTEST_API_ void Log(LogSeverity severity,
- const string& message,
+GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip);
-// TODO([email protected]): group all type utilities together.
+// A marker class that is used to resolve parameterless expectations to the
+// correct overload. This must not be instantiable, to prevent client code from
+// accidentally resolving to the overload; for example:
+//
+// ON_CALL(mock, Method({}, nullptr))...
+//
+class WithoutMatchers {
+ private:
+ WithoutMatchers() {}
+ friend GTEST_API_ WithoutMatchers GetWithoutMatchers();
+};
+
+// Internal use only: access the singleton instance of WithoutMatchers.
+GTEST_API_ WithoutMatchers GetWithoutMatchers();
// Type traits.
-// is_reference<T>::value is non-zero iff T is a reference type.
-template <typename T> struct is_reference : public false_type {};
-template <typename T> struct is_reference<T&> : public true_type {};
-
-// type_equals<T1, T2>::value is non-zero iff T1 and T2 are the same type.
-template <typename T1, typename T2> struct type_equals : public false_type {};
-template <typename T> struct type_equals<T, T> : public true_type {};
-
-// remove_reference<T>::type removes the reference from type T, if any.
-template <typename T> struct remove_reference { typedef T type; }; // NOLINT
-template <typename T> struct remove_reference<T&> { typedef T type; }; // NOLINT
-
-// DecayArray<T>::type turns an array type U[N] to const U* and preserves
-// other types. Useful for saving a copy of a function argument.
-template <typename T> struct DecayArray { typedef T type; }; // NOLINT
-template <typename T, size_t N> struct DecayArray<T[N]> {
- typedef const T* type;
-};
-// Sometimes people use arrays whose size is not available at the use site
-// (e.g. extern const char kNamePrefix[]). This specialization covers that
-// case.
-template <typename T> struct DecayArray<T[]> {
- typedef const T* type;
-};
-
// Disable MSVC warnings for infinite recursion, since in this case the
// the recursion is unreachable.
#ifdef _MSC_VER
@@ -411,9 +386,8 @@
typedef const type& const_reference;
static const_reference ConstReference(const RawContainer& container) {
- // Ensures that RawContainer is not a const type.
- testing::StaticAssertTypeEq<RawContainer,
- GTEST_REMOVE_CONST_(RawContainer)>();
+ static_assert(!std::is_const<RawContainer>::value,
+ "RawContainer type must not be const");
return container;
}
static type Copy(const RawContainer& container) { return container; }
@@ -423,7 +397,7 @@
template <typename Element, size_t N>
class StlContainerView<Element[N]> {
public:
- typedef GTEST_REMOVE_CONST_(Element) RawElement;
+ typedef typename std::remove_const<Element>::type RawElement;
typedef internal::NativeArray<RawElement> type;
// NativeArray<T> can represent a native array either by value or by
// reference (selected by a constructor argument), so 'const type'
@@ -433,53 +407,32 @@
typedef const type const_reference;
static const_reference ConstReference(const Element (&array)[N]) {
- // Ensures that Element is not a const type.
- testing::StaticAssertTypeEq<Element, RawElement>();
-#if GTEST_OS_SYMBIAN
- // The Nokia Symbian compiler confuses itself in template instantiation
- // for this call without the cast to Element*:
- // function call '[testing::internal::NativeArray<char *>].NativeArray(
- // {lval} const char *[4], long, testing::internal::RelationToSource)'
- // does not match
- // 'testing::internal::NativeArray<char *>::NativeArray(
- // char *const *, unsigned int, testing::internal::RelationToSource)'
- // (instantiating: 'testing::internal::ContainsMatcherImpl
- // <const char * (&)[4]>::Matches(const char * (&)[4]) const')
- // (instantiating: 'testing::internal::StlContainerView<char *[4]>::
- // ConstReference(const char * (&)[4])')
- // (and though the N parameter type is mismatched in the above explicit
- // conversion of it doesn't help - only the conversion of the array).
- return type(const_cast<Element*>(&array[0]), N,
- RelationToSourceReference());
-#else
+ static_assert(std::is_same<Element, RawElement>::value,
+ "Element type must not be const");
return type(array, N, RelationToSourceReference());
-#endif // GTEST_OS_SYMBIAN
}
static type Copy(const Element (&array)[N]) {
-#if GTEST_OS_SYMBIAN
- return type(const_cast<Element*>(&array[0]), N, RelationToSourceCopy());
-#else
return type(array, N, RelationToSourceCopy());
-#endif // GTEST_OS_SYMBIAN
}
};
// This specialization is used when RawContainer is a native array
// represented as a (pointer, size) tuple.
template <typename ElementPointer, typename Size>
-class StlContainerView< ::testing::tuple<ElementPointer, Size> > {
+class StlContainerView< ::std::tuple<ElementPointer, Size> > {
public:
- typedef GTEST_REMOVE_CONST_(
- typename internal::PointeeOf<ElementPointer>::type) RawElement;
+ typedef typename std::remove_const<
+ typename internal::PointeeOf<ElementPointer>::type>::type RawElement;
typedef internal::NativeArray<RawElement> type;
typedef const type const_reference;
static const_reference ConstReference(
- const ::testing::tuple<ElementPointer, Size>& array) {
- return type(get<0>(array), get<1>(array), RelationToSourceReference());
+ const ::std::tuple<ElementPointer, Size>& array) {
+ return type(std::get<0>(array), std::get<1>(array),
+ RelationToSourceReference());
}
- static type Copy(const ::testing::tuple<ElementPointer, Size>& array) {
- return type(get<0>(array), get<1>(array), RelationToSourceCopy());
+ static type Copy(const ::std::tuple<ElementPointer, Size>& array) {
+ return type(std::get<0>(array), std::get<1>(array), RelationToSourceCopy());
}
};
@@ -501,13 +454,62 @@
typedef std::pair<K, V> type;
};
-// Mapping from booleans to types. Similar to boost::bool_<kValue> and
-// std::integral_constant<bool, kValue>.
-template <bool kValue>
-struct BooleanConstant {};
+// Emit an assertion failure due to incorrect DoDefault() usage. Out-of-lined to
+// reduce code size.
+GTEST_API_ void IllegalDoDefault(const char* file, int line);
+
+template <typename F, typename Tuple, size_t... Idx>
+auto ApplyImpl(F&& f, Tuple&& args, IndexSequence<Idx...>) -> decltype(
+ std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...)) {
+ return std::forward<F>(f)(std::get<Idx>(std::forward<Tuple>(args))...);
+}
+
+// Apply the function to a tuple of arguments.
+template <typename F, typename Tuple>
+auto Apply(F&& f, Tuple&& args)
+ -> decltype(ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
+ MakeIndexSequence<std::tuple_size<Tuple>::value>())) {
+ return ApplyImpl(std::forward<F>(f), std::forward<Tuple>(args),
+ MakeIndexSequence<std::tuple_size<Tuple>::value>());
+}
+
+// Template struct Function<F>, where F must be a function type, contains
+// the following typedefs:
+//
+// Result: the function's return type.
+// Arg<N>: the type of the N-th argument, where N starts with 0.
+// ArgumentTuple: the tuple type consisting of all parameters of F.
+// ArgumentMatcherTuple: the tuple type consisting of Matchers for all
+// parameters of F.
+// MakeResultVoid: the function type obtained by substituting void
+// for the return type of F.
+// MakeResultIgnoredValue:
+// the function type obtained by substituting Something
+// for the return type of F.
+template <typename T>
+struct Function;
+
+template <typename R, typename... Args>
+struct Function<R(Args...)> {
+ using Result = R;
+ static constexpr size_t ArgumentCount = sizeof...(Args);
+ template <size_t I>
+ using Arg = ElemFromList<I, typename MakeIndexSequence<sizeof...(Args)>::type,
+ Args...>;
+ using ArgumentTuple = std::tuple<Args...>;
+ using ArgumentMatcherTuple = std::tuple<Matcher<Args>...>;
+ using MakeResultVoid = void(Args...);
+ using MakeResultIgnoredValue = IgnoredValue(Args...);
+};
+
+template <typename R, typename... Args>
+constexpr size_t Function<R(Args...)>::ArgumentCount;
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
} // namespace internal
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_
-
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-port.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-port.h
index 0a2935d..27e4c0c 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-port.h
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-port.h
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Vadim Berman)
+
//
// Low-level types and utilities for porting Google Mock to various
// platforms. All macros ending with _ and symbols defined in an
@@ -36,6 +35,8 @@
// end with _ are part of Google Mock's public API and can be used by
// code outside Google Mock.
+// GOOGLETEST_CM0002 DO NOT DELETE
+
// IWYU pragma: private, include "gmock/gmock.h"
#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_
@@ -52,19 +53,14 @@
// portability utilities to Google Test's gtest-port.h instead of
// here, as Google Mock depends on Google Test. Only add a utility
// here if it's truly specific to Google Mock.
-#include "gtest/internal/gtest-linked_ptr.h"
+
#include "gtest/internal/gtest-port.h"
#include "gmock/internal/custom/gmock-port.h"
-// To avoid conditional compilation everywhere, we make it
-// gmock-port.h's responsibility to #include the header implementing
-// tr1/tuple. gmock-port.h does this via gtest-port.h, which is
-// guaranteed to pull in the tuple header.
-
-// For MS Visual C++, check the compiler version. At least VS 2003 is
+// For MS Visual C++, check the compiler version. At least VS 2015 is
// required to compile Google Mock.
-#if defined(_MSC_VER) && _MSC_VER < 1310
-# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock."
+#if defined(_MSC_VER) && _MSC_VER < 1900
+# error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
#endif
// Macro for referencing flags. This is public as we want the user to
@@ -74,18 +70,18 @@
#if !defined(GMOCK_DECLARE_bool_)
// Macros for declaring flags.
-#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
-#define GMOCK_DECLARE_int32_(name) \
+# define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name)
+# define GMOCK_DECLARE_int32_(name) \
extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name)
-#define GMOCK_DECLARE_string_(name) \
+# define GMOCK_DECLARE_string_(name) \
extern GTEST_API_ ::std::string GMOCK_FLAG(name)
// Macros for defining flags.
-#define GMOCK_DEFINE_bool_(name, default_val, doc) \
+# define GMOCK_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GMOCK_FLAG(name) = (default_val)
-#define GMOCK_DEFINE_int32_(name, default_val, doc) \
+# define GMOCK_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val)
-#define GMOCK_DEFINE_string_(name, default_val, doc) \
+# define GMOCK_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val)
#endif // !defined(GMOCK_DECLARE_bool_)
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-pp.h b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-pp.h
new file mode 100644
index 0000000..1ab80e1
--- /dev/null
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/include/gmock/internal/gmock-pp.h
@@ -0,0 +1,317 @@
+#ifndef THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
+#define THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_PP_H_
+
+#undef GMOCK_PP_INTERNAL_USE_MSVC
+#if defined(__clang__)
+#define GMOCK_PP_INTERNAL_USE_MSVC 0
+#elif defined(_MSC_VER)
+// TODO(iserna): Also verify tradional versus comformant preprocessor.
+static_assert(
+ _MSC_VER >= 1900,
+ "MSVC version not supported. There is support for MSVC 14.0 and above.");
+#define GMOCK_PP_INTERNAL_USE_MSVC 1
+#else
+#define GMOCK_PP_INTERNAL_USE_MSVC 0
+#endif
+
+// Expands and concatenates the arguments. Constructed macros reevaluate.
+#define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2)
+
+// Expands and stringifies the only argument.
+#define GMOCK_PP_STRINGIZE(...) GMOCK_PP_INTERNAL_STRINGIZE(__VA_ARGS__)
+
+// Returns empty. Given a variadic number of arguments.
+#define GMOCK_PP_EMPTY(...)
+
+// Returns a comma. Given a variadic number of arguments.
+#define GMOCK_PP_COMMA(...) ,
+
+// Returns the only argument.
+#define GMOCK_PP_IDENTITY(_1) _1
+
+// MSVC preprocessor collapses __VA_ARGS__ in a single argument, we use a
+// CAT-like directive to force correct evaluation. Each macro has its own.
+#if GMOCK_PP_INTERNAL_USE_MSVC
+
+// Evaluates to the number of arguments after expansion.
+//
+// #define PAIR x, y
+//
+// GMOCK_PP_NARG() => 1
+// GMOCK_PP_NARG(x) => 1
+// GMOCK_PP_NARG(x, y) => 2
+// GMOCK_PP_NARG(PAIR) => 2
+//
+// Requires: the number of arguments after expansion is at most 15.
+#define GMOCK_PP_NARG(...) \
+ GMOCK_PP_INTERNAL_NARG_CAT( \
+ GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, \
+ 8, 7, 6, 5, 4, 3, 2, 1), )
+
+// Returns 1 if the expansion of arguments has an unprotected comma. Otherwise
+// returns 0. Requires no more than 15 unprotected commas.
+#define GMOCK_PP_HAS_COMMA(...) \
+ GMOCK_PP_INTERNAL_HAS_COMMA_CAT( \
+ GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 1, 0), )
+// Returns the first argument.
+#define GMOCK_PP_HEAD(...) \
+ GMOCK_PP_INTERNAL_HEAD_CAT(GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__), )
+
+// Returns the tail. A variadic list of all arguments minus the first. Requires
+// at least one argument.
+#define GMOCK_PP_TAIL(...) \
+ GMOCK_PP_INTERNAL_TAIL_CAT(GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__), )
+
+// Calls CAT(_Macro, NARG(__VA_ARGS__))(__VA_ARGS__)
+#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
+ GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT( \
+ GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__), )
+
+#else // GMOCK_PP_INTERNAL_USE_MSVC
+
+#define GMOCK_PP_NARG(...) \
+ GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 15, 14, 13, 12, 11, 10, 9, 8, \
+ 7, 6, 5, 4, 3, 2, 1)
+#define GMOCK_PP_HAS_COMMA(...) \
+ GMOCK_PP_INTERNAL_INTERNAL_16TH(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
+ 1, 1, 1, 1, 0)
+#define GMOCK_PP_HEAD(...) GMOCK_PP_INTERNAL_HEAD(__VA_ARGS__)
+#define GMOCK_PP_TAIL(...) GMOCK_PP_INTERNAL_TAIL(__VA_ARGS__)
+#define GMOCK_PP_VARIADIC_CALL(_Macro, ...) \
+ GMOCK_PP_CAT(_Macro, GMOCK_PP_NARG(__VA_ARGS__))(__VA_ARGS__)
+
+#endif // GMOCK_PP_INTERNAL_USE_MSVC
+
+// If the arguments after expansion have no tokens, evaluates to `1`. Otherwise
+// evaluates to `0`.
+//
+// Requires: * the number of arguments after expansion is at most 15.
+// * If the argument is a macro, it must be able to be called with one
+// argument.
+//
+// Implementation details:
+//
+// There is one case when it generates a compile error: if the argument is macro
+// that cannot be called with one argument.
+//
+// #define M(a, b) // it doesn't matter what it expands to
+//
+// // Expected: expands to `0`.
+// // Actual: compile error.
+// GMOCK_PP_IS_EMPTY(M)
+//
+// There are 4 cases tested:
+//
+// * __VA_ARGS__ possible expansion has no unparen'd commas. Expected 0.
+// * __VA_ARGS__ possible expansion is not enclosed in parenthesis. Expected 0.
+// * __VA_ARGS__ possible expansion is not a macro that ()-evaluates to a comma.
+// Expected 0
+// * __VA_ARGS__ is empty, or has unparen'd commas, or is enclosed in
+// parenthesis, or is a macro that ()-evaluates to comma. Expected 1.
+//
+// We trigger detection on '0001', i.e. on empty.
+#define GMOCK_PP_IS_EMPTY(...) \
+ GMOCK_PP_INTERNAL_IS_EMPTY(GMOCK_PP_HAS_COMMA(__VA_ARGS__), \
+ GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__), \
+ GMOCK_PP_HAS_COMMA(__VA_ARGS__()), \
+ GMOCK_PP_HAS_COMMA(GMOCK_PP_COMMA __VA_ARGS__()))
+
+// Evaluates to _Then if _Cond is 1 and _Else if _Cond is 0.
+#define GMOCK_PP_IF(_Cond, _Then, _Else) \
+ GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IF_, _Cond)(_Then, _Else)
+
+// Evaluates to the number of arguments after expansion. Identifies 'empty' as
+// 0.
+//
+// #define PAIR x, y
+//
+// GMOCK_PP_NARG0() => 0
+// GMOCK_PP_NARG0(x) => 1
+// GMOCK_PP_NARG0(x, y) => 2
+// GMOCK_PP_NARG0(PAIR) => 2
+//
+// Requires: * the number of arguments after expansion is at most 15.
+// * If the argument is a macro, it must be able to be called with one
+// argument.
+#define GMOCK_PP_NARG0(...) \
+ GMOCK_PP_IF(GMOCK_PP_IS_EMPTY(__VA_ARGS__), 0, GMOCK_PP_NARG(__VA_ARGS__))
+
+// Expands to 1 if the first argument starts with something in parentheses,
+// otherwise to 0.
+#define GMOCK_PP_IS_BEGIN_PARENS(...) \
+ GMOCK_PP_INTERNAL_ALTERNATE_HEAD( \
+ GMOCK_PP_CAT(GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_, \
+ GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C __VA_ARGS__))
+
+// Expands to 1 is there is only one argument and it is enclosed in parentheses.
+#define GMOCK_PP_IS_ENCLOSED_PARENS(...) \
+ GMOCK_PP_IF(GMOCK_PP_IS_BEGIN_PARENS(__VA_ARGS__), \
+ GMOCK_PP_IS_EMPTY(GMOCK_PP_EMPTY __VA_ARGS__), 0)
+
+// Remove the parens, requires GMOCK_PP_IS_ENCLOSED_PARENS(args) => 1.
+#define GMOCK_PP_REMOVE_PARENS(...) GMOCK_PP_INTERNAL_REMOVE_PARENS __VA_ARGS__
+
+// Expands to _Macro(0, _Data, e1) _Macro(1, _Data, e2) ... _Macro(K -1, _Data,
+// eK) as many of GMOCK_INTERNAL_NARG0 _Tuple.
+// Requires: * |_Macro| can be called with 3 arguments.
+// * |_Tuple| expansion has no more than 15 elements.
+#define GMOCK_PP_FOR_EACH(_Macro, _Data, _Tuple) \
+ GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, GMOCK_PP_NARG0 _Tuple) \
+ (0, _Macro, _Data, _Tuple)
+
+// Expands to _Macro(0, _Data, ) _Macro(1, _Data, ) ... _Macro(K - 1, _Data, )
+// Empty if _K = 0.
+// Requires: * |_Macro| can be called with 3 arguments.
+// * |_K| literal between 0 and 15
+#define GMOCK_PP_REPEAT(_Macro, _Data, _N) \
+ GMOCK_PP_CAT(GMOCK_PP_INTERNAL_FOR_EACH_IMPL_, _N) \
+ (0, _Macro, _Data, GMOCK_PP_INTENRAL_EMPTY_TUPLE)
+
+// Increments the argument, requires the argument to be between 0 and 15.
+#define GMOCK_PP_INC(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_INC_, _i)
+
+// Returns comma if _i != 0. Requires _i to be between 0 and 15.
+#define GMOCK_PP_COMMA_IF(_i) GMOCK_PP_CAT(GMOCK_PP_INTERNAL_COMMA_IF_, _i)
+
+// Internal details follow. Do not use any of these symbols outside of this
+// file or we will break your code.
+#define GMOCK_PP_INTENRAL_EMPTY_TUPLE (, , , , , , , , , , , , , , , )
+#define GMOCK_PP_INTERNAL_CAT(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_STRINGIZE(...) #__VA_ARGS__
+#define GMOCK_PP_INTERNAL_INTERNAL_16TH(_1, _2, _3, _4, _5, _6, _7, _8, _9, \
+ _10, _11, _12, _13, _14, _15, _16, \
+ ...) \
+ _16
+#define GMOCK_PP_INTERNAL_CAT_5(_1, _2, _3, _4, _5) _1##_2##_3##_4##_5
+#define GMOCK_PP_INTERNAL_IS_EMPTY(_1, _2, _3, _4) \
+ GMOCK_PP_HAS_COMMA(GMOCK_PP_INTERNAL_CAT_5(GMOCK_PP_INTERNAL_IS_EMPTY_CASE_, \
+ _1, _2, _3, _4))
+#define GMOCK_PP_INTERNAL_IS_EMPTY_CASE_0001 ,
+#define GMOCK_PP_INTERNAL_IF_1(_Then, _Else) _Then
+#define GMOCK_PP_INTERNAL_IF_0(_Then, _Else) _Else
+#define GMOCK_PP_INTERNAL_HEAD(_1, ...) _1
+#define GMOCK_PP_INTERNAL_TAIL(_1, ...) __VA_ARGS__
+
+#if GMOCK_PP_INTERNAL_USE_MSVC
+#define GMOCK_PP_INTERNAL_NARG_CAT(_1, _2) GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_HEAD_CAT(_1, _2) GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT(_1, _2) \
+ GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_TAIL_CAT(_1, _2) GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT(_1, _2) \
+ GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_NARG_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_HEAD_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_HAS_COMMA_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_TAIL_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_VARIADIC_CALL_CAT_I(_1, _2) _1##_2
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) \
+ GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(GMOCK_PP_HEAD(__VA_ARGS__), )
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT(_1, _2) \
+ GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2)
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD_CAT_I(_1, _2) _1##_2
+#else // GMOCK_PP_INTERNAL_USE_MSVC
+#define GMOCK_PP_INTERNAL_ALTERNATE_HEAD(...) GMOCK_PP_HEAD(__VA_ARGS__)
+#endif // GMOCK_PP_INTERNAL_USE_MSVC
+
+#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C(...) 1 _
+#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_1 1,
+#define GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_R_GMOCK_PP_INTERNAL_IBP_IS_VARIADIC_C \
+ 0,
+#define GMOCK_PP_INTERNAL_REMOVE_PARENS(...) __VA_ARGS__
+#define GMOCK_PP_INTERNAL_INC_0 1
+#define GMOCK_PP_INTERNAL_INC_1 2
+#define GMOCK_PP_INTERNAL_INC_2 3
+#define GMOCK_PP_INTERNAL_INC_3 4
+#define GMOCK_PP_INTERNAL_INC_4 5
+#define GMOCK_PP_INTERNAL_INC_5 6
+#define GMOCK_PP_INTERNAL_INC_6 7
+#define GMOCK_PP_INTERNAL_INC_7 8
+#define GMOCK_PP_INTERNAL_INC_8 9
+#define GMOCK_PP_INTERNAL_INC_9 10
+#define GMOCK_PP_INTERNAL_INC_10 11
+#define GMOCK_PP_INTERNAL_INC_11 12
+#define GMOCK_PP_INTERNAL_INC_12 13
+#define GMOCK_PP_INTERNAL_INC_13 14
+#define GMOCK_PP_INTERNAL_INC_14 15
+#define GMOCK_PP_INTERNAL_INC_15 16
+#define GMOCK_PP_INTERNAL_COMMA_IF_0
+#define GMOCK_PP_INTERNAL_COMMA_IF_1 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_2 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_3 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_4 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_5 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_6 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_7 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_8 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_9 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_10 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_11 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_12 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_13 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_14 ,
+#define GMOCK_PP_INTERNAL_COMMA_IF_15 ,
+#define GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, _element) \
+ _Macro(_i, _Data, _element)
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_0(_i, _Macro, _Data, _Tuple)
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple)
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_1(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_2(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_3(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_4(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_5(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_6(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_7(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_8(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_9(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_10(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_11(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_12(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_13(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+#define GMOCK_PP_INTERNAL_FOR_EACH_IMPL_15(_i, _Macro, _Data, _Tuple) \
+ GMOCK_PP_INTERNAL_CALL_MACRO(_Macro, _i, _Data, GMOCK_PP_HEAD _Tuple) \
+ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \
+ (GMOCK_PP_TAIL _Tuple))
+
+#endif // THIRD_PARTY_GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-all.cc b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-all.cc
index 7aebce7..e43c9b7 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-all.cc
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-all.cc
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
//
// Google C++ Mocking Framework (Google Mock)
//
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-cardinalities.cc b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-cardinalities.cc
index 50ec728..7463f43 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-cardinalities.cc
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-cardinalities.cc
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -71,18 +70,18 @@
// Conservative estimate on the lower/upper bound of the number of
// calls allowed.
- virtual int ConservativeLowerBound() const { return min_; }
- virtual int ConservativeUpperBound() const { return max_; }
+ int ConservativeLowerBound() const override { return min_; }
+ int ConservativeUpperBound() const override { return max_; }
- virtual bool IsSatisfiedByCallCount(int call_count) const {
+ bool IsSatisfiedByCallCount(int call_count) const override {
return min_ <= call_count && call_count <= max_;
}
- virtual bool IsSaturatedByCallCount(int call_count) const {
+ bool IsSaturatedByCallCount(int call_count) const override {
return call_count >= max_;
}
- virtual void DescribeTo(::std::ostream* os) const;
+ void DescribeTo(::std::ostream* os) const override;
private:
const int min_;
@@ -92,7 +91,7 @@
};
// Formats "n times" in a human-friendly way.
-inline internal::string FormatTimes(int n) {
+inline std::string FormatTimes(int n) {
if (n == 1) {
return "once";
} else if (n == 2) {
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-internal-utils.cc b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-internal-utils.cc
index fb53080..e5b5479 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-internal-utils.cc
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-internal-utils.cc
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -47,12 +46,31 @@
namespace testing {
namespace internal {
+// Joins a vector of strings as if they are fields of a tuple; returns
+// the joined string.
+GTEST_API_ std::string JoinAsTuple(const Strings& fields) {
+ switch (fields.size()) {
+ case 0:
+ return "";
+ case 1:
+ return fields[0];
+ default:
+ std::string result = "(" + fields[0];
+ for (size_t i = 1; i < fields.size(); i++) {
+ result += ", ";
+ result += fields[i];
+ }
+ result += ")";
+ return result;
+ }
+}
+
// Converts an identifier name to a space-separated list of lower-case
// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is
// treated as one word. For example, both "FooBar123" and
// "foo_bar_123" are converted to "foo bar 123".
-GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) {
- string result;
+GTEST_API_ std::string ConvertIdentifierNameToWords(const char* id_name) {
+ std::string result;
char prev_char = '\0';
for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) {
// We don't care about the current locale as the input is
@@ -71,12 +89,12 @@
}
// This class reports Google Mock failures as Google Test failures. A
-// user can define another class in a similar fashion if he intends to
+// user can define another class in a similar fashion if they intend to
// use Google Mock with a testing framework other than Google Test.
class GoogleTestFailureReporter : public FailureReporterInterface {
public:
- virtual void ReportFailure(FailureType type, const char* file, int line,
- const string& message) {
+ void ReportFailure(FailureType type, const char* file, int line,
+ const std::string& message) override {
AssertHelper(type == kFatal ?
TestPartResult::kFatalFailure :
TestPartResult::kNonFatalFailure,
@@ -105,8 +123,8 @@
// Protects global resources (stdout in particular) used by Log().
static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex);
-// Returns true iff a log with the given severity is visible according
-// to the --gmock_verbose flag.
+// Returns true if and only if a log with the given severity is visible
+// according to the --gmock_verbose flag.
GTEST_API_ bool LogIsVisible(LogSeverity severity) {
if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
// Always show the log if --gmock_verbose=info.
@@ -121,15 +139,14 @@
}
}
-// Prints the given message to stdout iff 'severity' >= the level
+// Prints the given message to stdout if and only if 'severity' >= the level
// specified by the --gmock_verbose flag. If stack_frames_to_skip >=
// 0, also prints the stack trace excluding the top
// stack_frames_to_skip frames. In opt mode, any positive
// stack_frames_to_skip is treated as 0, since we don't know which
// function calls will be inlined by the compiler and need to be
// conservative.
-GTEST_API_ void Log(LogSeverity severity,
- const string& message,
+GTEST_API_ void Log(LogSeverity severity, const std::string& message,
int stack_frames_to_skip) {
if (!LogIsVisible(severity))
return;
@@ -137,9 +154,6 @@
// Ensures that logs from different threads don't interleave.
MutexLock l(&g_log_mutex);
- // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a
- // macro.
-
if (severity == kWarning) {
// Prints a GMOCK WARNING marker to make the warnings easily searchable.
std::cout << "\nGMOCK WARNING:";
@@ -170,5 +184,17 @@
std::cout << ::std::flush;
}
+GTEST_API_ WithoutMatchers GetWithoutMatchers() { return WithoutMatchers(); }
+
+GTEST_API_ void IllegalDoDefault(const char* file, int line) {
+ internal::Assert(
+ false, file, line,
+ "You are using DoDefault() inside a composite action like "
+ "DoAll() or WithArgs(). This is not supported for technical "
+ "reasons. Please instead spell out the default action, or "
+ "assign the default action to an Action variable and use "
+ "the variable in various places.");
+}
+
} // namespace internal
} // namespace testing
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-matchers.cc b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-matchers.cc
index e742451..4a3f7af 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-matchers.cc
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-matchers.cc
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -38,98 +37,23 @@
#include "gmock/gmock-generated-matchers.h"
#include <string.h>
+#include <iostream>
#include <sstream>
#include <string>
namespace testing {
-
-// Constructs a matcher that matches a const string& whose value is
-// equal to s.
-Matcher<const internal::string&>::Matcher(const internal::string& s) {
- *this = Eq(s);
-}
-
-// Constructs a matcher that matches a const string& whose value is
-// equal to s.
-Matcher<const internal::string&>::Matcher(const char* s) {
- *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a string whose value is equal to s.
-Matcher<internal::string>::Matcher(const internal::string& s) { *this = Eq(s); }
-
-// Constructs a matcher that matches a string whose value is equal to s.
-Matcher<internal::string>::Matcher(const char* s) {
- *this = Eq(internal::string(s));
-}
-
-#if GTEST_HAS_STRING_PIECE_
-// Constructs a matcher that matches a const StringPiece& whose value is
-// equal to s.
-Matcher<const StringPiece&>::Matcher(const internal::string& s) {
- *this = Eq(s);
-}
-
-// Constructs a matcher that matches a const StringPiece& whose value is
-// equal to s.
-Matcher<const StringPiece&>::Matcher(const char* s) {
- *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a const StringPiece& whose value is
-// equal to s.
-Matcher<const StringPiece&>::Matcher(StringPiece s) {
- *this = Eq(s.ToString());
-}
-
-// Constructs a matcher that matches a StringPiece whose value is equal to s.
-Matcher<StringPiece>::Matcher(const internal::string& s) {
- *this = Eq(s);
-}
-
-// Constructs a matcher that matches a StringPiece whose value is equal to s.
-Matcher<StringPiece>::Matcher(const char* s) {
- *this = Eq(internal::string(s));
-}
-
-// Constructs a matcher that matches a StringPiece whose value is equal to s.
-Matcher<StringPiece>::Matcher(StringPiece s) {
- *this = Eq(s.ToString());
-}
-#endif // GTEST_HAS_STRING_PIECE_
-
namespace internal {
-// Joins a vector of strings as if they are fields of a tuple; returns
-// the joined string.
-GTEST_API_ string JoinAsTuple(const Strings& fields) {
- switch (fields.size()) {
- case 0:
- return "";
- case 1:
- return fields[0];
- default:
- string result = "(" + fields[0];
- for (size_t i = 1; i < fields.size(); i++) {
- result += ", ";
- result += fields[i];
- }
- result += ")";
- return result;
- }
-}
-
// Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if
// 'negation' is false; otherwise returns the description of the
// negation of the matcher. 'param_values' contains a list of strings
// that are the print-out of the matcher's parameters.
-GTEST_API_ string FormatMatcherDescription(bool negation,
- const char* matcher_name,
- const Strings& param_values) {
- string result = ConvertIdentifierNameToWords(matcher_name);
- if (param_values.size() >= 1)
- result += " " + JoinAsTuple(param_values);
+GTEST_API_ std::string FormatMatcherDescription(bool negation,
+ const char* matcher_name,
+ const Strings& param_values) {
+ std::string result = ConvertIdentifierNameToWords(matcher_name);
+ if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values);
return negation ? "not (" + result + ")" : result;
}
@@ -200,8 +124,7 @@
explicit MaxBipartiteMatchState(const MatchMatrix& graph)
: graph_(&graph),
left_(graph_->LhsSize(), kUnused),
- right_(graph_->RhsSize(), kUnused) {
- }
+ right_(graph_->RhsSize(), kUnused) {}
// Returns the edges of a maximal match, each in the form {left, right}.
ElementMatcherPairs Compute() {
@@ -258,10 +181,8 @@
//
bool TryAugment(size_t ilhs, ::std::vector<char>* seen) {
for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) {
- if ((*seen)[irhs])
- continue;
- if (!graph_->HasEdge(ilhs, irhs))
- continue;
+ if ((*seen)[irhs]) continue;
+ if (!graph_->HasEdge(ilhs, irhs)) continue;
// There's an available edge from ilhs to irhs.
(*seen)[irhs] = 1;
// Next a search is performed to determine whether
@@ -288,7 +209,7 @@
// Each element of the left_ vector represents a left hand side node
// (i.e. an element) and each element of right_ is a right hand side
// node (i.e. a matcher). The values in the left_ vector indicate
- // outflow from that node to a node on the the right_ side. The values
+ // outflow from that node to a node on the right_ side. The values
// in the right_ indicate inflow, and specify which left_ node is
// feeding that right_ node, if any. For example, left_[3] == 1 means
// there's a flow from element #3 to matcher #1. Such a flow would also
@@ -304,8 +225,7 @@
const size_t MaxBipartiteMatchState::kUnused;
-GTEST_API_ ElementMatcherPairs
-FindMaxBipartiteMatching(const MatchMatrix& g) {
+GTEST_API_ ElementMatcherPairs FindMaxBipartiteMatching(const MatchMatrix& g) {
return MaxBipartiteMatchState(g).Compute();
}
@@ -314,7 +234,7 @@
typedef ElementMatcherPairs::const_iterator Iter;
::std::ostream& os = *stream;
os << "{";
- const char *sep = "";
+ const char* sep = "";
for (Iter it = pairs.begin(); it != pairs.end(); ++it) {
os << sep << "\n ("
<< "element #" << it->first << ", "
@@ -324,38 +244,6 @@
os << "\n}";
}
-// Tries to find a pairing, and explains the result.
-GTEST_API_ bool FindPairing(const MatchMatrix& matrix,
- MatchResultListener* listener) {
- ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
-
- size_t max_flow = matches.size();
- bool result = (max_flow == matrix.RhsSize());
-
- if (!result) {
- if (listener->IsInterested()) {
- *listener << "where no permutation of the elements can "
- "satisfy all matchers, and the closest match is "
- << max_flow << " of " << matrix.RhsSize()
- << " matchers with the pairings:\n";
- LogElementMatcherPairVec(matches, listener->stream());
- }
- return false;
- }
-
- if (matches.size() > 1) {
- if (listener->IsInterested()) {
- const char *sep = "where:\n";
- for (size_t mi = 0; mi < matches.size(); ++mi) {
- *listener << sep << " - element #" << matches[mi].first
- << " is matched by matcher #" << matches[mi].second;
- sep = ",\n";
- }
- }
- }
- return true;
-}
-
bool MatchMatrix::NextGraph() {
for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) {
for (size_t irhs = 0; irhs < RhsSize(); ++irhs) {
@@ -379,9 +267,9 @@
}
}
-string MatchMatrix::DebugString() const {
+std::string MatchMatrix::DebugString() const {
::std::stringstream ss;
- const char *sep = "";
+ const char* sep = "";
for (size_t i = 0; i < LhsSize(); ++i) {
ss << sep;
for (size_t j = 0; j < RhsSize(); ++j) {
@@ -394,44 +282,83 @@
void UnorderedElementsAreMatcherImplBase::DescribeToImpl(
::std::ostream* os) const {
- if (matcher_describers_.empty()) {
- *os << "is empty";
- return;
+ switch (match_flags()) {
+ case UnorderedMatcherRequire::ExactMatch:
+ if (matcher_describers_.empty()) {
+ *os << "is empty";
+ return;
+ }
+ if (matcher_describers_.size() == 1) {
+ *os << "has " << Elements(1) << " and that element ";
+ matcher_describers_[0]->DescribeTo(os);
+ return;
+ }
+ *os << "has " << Elements(matcher_describers_.size())
+ << " and there exists some permutation of elements such that:\n";
+ break;
+ case UnorderedMatcherRequire::Superset:
+ *os << "a surjection from elements to requirements exists such that:\n";
+ break;
+ case UnorderedMatcherRequire::Subset:
+ *os << "an injection from elements to requirements exists such that:\n";
+ break;
}
- if (matcher_describers_.size() == 1) {
- *os << "has " << Elements(1) << " and that element ";
- matcher_describers_[0]->DescribeTo(os);
- return;
- }
- *os << "has " << Elements(matcher_describers_.size())
- << " and there exists some permutation of elements such that:\n";
+
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
- *os << sep << " - element #" << i << " ";
+ *os << sep;
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ *os << " - element #" << i << " ";
+ } else {
+ *os << " - an element ";
+ }
matcher_describers_[i]->DescribeTo(os);
- sep = ", and\n";
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ sep = ", and\n";
+ } else {
+ sep = "\n";
+ }
}
}
void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl(
::std::ostream* os) const {
- if (matcher_describers_.empty()) {
- *os << "isn't empty";
- return;
+ switch (match_flags()) {
+ case UnorderedMatcherRequire::ExactMatch:
+ if (matcher_describers_.empty()) {
+ *os << "isn't empty";
+ return;
+ }
+ if (matcher_describers_.size() == 1) {
+ *os << "doesn't have " << Elements(1) << ", or has " << Elements(1)
+ << " that ";
+ matcher_describers_[0]->DescribeNegationTo(os);
+ return;
+ }
+ *os << "doesn't have " << Elements(matcher_describers_.size())
+ << ", or there exists no permutation of elements such that:\n";
+ break;
+ case UnorderedMatcherRequire::Superset:
+ *os << "no surjection from elements to requirements exists such that:\n";
+ break;
+ case UnorderedMatcherRequire::Subset:
+ *os << "no injection from elements to requirements exists such that:\n";
+ break;
}
- if (matcher_describers_.size() == 1) {
- *os << "doesn't have " << Elements(1)
- << ", or has " << Elements(1) << " that ";
- matcher_describers_[0]->DescribeNegationTo(os);
- return;
- }
- *os << "doesn't have " << Elements(matcher_describers_.size())
- << ", or there exists no permutation of elements such that:\n";
const char* sep = "";
for (size_t i = 0; i != matcher_describers_.size(); ++i) {
- *os << sep << " - element #" << i << " ";
+ *os << sep;
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ *os << " - element #" << i << " ";
+ } else {
+ *os << " - an element ";
+ }
matcher_describers_[i]->DescribeTo(os);
- sep = ", and\n";
+ if (match_flags() == UnorderedMatcherRequire::ExactMatch) {
+ sep = ", and\n";
+ } else {
+ sep = "\n";
+ }
}
}
@@ -440,11 +367,9 @@
// and better error reporting.
// Returns false, writing an explanation to 'listener', if and only
// if the success criteria are not met.
-bool UnorderedElementsAreMatcherImplBase::
-VerifyAllElementsAndMatchersAreMatched(
- const ::std::vector<string>& element_printouts,
- const MatchMatrix& matrix,
- MatchResultListener* listener) const {
+bool UnorderedElementsAreMatcherImplBase::VerifyMatchMatrix(
+ const ::std::vector<std::string>& element_printouts,
+ const MatchMatrix& matrix, MatchResultListener* listener) const {
bool result = true;
::std::vector<char> element_matched(matrix.LhsSize(), 0);
::std::vector<char> matcher_matched(matrix.RhsSize(), 0);
@@ -457,12 +382,11 @@
}
}
- {
+ if (match_flags() & UnorderedMatcherRequire::Superset) {
const char* sep =
"where the following matchers don't match any elements:\n";
for (size_t mi = 0; mi < matcher_matched.size(); ++mi) {
- if (matcher_matched[mi])
- continue;
+ if (matcher_matched[mi]) continue;
result = false;
if (listener->IsInterested()) {
*listener << sep << "matcher #" << mi << ": ";
@@ -472,7 +396,7 @@
}
}
- {
+ if (match_flags() & UnorderedMatcherRequire::Subset) {
const char* sep =
"where the following elements don't match any matchers:\n";
const char* outer_sep = "";
@@ -480,8 +404,7 @@
outer_sep = "\nand ";
}
for (size_t ei = 0; ei < element_matched.size(); ++ei) {
- if (element_matched[ei])
- continue;
+ if (element_matched[ei]) continue;
result = false;
if (listener->IsInterested()) {
*listener << outer_sep << sep << "element #" << ei << ": "
@@ -494,5 +417,46 @@
return result;
}
+bool UnorderedElementsAreMatcherImplBase::FindPairing(
+ const MatchMatrix& matrix, MatchResultListener* listener) const {
+ ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix);
+
+ size_t max_flow = matches.size();
+ if ((match_flags() & UnorderedMatcherRequire::Superset) &&
+ max_flow < matrix.RhsSize()) {
+ if (listener->IsInterested()) {
+ *listener << "where no permutation of the elements can satisfy all "
+ "matchers, and the closest match is "
+ << max_flow << " of " << matrix.RhsSize()
+ << " matchers with the pairings:\n";
+ LogElementMatcherPairVec(matches, listener->stream());
+ }
+ return false;
+ }
+ if ((match_flags() & UnorderedMatcherRequire::Subset) &&
+ max_flow < matrix.LhsSize()) {
+ if (listener->IsInterested()) {
+ *listener
+ << "where not all elements can be matched, and the closest match is "
+ << max_flow << " of " << matrix.RhsSize()
+ << " matchers with the pairings:\n";
+ LogElementMatcherPairVec(matches, listener->stream());
+ }
+ return false;
+ }
+
+ if (matches.size() > 1) {
+ if (listener->IsInterested()) {
+ const char* sep = "where:\n";
+ for (size_t mi = 0; mi < matches.size(); ++mi) {
+ *listener << sep << " - element #" << matches[mi].first
+ << " is matched by matcher #" << matches[mi].second;
+ sep = ",\n";
+ }
+ }
+ }
+ return true;
+}
+
} // namespace internal
} // namespace testing
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-spec-builders.cc b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-spec-builders.cc
index 9551342..f9d3434 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-spec-builders.cc
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock-spec-builders.cc
@@ -26,8 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
// Google Mock - a framework for writing C++ mock classes.
//
@@ -39,8 +38,10 @@
#include <stdlib.h>
#include <iostream> // NOLINT
#include <map>
+#include <memory>
#include <set>
#include <string>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -48,6 +49,15 @@
# include <unistd.h> // NOLINT
#endif
+// Silence C4800 (C4800: 'int *const ': forcing value
+// to bool 'true' or 'false') for MSVC 15
+#ifdef _MSC_VER
+#if _MSC_VER == 1900
+# pragma warning(push)
+# pragma warning(disable:4800)
+#endif
+#endif
+
namespace testing {
namespace internal {
@@ -58,16 +68,15 @@
// Logs a message including file and line number information.
GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity,
const char* file, int line,
- const string& message) {
+ const std::string& message) {
::std::ostringstream s;
s << file << ":" << line << ": " << message << ::std::endl;
Log(severity, s.str(), 0);
}
// Constructs an ExpectationBase object.
-ExpectationBase::ExpectationBase(const char* a_file,
- int a_line,
- const string& a_source_text)
+ExpectationBase::ExpectationBase(const char* a_file, int a_line,
+ const std::string& a_source_text)
: file_(a_file),
line_(a_line),
source_text_(a_source_text),
@@ -100,26 +109,40 @@
return;
}
- for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
- it != immediate_prerequisites_.end(); ++it) {
- ExpectationBase* const prerequisite = it->expectation_base().get();
- if (!prerequisite->is_retired()) {
- prerequisite->RetireAllPreRequisites();
- prerequisite->Retire();
+ ::std::vector<ExpectationBase*> expectations(1, this);
+ while (!expectations.empty()) {
+ ExpectationBase* exp = expectations.back();
+ expectations.pop_back();
+
+ for (ExpectationSet::const_iterator it =
+ exp->immediate_prerequisites_.begin();
+ it != exp->immediate_prerequisites_.end(); ++it) {
+ ExpectationBase* next = it->expectation_base().get();
+ if (!next->is_retired()) {
+ next->Retire();
+ expectations.push_back(next);
+ }
}
}
}
-// Returns true iff all pre-requisites of this expectation have been
-// satisfied.
+// Returns true if and only if all pre-requisites of this expectation
+// have been satisfied.
bool ExpectationBase::AllPrerequisitesAreSatisfied() const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
- for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
- it != immediate_prerequisites_.end(); ++it) {
- if (!(it->expectation_base()->IsSatisfied()) ||
- !(it->expectation_base()->AllPrerequisitesAreSatisfied()))
- return false;
+ ::std::vector<const ExpectationBase*> expectations(1, this);
+ while (!expectations.empty()) {
+ const ExpectationBase* exp = expectations.back();
+ expectations.pop_back();
+
+ for (ExpectationSet::const_iterator it =
+ exp->immediate_prerequisites_.begin();
+ it != exp->immediate_prerequisites_.end(); ++it) {
+ const ExpectationBase* next = it->expectation_base().get();
+ if (!next->IsSatisfied()) return false;
+ expectations.push_back(next);
+ }
}
return true;
}
@@ -128,19 +151,28 @@
void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
- for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin();
- it != immediate_prerequisites_.end(); ++it) {
- if (it->expectation_base()->IsSatisfied()) {
- // If *it is satisfied and has a call count of 0, some of its
- // pre-requisites may not be satisfied yet.
- if (it->expectation_base()->call_count_ == 0) {
- it->expectation_base()->FindUnsatisfiedPrerequisites(result);
+ ::std::vector<const ExpectationBase*> expectations(1, this);
+ while (!expectations.empty()) {
+ const ExpectationBase* exp = expectations.back();
+ expectations.pop_back();
+
+ for (ExpectationSet::const_iterator it =
+ exp->immediate_prerequisites_.begin();
+ it != exp->immediate_prerequisites_.end(); ++it) {
+ const ExpectationBase* next = it->expectation_base().get();
+
+ if (next->IsSatisfied()) {
+ // If *it is satisfied and has a call count of 0, some of its
+ // pre-requisites may not be satisfied yet.
+ if (next->call_count_ == 0) {
+ expectations.push_back(next);
+ }
+ } else {
+ // Now that we know next is unsatisfied, we are not so interested
+ // in whether its pre-requisites are satisfied. Therefore we
+ // don't iterate into it here.
+ *result += *it;
}
- } else {
- // Now that we know *it is unsatisfied, we are not so interested
- // in whether its pre-requisites are satisfied. Therefore we
- // don't recursively call FindUnsatisfiedPrerequisites() here.
- *result += *it;
}
}
}
@@ -244,7 +276,7 @@
// Reports an uninteresting call (whose description is in msg) in the
// manner specified by 'reaction'.
-void ReportUninterestingCall(CallReaction reaction, const string& msg) {
+void ReportUninterestingCall(CallReaction reaction, const std::string& msg) {
// Include a stack trace only if --gmock_verbose=info is specified.
const int stack_frames_to_skip =
GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1;
@@ -255,20 +287,22 @@
case kWarn:
Log(kWarning,
msg +
- "\nNOTE: You can safely ignore the above warning unless this "
- "call should not happen. Do not suppress it by blindly adding "
- "an EXPECT_CALL() if you don't mean to enforce the call. "
- "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#"
- "knowing-when-to-expect for details.\n",
+ "\nNOTE: You can safely ignore the above warning unless this "
+ "call should not happen. Do not suppress it by blindly adding "
+ "an EXPECT_CALL() if you don't mean to enforce the call. "
+ "See "
+ "https://github.com/google/googletest/blob/master/googlemock/"
+ "docs/cook_book.md#"
+ "knowing-when-to-expect for details.\n",
stack_frames_to_skip);
break;
default: // FAIL
- Expect(false, NULL, -1, msg);
+ Expect(false, nullptr, -1, msg);
}
}
UntypedFunctionMockerBase::UntypedFunctionMockerBase()
- : mock_obj_(NULL), name_("") {}
+ : mock_obj_(nullptr), name_("") {}
UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {}
@@ -307,7 +341,7 @@
// We protect mock_obj_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
- Assert(mock_obj_ != NULL, __FILE__, __LINE__,
+ Assert(mock_obj_ != nullptr, __FILE__, __LINE__,
"MockObject() must not be called before RegisterOwner() or "
"SetOwnerAndName() has been called.");
mock_obj = mock_obj_;
@@ -324,7 +358,7 @@
// We protect name_ under g_gmock_mutex in case this mock
// function is called from two threads concurrently.
MutexLock l(&g_gmock_mutex);
- Assert(name_ != NULL, __FILE__, __LINE__,
+ Assert(name_ != nullptr, __FILE__, __LINE__,
"Name() must not be called before SetOwnerAndName() has "
"been called.");
name = name_;
@@ -335,9 +369,10 @@
// Calculates the result of invoking this mock function with the given
// arguments, prints it, and returns it. The caller is responsible
// for deleting the result.
-UntypedActionResultHolderBase*
-UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args)
- GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+UntypedActionResultHolderBase* UntypedFunctionMockerBase::UntypedInvokeWith(
+ void* const untyped_args) GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
+ // See the definition of untyped_expectations_ for why access to it
+ // is unprotected here.
if (untyped_expectations_.size() == 0) {
// No expectation is set on this mock method - we have an
// uninteresting call.
@@ -349,23 +384,26 @@
const CallReaction reaction =
Mock::GetReactionOnUninterestingCalls(MockObject());
- // True iff we need to print this call's arguments and return
+ // True if and only if we need to print this call's arguments and return
// value. This definition must be kept in sync with
// the behavior of ReportUninterestingCall().
const bool need_to_report_uninteresting_call =
// If the user allows this uninteresting call, we print it
- // only when he wants informational messages.
+ // only when they want informational messages.
reaction == kAllow ? LogIsVisible(kInfo) :
- // If the user wants this to be a warning, we print it only
- // when he wants to see warnings.
- reaction == kWarn ? LogIsVisible(kWarning) :
- // Otherwise, the user wants this to be an error, and we
- // should always print detailed information in the error.
- true;
+ // If the user wants this to be a warning, we print
+ // it only when they want to see warnings.
+ reaction == kWarn
+ ? LogIsVisible(kWarning)
+ :
+ // Otherwise, the user wants this to be an error, and we
+ // should always print detailed information in the error.
+ true;
if (!need_to_report_uninteresting_call) {
// Perform the action without printing the call information.
- return this->UntypedPerformDefaultAction(untyped_args, "");
+ return this->UntypedPerformDefaultAction(
+ untyped_args, "Function call: " + std::string(Name()));
}
// Warns about the uninteresting call.
@@ -377,8 +415,7 @@
this->UntypedPerformDefaultAction(untyped_args, ss.str());
// Prints the function result.
- if (result != NULL)
- result->PrintAsActionResult(&ss);
+ if (result != nullptr) result->PrintAsActionResult(&ss);
ReportUninterestingCall(reaction, ss.str());
return result;
@@ -388,7 +425,7 @@
::std::stringstream ss;
::std::stringstream why;
::std::stringstream loc;
- const void* untyped_action = NULL;
+ const void* untyped_action = nullptr;
// The UntypedFindMatchingExpectation() function acquires and
// releases g_gmock_mutex.
@@ -396,19 +433,19 @@
this->UntypedFindMatchingExpectation(
untyped_args, &untyped_action, &is_excessive,
&ss, &why);
- const bool found = untyped_expectation != NULL;
+ const bool found = untyped_expectation != nullptr;
- // True iff we need to print the call's arguments and return value.
+ // True if and only if we need to print the call's arguments
+ // and return value.
// This definition must be kept in sync with the uses of Expect()
// and Log() in this function.
const bool need_to_report_call =
!found || is_excessive || LogIsVisible(kInfo);
if (!need_to_report_call) {
// Perform the action without printing the call information.
- return
- untyped_action == NULL ?
- this->UntypedPerformDefaultAction(untyped_args, "") :
- this->UntypedPerformAction(untyped_action, untyped_args);
+ return untyped_action == nullptr
+ ? this->UntypedPerformDefaultAction(untyped_args, "")
+ : this->UntypedPerformAction(untyped_action, untyped_args);
}
ss << " Function call: " << Name();
@@ -421,16 +458,15 @@
}
UntypedActionResultHolderBase* const result =
- untyped_action == NULL ?
- this->UntypedPerformDefaultAction(untyped_args, ss.str()) :
- this->UntypedPerformAction(untyped_action, untyped_args);
- if (result != NULL)
- result->PrintAsActionResult(&ss);
+ untyped_action == nullptr
+ ? this->UntypedPerformDefaultAction(untyped_args, ss.str())
+ : this->UntypedPerformAction(untyped_action, untyped_args);
+ if (result != nullptr) result->PrintAsActionResult(&ss);
ss << "\n" << why.str();
if (!found) {
// No expectation matches this call - reports a failure.
- Expect(false, NULL, -1, ss.str());
+ Expect(false, nullptr, -1, ss.str());
} else if (is_excessive) {
// We had an upper-bound violation and the failure message is in ss.
Expect(false, untyped_expectation->file(),
@@ -447,6 +483,8 @@
// Returns an Expectation object that references and co-owns exp,
// which must be an expectation on this mock function.
Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) {
+ // See the definition of untyped_expectations_ for why access to it
+ // is unprotected here.
for (UntypedExpectations::const_iterator it =
untyped_expectations_.begin();
it != untyped_expectations_.end(); ++it) {
@@ -509,6 +547,13 @@
return expectations_met;
}
+CallReaction intToCallReaction(int mock_behavior) {
+ if (mock_behavior >= kAllow && mock_behavior <= kFail) {
+ return static_cast<internal::CallReaction>(mock_behavior);
+ }
+ return kWarn;
+}
+
} // namespace internal
// Class Mock.
@@ -522,15 +567,15 @@
// expectations.
struct MockObjectState {
MockObjectState()
- : first_used_file(NULL), first_used_line(-1), leakable(false) {}
+ : first_used_file(nullptr), first_used_line(-1), leakable(false) {}
// Where in the source file an ON_CALL or EXPECT_CALL is first
// invoked on this mock object.
const char* first_used_file;
int first_used_line;
- ::std::string first_used_test_case;
+ ::std::string first_used_test_suite;
::std::string first_used_test;
- bool leakable; // true iff it's OK to leak the object.
+ bool leakable; // true if and only if it's OK to leak the object.
FunctionMockers function_mockers; // All registered methods of the object.
};
@@ -548,9 +593,6 @@
// object alive. Therefore we report any living object as test
// failure, unless the user explicitly asked us to ignore it.
~MockObjectRegistry() {
- // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is
- // a macro.
-
if (!GMOCK_FLAG(catch_leaked_mocks))
return;
@@ -560,7 +602,7 @@
if (it->second.leakable) // The user said it's fine to leak this object.
continue;
- // TODO([email protected]): Print the type of the leaked object.
+ // FIXME: Print the type of the leaked object.
// This can help the user identify the leaked object.
std::cout << "\n";
const MockObjectState& state = it->second;
@@ -568,17 +610,23 @@
state.first_used_line);
std::cout << " ERROR: this mock object";
if (state.first_used_test != "") {
- std::cout << " (used in test " << state.first_used_test_case << "."
- << state.first_used_test << ")";
+ std::cout << " (used in test " << state.first_used_test_suite << "."
+ << state.first_used_test << ")";
}
std::cout << " should be deleted but never is. Its address is @"
<< it->first << ".";
leaked_count++;
}
if (leaked_count > 0) {
- std::cout << "\nERROR: " << leaked_count
- << " leaked mock " << (leaked_count == 1 ? "object" : "objects")
- << " found at program exit.\n";
+ std::cout << "\nERROR: " << leaked_count << " leaked mock "
+ << (leaked_count == 1 ? "object" : "objects")
+ << " found at program exit. Expectations on a mock object is "
+ "verified when the object is destructed. Leaking a mock "
+ "means that its expectations aren't verified, which is "
+ "usually a test bug. If you really intend to leak a mock, "
+ "you can suppress this error using "
+ "testing::Mock::AllowLeak(mock_object), or you may use a "
+ "fake or stub instead of a mock.\n";
std::cout.flush();
::std::cerr.flush();
// RUN_ALL_TESTS() has already returned when this destructor is
@@ -649,7 +697,8 @@
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
return (g_uninteresting_call_reaction.count(mock_obj) == 0) ?
- internal::kDefault : g_uninteresting_call_reaction[mock_obj];
+ internal::intToCallReaction(GMOCK_FLAG(default_mock_behavior)) :
+ g_uninteresting_call_reaction[mock_obj];
}
// Tells Google Mock to ignore mock_obj when checking for leaked mock
@@ -670,7 +719,7 @@
}
// Verifies all expectations on the given mock object and clears its
-// default actions and expectations. Returns true iff the
+// default actions and expectations. Returns true if and only if the
// verification was successful.
bool Mock::VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
@@ -707,6 +756,19 @@
return expectations_met;
}
+bool Mock::IsNaggy(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+ return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kWarn;
+}
+bool Mock::IsNice(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+ return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kAllow;
+}
+bool Mock::IsStrict(void* mock_obj)
+ GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
+ return Mock::GetReactionOnUninterestingCalls(mock_obj) == internal::kFail;
+}
+
// Registers a mock object and a mock method it owns.
void Mock::Register(const void* mock_obj,
internal::UntypedFunctionMockerBase* mocker)
@@ -723,16 +785,13 @@
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
MockObjectState& state = g_mock_object_registry.states()[mock_obj];
- if (state.first_used_file == NULL) {
+ if (state.first_used_file == nullptr) {
state.first_used_file = file;
state.first_used_line = line;
const TestInfo* const test_info =
UnitTest::GetInstance()->current_test_info();
- if (test_info != NULL) {
- // TODO([email protected]): record the test case name when the
- // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or
- // TearDownTestCase().
- state.first_used_test_case = test_info->test_case_name();
+ if (test_info != nullptr) {
+ state.first_used_test_suite = test_info->test_suite_name();
state.first_used_test = test_info->name();
}
}
@@ -785,7 +844,7 @@
Expectation::Expectation() {}
Expectation::Expectation(
- const internal::linked_ptr<internal::ExpectationBase>& an_expectation_base)
+ const std::shared_ptr<internal::ExpectationBase>& an_expectation_base)
: expectation_base_(an_expectation_base) {}
Expectation::~Expectation() {}
@@ -793,7 +852,7 @@
// Adds an expectation to a sequence.
void Sequence::AddExpectation(const Expectation& expectation) const {
if (*last_expectation_ != expectation) {
- if (last_expectation_->expectation_base() != NULL) {
+ if (last_expectation_->expectation_base() != nullptr) {
expectation.expectation_base()->immediate_prerequisites_
+= *last_expectation_;
}
@@ -803,7 +862,7 @@
// Creates the implicit sequence if there isn't one.
InSequence::InSequence() {
- if (internal::g_gmock_implicit_sequence.get() == NULL) {
+ if (internal::g_gmock_implicit_sequence.get() == nullptr) {
internal::g_gmock_implicit_sequence.set(new Sequence);
sequence_created_ = true;
} else {
@@ -816,8 +875,14 @@
InSequence::~InSequence() {
if (sequence_created_) {
delete internal::g_gmock_implicit_sequence.get();
- internal::g_gmock_implicit_sequence.set(NULL);
+ internal::g_gmock_implicit_sequence.set(nullptr);
}
}
} // namespace testing
+
+#ifdef _MSC_VER
+#if _MSC_VER == 1900
+# pragma warning(pop)
+#endif
+#endif
diff --git a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock.cc b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock.cc
index eac3d84..32b2a73 100644
--- a/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock.cc
+++ b/src/llvm-project/llvm/utils/unittest/googlemock/src/gmock.cc
@@ -26,20 +26,16 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
#include "gmock/gmock.h"
#include "gmock/internal/gmock-port.h"
namespace testing {
-// TODO([email protected]): support using environment variables to
-// control the flag values, like what Google Test does.
-
GMOCK_DEFINE_bool_(catch_leaked_mocks, true,
- "true iff Google Mock should report leaked mock objects "
- "as failures.");
+ "true if and only if Google Mock should report leaked "
+ "mock objects as failures.");
GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity,
"Controls how verbose Google Mock's output is."
@@ -48,6 +44,13 @@
" warning - prints warnings and errors.\n"
" error - prints errors only.");
+GMOCK_DEFINE_int32_(default_mock_behavior, 1,
+ "Controls the default behavior of mocks."
+ " Valid values:\n"
+ " 0 - by default, mocks act as NiceMocks.\n"
+ " 1 - by default, mocks act as NaggyMocks.\n"
+ " 2 - by default, mocks act as StrictMocks.");
+
namespace internal {
// Parses a string as a command line flag. The string should have the
@@ -59,12 +62,12 @@
const char* flag,
bool def_optional) {
// str and flag must not be NULL.
- if (str == NULL || flag == NULL) return NULL;
+ if (str == nullptr || flag == nullptr) return nullptr;
// The flag must start with "--gmock_".
const std::string flag_str = std::string("--gmock_") + flag;
const size_t flag_len = flag_str.length();
- if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+ if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
// Skips the flag name.
const char* flag_end = str + flag_len;
@@ -77,7 +80,7 @@
// If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after
// the flag name.
- if (flag_end[0] != '=') return NULL;
+ if (flag_end[0] != '=') return nullptr;
// Returns the string after "=".
return flag_end + 1;
@@ -94,7 +97,7 @@
const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Converts the string value to a bool.
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
@@ -113,13 +116,26 @@
const char* const value_str = ParseGoogleMockFlagValue(str, flag, false);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
*value = value_str;
return true;
}
+static bool ParseGoogleMockIntFlag(const char* str, const char* flag,
+ int* value) {
+ // Gets the value of the flag as a string.
+ const char* const value_str = ParseGoogleMockFlagValue(str, flag, true);
+
+ // Aborts if the parsing failed.
+ if (value_str == nullptr) return false;
+
+ // Sets *value to the value of the flag.
+ return ParseInt32(Message() << "The value of flag --" << flag,
+ value_str, value);
+}
+
// The internal implementation of InitGoogleMock().
//
// The type parameter CharType can be instantiated to either char or
@@ -138,7 +154,9 @@
// Do we see a Google Mock flag?
if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks",
&GMOCK_FLAG(catch_leaked_mocks)) ||
- ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) {
+ ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose)) ||
+ ParseGoogleMockIntFlag(arg, "default_mock_behavior",
+ &GMOCK_FLAG(default_mock_behavior))) {
// Yes. Shift the remainder of the argv list left by one. Note
// that argv has (*argc + 1) elements, the last one always being
// NULL. The following loop moves the trailing NULL element as
@@ -180,4 +198,16 @@
internal::InitGoogleMockImpl(argc, argv);
}
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleMock() {
+ // Since Arduino doesn't have a command line, fake out the argc/argv arguments
+ int argc = 1;
+ const auto arg0 = "dummy";
+ char* argv0 = const_cast<char*>(arg0);
+ char** argv = &argv0;
+
+ internal::InitGoogleMockImpl(&argc, argv);
+}
+
} // namespace testing
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/README.LLVM b/src/llvm-project/llvm/utils/unittest/googletest/README.LLVM
index 99d0bc5..fea59e5 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/README.LLVM
+++ b/src/llvm-project/llvm/utils/unittest/googletest/README.LLVM
@@ -1,7 +1,7 @@
LLVM notes
----------
-This directory contains Google Test 1.8.0, with all elements removed except for
+This directory contains Google Test 1.10.0, with all elements removed except for
the actual source code, to minimize the addition to the LLVM distribution.
Cleaned up as follows:
@@ -18,3 +18,4 @@
Modified as follows:
* Added support for NetBSD, Minix and Haiku.
* Added raw_os_ostream support to include/gtest/internal/custom/gtest-printers.h.
+* Added StringRef support to include/gtest/internal/custom/gtest-printers.h.
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h
index 957a69c..dc878ff 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-death-test.h
@@ -26,14 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this
// directly.
+// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
@@ -99,10 +99,11 @@
//
// On the regular expressions used in death tests:
//
+// GOOGLETEST_CM0005 DO NOT DELETE
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax.
//
-// On other platforms (e.g. Windows), we only support a simple regex
+// On other platforms (e.g. Windows or Mac), we only support a simple regex
// syntax implemented as part of Google Test. This limited
// implementation should be enough most of the time when writing
// death tests; though it lacks many features you can find in PCRE
@@ -160,7 +161,6 @@
// is rarely a problem as people usually don't put the test binary
// directory in PATH.
//
-// TODO([email protected]): make thread-safe death tests search the PATH.
// Asserts that a given statement causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output
@@ -169,7 +169,7 @@
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
// Like ASSERT_EXIT, but continues on to successive tests in the
-// test case, if any:
+// test suite, if any:
# define EXPECT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
@@ -180,7 +180,7 @@
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// Like ASSERT_DEATH, but continues on to successive tests in the
-// test case, if any:
+// test suite, if any:
# define EXPECT_DEATH(statement, regex) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
@@ -198,9 +198,10 @@
const int exit_code_;
};
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Tests that an exit code describes an exit due to termination by a
// given signal.
+// GOOGLETEST_CM0006 DO NOT DELETE
class GTEST_API_ KilledBySignal {
public:
explicit KilledBySignal(int signum);
@@ -226,7 +227,7 @@
// return 12;
// }
//
-// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) {
+// TEST(TestSuite, TestDieOr12WorksInDgbAndOpt) {
// int sideeffect = 0;
// // Only asserts in dbg.
// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death");
@@ -272,6 +273,54 @@
# endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST
+// This macro is used for implementing macros such as
+// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
+// death tests are not supported. Those macros must compile on such systems
+// if and only if EXPECT_DEATH and ASSERT_DEATH compile with the same parameters
+// on systems that support death tests. This allows one to write such a macro on
+// a system that does not support death tests and be sure that it will compile
+// on a death-test supporting system. It is exposed publicly so that systems
+// that have death-tests with stricter requirements than GTEST_HAS_DEATH_TEST
+// can write their own equivalent of EXPECT_DEATH_IF_SUPPORTED and
+// ASSERT_DEATH_IF_SUPPORTED.
+//
+// Parameters:
+// statement - A statement that a macro such as EXPECT_DEATH would test
+// for program termination. This macro has to make sure this
+// statement is compiled but not executed, to ensure that
+// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
+// parameter if and only if EXPECT_DEATH compiles with it.
+// regex - A regex that a macro such as EXPECT_DEATH would use to test
+// the output of statement. This parameter has to be
+// compiled but not evaluated by this macro, to ensure that
+// this macro only accepts expressions that a macro such as
+// EXPECT_DEATH would accept.
+// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
+// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
+// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
+// compile inside functions where ASSERT_DEATH doesn't
+// compile.
+//
+// The branch that has an always false condition is used to ensure that
+// statement and regex are compiled (and thus syntactically correct) but
+// never executed. The unreachable code macro protects the terminator
+// statement from generating an 'unreachable code' warning in case
+// statement unconditionally returns or throws. The Message constructor at
+// the end allows the syntax of streaming additional messages into the
+// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
+# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::AlwaysTrue()) { \
+ GTEST_LOG_(WARNING) \
+ << "Death tests are not supported on this platform.\n" \
+ << "Statement '" #statement "' cannot be verified."; \
+ } else if (::testing::internal::AlwaysFalse()) { \
+ ::testing::internal::RE::PartialMatch(".*", (regex)); \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ terminator; \
+ } else \
+ ::testing::Message()
+
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
// death tests are supported; otherwise they just issue a warning. This is
@@ -284,9 +333,9 @@
ASSERT_DEATH(statement, regex)
#else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
- GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, )
+ GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
- GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return)
+ GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
#endif
} // namespace testing
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-matchers.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-matchers.h
new file mode 100644
index 0000000..9de6c2e
--- /dev/null
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-matchers.h
@@ -0,0 +1,750 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The Google C++ Testing and Mocking Framework (Google Test)
+//
+// This file implements just enough of the matcher interface to allow
+// EXPECT_DEATH and friends to accept a matcher argument.
+
+// IWYU pragma: private, include "testing/base/public/gunit.h"
+// IWYU pragma: friend third_party/googletest/googlemock/.*
+// IWYU pragma: friend third_party/googletest/googletest/.*
+
+#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
+#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
+
+#include <memory>
+#include <ostream>
+#include <string>
+#include <type_traits>
+
+#include "gtest/gtest-printers.h"
+#include "gtest/internal/gtest-internal.h"
+#include "gtest/internal/gtest-port.h"
+
+// MSVC warning C5046 is new as of VS2017 version 15.8.
+#if defined(_MSC_VER) && _MSC_VER >= 1915
+#define GTEST_MAYBE_5046_ 5046
+#else
+#define GTEST_MAYBE_5046_
+#endif
+
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(
+ 4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by
+ clients of class B */
+ /* Symbol involving type with internal linkage not defined */)
+
+namespace testing {
+
+// To implement a matcher Foo for type T, define:
+// 1. a class FooMatcherImpl that implements the
+// MatcherInterface<T> interface, and
+// 2. a factory function that creates a Matcher<T> object from a
+// FooMatcherImpl*.
+//
+// The two-level delegation design makes it possible to allow a user
+// to write "v" instead of "Eq(v)" where a Matcher is expected, which
+// is impossible if we pass matchers by pointers. It also eases
+// ownership management as Matcher objects can now be copied like
+// plain values.
+
+// MatchResultListener is an abstract class. Its << operator can be
+// used by a matcher to explain why a value matches or doesn't match.
+//
+class MatchResultListener {
+ public:
+ // Creates a listener object with the given underlying ostream. The
+ // listener does not own the ostream, and does not dereference it
+ // in the constructor or destructor.
+ explicit MatchResultListener(::std::ostream* os) : stream_(os) {}
+ virtual ~MatchResultListener() = 0; // Makes this class abstract.
+
+ // Streams x to the underlying ostream; does nothing if the ostream
+ // is NULL.
+ template <typename T>
+ MatchResultListener& operator<<(const T& x) {
+ if (stream_ != nullptr) *stream_ << x;
+ return *this;
+ }
+
+ // Returns the underlying ostream.
+ ::std::ostream* stream() { return stream_; }
+
+ // Returns true if and only if the listener is interested in an explanation
+ // of the match result. A matcher's MatchAndExplain() method can use
+ // this information to avoid generating the explanation when no one
+ // intends to hear it.
+ bool IsInterested() const { return stream_ != nullptr; }
+
+ private:
+ ::std::ostream* const stream_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
+};
+
+inline MatchResultListener::~MatchResultListener() {
+}
+
+// An instance of a subclass of this knows how to describe itself as a
+// matcher.
+class MatcherDescriberInterface {
+ public:
+ virtual ~MatcherDescriberInterface() {}
+
+ // Describes this matcher to an ostream. The function should print
+ // a verb phrase that describes the property a value matching this
+ // matcher should have. The subject of the verb phrase is the value
+ // being matched. For example, the DescribeTo() method of the Gt(7)
+ // matcher prints "is greater than 7".
+ virtual void DescribeTo(::std::ostream* os) const = 0;
+
+ // Describes the negation of this matcher to an ostream. For
+ // example, if the description of this matcher is "is greater than
+ // 7", the negated description could be "is not greater than 7".
+ // You are not required to override this when implementing
+ // MatcherInterface, but it is highly advised so that your matcher
+ // can produce good error messages.
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ *os << "not (";
+ DescribeTo(os);
+ *os << ")";
+ }
+};
+
+// The implementation of a matcher.
+template <typename T>
+class MatcherInterface : public MatcherDescriberInterface {
+ public:
+ // Returns true if and only if the matcher matches x; also explains the
+ // match result to 'listener' if necessary (see the next paragraph), in
+ // the form of a non-restrictive relative clause ("which ...",
+ // "whose ...", etc) that describes x. For example, the
+ // MatchAndExplain() method of the Pointee(...) matcher should
+ // generate an explanation like "which points to ...".
+ //
+ // Implementations of MatchAndExplain() should add an explanation of
+ // the match result *if and only if* they can provide additional
+ // information that's not already present (or not obvious) in the
+ // print-out of x and the matcher's description. Whether the match
+ // succeeds is not a factor in deciding whether an explanation is
+ // needed, as sometimes the caller needs to print a failure message
+ // when the match succeeds (e.g. when the matcher is used inside
+ // Not()).
+ //
+ // For example, a "has at least 10 elements" matcher should explain
+ // what the actual element count is, regardless of the match result,
+ // as it is useful information to the reader; on the other hand, an
+ // "is empty" matcher probably only needs to explain what the actual
+ // size is when the match fails, as it's redundant to say that the
+ // size is 0 when the value is already known to be empty.
+ //
+ // You should override this method when defining a new matcher.
+ //
+ // It's the responsibility of the caller (Google Test) to guarantee
+ // that 'listener' is not NULL. This helps to simplify a matcher's
+ // implementation when it doesn't care about the performance, as it
+ // can talk to 'listener' without checking its validity first.
+ // However, in order to implement dummy listeners efficiently,
+ // listener->stream() may be NULL.
+ virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0;
+
+ // Inherits these methods from MatcherDescriberInterface:
+ // virtual void DescribeTo(::std::ostream* os) const = 0;
+ // virtual void DescribeNegationTo(::std::ostream* os) const;
+};
+
+namespace internal {
+
+// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
+template <typename T>
+class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
+ public:
+ explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
+ : impl_(impl) {}
+ ~MatcherInterfaceAdapter() override { delete impl_; }
+
+ void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); }
+
+ void DescribeNegationTo(::std::ostream* os) const override {
+ impl_->DescribeNegationTo(os);
+ }
+
+ bool MatchAndExplain(const T& x,
+ MatchResultListener* listener) const override {
+ return impl_->MatchAndExplain(x, listener);
+ }
+
+ private:
+ const MatcherInterface<T>* const impl_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
+};
+
+struct AnyEq {
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const { return a == b; }
+};
+struct AnyNe {
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const { return a != b; }
+};
+struct AnyLt {
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const { return a < b; }
+};
+struct AnyGt {
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const { return a > b; }
+};
+struct AnyLe {
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const { return a <= b; }
+};
+struct AnyGe {
+ template <typename A, typename B>
+ bool operator()(const A& a, const B& b) const { return a >= b; }
+};
+
+// A match result listener that ignores the explanation.
+class DummyMatchResultListener : public MatchResultListener {
+ public:
+ DummyMatchResultListener() : MatchResultListener(nullptr) {}
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
+};
+
+// A match result listener that forwards the explanation to a given
+// ostream. The difference between this and MatchResultListener is
+// that the former is concrete.
+class StreamMatchResultListener : public MatchResultListener {
+ public:
+ explicit StreamMatchResultListener(::std::ostream* os)
+ : MatchResultListener(os) {}
+
+ private:
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
+};
+
+// An internal class for implementing Matcher<T>, which will derive
+// from it. We put functionalities common to all Matcher<T>
+// specializations here to avoid code duplication.
+template <typename T>
+class MatcherBase {
+ public:
+ // Returns true if and only if the matcher matches x; also explains the
+ // match result to 'listener'.
+ bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
+ return impl_->MatchAndExplain(x, listener);
+ }
+
+ // Returns true if and only if this matcher matches x.
+ bool Matches(const T& x) const {
+ DummyMatchResultListener dummy;
+ return MatchAndExplain(x, &dummy);
+ }
+
+ // Describes this matcher to an ostream.
+ void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
+
+ // Describes the negation of this matcher to an ostream.
+ void DescribeNegationTo(::std::ostream* os) const {
+ impl_->DescribeNegationTo(os);
+ }
+
+ // Explains why x matches, or doesn't match, the matcher.
+ void ExplainMatchResultTo(const T& x, ::std::ostream* os) const {
+ StreamMatchResultListener listener(os);
+ MatchAndExplain(x, &listener);
+ }
+
+ // Returns the describer for this matcher object; retains ownership
+ // of the describer, which is only guaranteed to be alive when
+ // this matcher object is alive.
+ const MatcherDescriberInterface* GetDescriber() const {
+ return impl_.get();
+ }
+
+ protected:
+ MatcherBase() {}
+
+ // Constructs a matcher from its implementation.
+ explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {}
+
+ template <typename U>
+ explicit MatcherBase(
+ const MatcherInterface<U>* impl,
+ typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
+ nullptr)
+ : impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
+
+ MatcherBase(const MatcherBase&) = default;
+ MatcherBase& operator=(const MatcherBase&) = default;
+ MatcherBase(MatcherBase&&) = default;
+ MatcherBase& operator=(MatcherBase&&) = default;
+
+ virtual ~MatcherBase() {}
+
+ private:
+ std::shared_ptr<const MatcherInterface<const T&>> impl_;
+};
+
+} // namespace internal
+
+// A Matcher<T> is a copyable and IMMUTABLE (except by assignment)
+// object that can check whether a value of type T matches. The
+// implementation of Matcher<T> is just a std::shared_ptr to const
+// MatcherInterface<T>. Don't inherit from Matcher!
+template <typename T>
+class Matcher : public internal::MatcherBase<T> {
+ public:
+ // Constructs a null matcher. Needed for storing Matcher objects in STL
+ // containers. A default-constructed matcher is not yet initialized. You
+ // cannot use it until a valid value has been assigned to it.
+ explicit Matcher() {} // NOLINT
+
+ // Constructs a matcher from its implementation.
+ explicit Matcher(const MatcherInterface<const T&>* impl)
+ : internal::MatcherBase<T>(impl) {}
+
+ template <typename U>
+ explicit Matcher(
+ const MatcherInterface<U>* impl,
+ typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
+ nullptr)
+ : internal::MatcherBase<T>(impl) {}
+
+ // Implicit constructor here allows people to write
+ // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
+ Matcher(T value); // NOLINT
+};
+
+// The following two specializations allow the user to write str
+// instead of Eq(str) and "foo" instead of Eq("foo") when a std::string
+// matcher is expected.
+template <>
+class GTEST_API_ Matcher<const std::string&>
+ : public internal::MatcherBase<const std::string&> {
+ public:
+ Matcher() {}
+
+ explicit Matcher(const MatcherInterface<const std::string&>* impl)
+ : internal::MatcherBase<const std::string&>(impl) {}
+
+ // Allows the user to write str instead of Eq(str) sometimes, where
+ // str is a std::string object.
+ Matcher(const std::string& s); // NOLINT
+
+ // Allows the user to write "foo" instead of Eq("foo") sometimes.
+ Matcher(const char* s); // NOLINT
+};
+
+template <>
+class GTEST_API_ Matcher<std::string>
+ : public internal::MatcherBase<std::string> {
+ public:
+ Matcher() {}
+
+ explicit Matcher(const MatcherInterface<const std::string&>* impl)
+ : internal::MatcherBase<std::string>(impl) {}
+ explicit Matcher(const MatcherInterface<std::string>* impl)
+ : internal::MatcherBase<std::string>(impl) {}
+
+ // Allows the user to write str instead of Eq(str) sometimes, where
+ // str is a string object.
+ Matcher(const std::string& s); // NOLINT
+
+ // Allows the user to write "foo" instead of Eq("foo") sometimes.
+ Matcher(const char* s); // NOLINT
+};
+
+#if GTEST_HAS_ABSL
+// The following two specializations allow the user to write str
+// instead of Eq(str) and "foo" instead of Eq("foo") when a absl::string_view
+// matcher is expected.
+template <>
+class GTEST_API_ Matcher<const absl::string_view&>
+ : public internal::MatcherBase<const absl::string_view&> {
+ public:
+ Matcher() {}
+
+ explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
+ : internal::MatcherBase<const absl::string_view&>(impl) {}
+
+ // Allows the user to write str instead of Eq(str) sometimes, where
+ // str is a std::string object.
+ Matcher(const std::string& s); // NOLINT
+
+ // Allows the user to write "foo" instead of Eq("foo") sometimes.
+ Matcher(const char* s); // NOLINT
+
+ // Allows the user to pass absl::string_views directly.
+ Matcher(absl::string_view s); // NOLINT
+};
+
+template <>
+class GTEST_API_ Matcher<absl::string_view>
+ : public internal::MatcherBase<absl::string_view> {
+ public:
+ Matcher() {}
+
+ explicit Matcher(const MatcherInterface<const absl::string_view&>* impl)
+ : internal::MatcherBase<absl::string_view>(impl) {}
+ explicit Matcher(const MatcherInterface<absl::string_view>* impl)
+ : internal::MatcherBase<absl::string_view>(impl) {}
+
+ // Allows the user to write str instead of Eq(str) sometimes, where
+ // str is a std::string object.
+ Matcher(const std::string& s); // NOLINT
+
+ // Allows the user to write "foo" instead of Eq("foo") sometimes.
+ Matcher(const char* s); // NOLINT
+
+ // Allows the user to pass absl::string_views directly.
+ Matcher(absl::string_view s); // NOLINT
+};
+#endif // GTEST_HAS_ABSL
+
+// Prints a matcher in a human-readable format.
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
+ matcher.DescribeTo(&os);
+ return os;
+}
+
+// The PolymorphicMatcher class template makes it easy to implement a
+// polymorphic matcher (i.e. a matcher that can match values of more
+// than one type, e.g. Eq(n) and NotNull()).
+//
+// To define a polymorphic matcher, a user should provide an Impl
+// class that has a DescribeTo() method and a DescribeNegationTo()
+// method, and define a member function (or member function template)
+//
+// bool MatchAndExplain(const Value& value,
+// MatchResultListener* listener) const;
+//
+// See the definition of NotNull() for a complete example.
+template <class Impl>
+class PolymorphicMatcher {
+ public:
+ explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {}
+
+ // Returns a mutable reference to the underlying matcher
+ // implementation object.
+ Impl& mutable_impl() { return impl_; }
+
+ // Returns an immutable reference to the underlying matcher
+ // implementation object.
+ const Impl& impl() const { return impl_; }
+
+ template <typename T>
+ operator Matcher<T>() const {
+ return Matcher<T>(new MonomorphicImpl<const T&>(impl_));
+ }
+
+ private:
+ template <typename T>
+ class MonomorphicImpl : public MatcherInterface<T> {
+ public:
+ explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {}
+
+ virtual void DescribeTo(::std::ostream* os) const { impl_.DescribeTo(os); }
+
+ virtual void DescribeNegationTo(::std::ostream* os) const {
+ impl_.DescribeNegationTo(os);
+ }
+
+ virtual bool MatchAndExplain(T x, MatchResultListener* listener) const {
+ return impl_.MatchAndExplain(x, listener);
+ }
+
+ private:
+ const Impl impl_;
+ };
+
+ Impl impl_;
+};
+
+// Creates a matcher from its implementation.
+// DEPRECATED: Especially in the generic code, prefer:
+// Matcher<T>(new MyMatcherImpl<const T&>(...));
+//
+// MakeMatcher may create a Matcher that accepts its argument by value, which
+// leads to unnecessary copies & lack of support for non-copyable types.
+template <typename T>
+inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
+ return Matcher<T>(impl);
+}
+
+// Creates a polymorphic matcher from its implementation. This is
+// easier to use than the PolymorphicMatcher<Impl> constructor as it
+// doesn't require you to explicitly write the template argument, e.g.
+//
+// MakePolymorphicMatcher(foo);
+// vs
+// PolymorphicMatcher<TypeOfFoo>(foo);
+template <class Impl>
+inline PolymorphicMatcher<Impl> MakePolymorphicMatcher(const Impl& impl) {
+ return PolymorphicMatcher<Impl>(impl);
+}
+
+namespace internal {
+// Implements a matcher that compares a given value with a
+// pre-supplied value using one of the ==, <=, <, etc, operators. The
+// two values being compared don't have to have the same type.
+//
+// The matcher defined here is polymorphic (for example, Eq(5) can be
+// used to match an int, a short, a double, etc). Therefore we use
+// a template type conversion operator in the implementation.
+//
+// The following template definition assumes that the Rhs parameter is
+// a "bare" type (i.e. neither 'const T' nor 'T&').
+template <typename D, typename Rhs, typename Op>
+class ComparisonBase {
+ public:
+ explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
+ template <typename Lhs>
+ operator Matcher<Lhs>() const {
+ return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
+ }
+
+ private:
+ template <typename T>
+ static const T& Unwrap(const T& v) { return v; }
+ template <typename T>
+ static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
+
+ template <typename Lhs, typename = Rhs>
+ class Impl : public MatcherInterface<Lhs> {
+ public:
+ explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
+ bool MatchAndExplain(Lhs lhs,
+ MatchResultListener* /* listener */) const override {
+ return Op()(lhs, Unwrap(rhs_));
+ }
+ void DescribeTo(::std::ostream* os) const override {
+ *os << D::Desc() << " ";
+ UniversalPrint(Unwrap(rhs_), os);
+ }
+ void DescribeNegationTo(::std::ostream* os) const override {
+ *os << D::NegatedDesc() << " ";
+ UniversalPrint(Unwrap(rhs_), os);
+ }
+
+ private:
+ Rhs rhs_;
+ };
+ Rhs rhs_;
+};
+
+template <typename Rhs>
+class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
+ public:
+ explicit EqMatcher(const Rhs& rhs)
+ : ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
+ static const char* Desc() { return "is equal to"; }
+ static const char* NegatedDesc() { return "isn't equal to"; }
+};
+template <typename Rhs>
+class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
+ public:
+ explicit NeMatcher(const Rhs& rhs)
+ : ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
+ static const char* Desc() { return "isn't equal to"; }
+ static const char* NegatedDesc() { return "is equal to"; }
+};
+template <typename Rhs>
+class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
+ public:
+ explicit LtMatcher(const Rhs& rhs)
+ : ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
+ static const char* Desc() { return "is <"; }
+ static const char* NegatedDesc() { return "isn't <"; }
+};
+template <typename Rhs>
+class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
+ public:
+ explicit GtMatcher(const Rhs& rhs)
+ : ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
+ static const char* Desc() { return "is >"; }
+ static const char* NegatedDesc() { return "isn't >"; }
+};
+template <typename Rhs>
+class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
+ public:
+ explicit LeMatcher(const Rhs& rhs)
+ : ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
+ static const char* Desc() { return "is <="; }
+ static const char* NegatedDesc() { return "isn't <="; }
+};
+template <typename Rhs>
+class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
+ public:
+ explicit GeMatcher(const Rhs& rhs)
+ : ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
+ static const char* Desc() { return "is >="; }
+ static const char* NegatedDesc() { return "isn't >="; }
+};
+
+// Implements polymorphic matchers MatchesRegex(regex) and
+// ContainsRegex(regex), which can be used as a Matcher<T> as long as
+// T can be converted to a string.
+class MatchesRegexMatcher {
+ public:
+ MatchesRegexMatcher(const RE* regex, bool full_match)
+ : regex_(regex), full_match_(full_match) {}
+
+#if GTEST_HAS_ABSL
+ bool MatchAndExplain(const absl::string_view& s,
+ MatchResultListener* listener) const {
+ return MatchAndExplain(std::string(s), listener);
+ }
+#endif // GTEST_HAS_ABSL
+
+ // Accepts pointer types, particularly:
+ // const char*
+ // char*
+ // const wchar_t*
+ // wchar_t*
+ template <typename CharType>
+ bool MatchAndExplain(CharType* s, MatchResultListener* listener) const {
+ return s != nullptr && MatchAndExplain(std::string(s), listener);
+ }
+
+ // Matches anything that can convert to std::string.
+ //
+ // This is a template, not just a plain function with const std::string&,
+ // because absl::string_view has some interfering non-explicit constructors.
+ template <class MatcheeStringType>
+ bool MatchAndExplain(const MatcheeStringType& s,
+ MatchResultListener* /* listener */) const {
+ const std::string& s2(s);
+ return full_match_ ? RE::FullMatch(s2, *regex_)
+ : RE::PartialMatch(s2, *regex_);
+ }
+
+ void DescribeTo(::std::ostream* os) const {
+ *os << (full_match_ ? "matches" : "contains") << " regular expression ";
+ UniversalPrinter<std::string>::Print(regex_->pattern(), os);
+ }
+
+ void DescribeNegationTo(::std::ostream* os) const {
+ *os << "doesn't " << (full_match_ ? "match" : "contain")
+ << " regular expression ";
+ UniversalPrinter<std::string>::Print(regex_->pattern(), os);
+ }
+
+ private:
+ const std::shared_ptr<const RE> regex_;
+ const bool full_match_;
+};
+} // namespace internal
+
+// Matches a string that fully matches regular expression 'regex'.
+// The matcher takes ownership of 'regex'.
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
+ const internal::RE* regex) {
+ return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
+}
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
+ const std::string& regex) {
+ return MatchesRegex(new internal::RE(regex));
+}
+
+// Matches a string that contains regular expression 'regex'.
+// The matcher takes ownership of 'regex'.
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
+ const internal::RE* regex) {
+ return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
+}
+inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
+ const std::string& regex) {
+ return ContainsRegex(new internal::RE(regex));
+}
+
+// Creates a polymorphic matcher that matches anything equal to x.
+// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
+// wouldn't compile.
+template <typename T>
+inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
+
+// Constructs a Matcher<T> from a 'value' of type T. The constructed
+// matcher matches any value that's equal to 'value'.
+template <typename T>
+Matcher<T>::Matcher(T value) { *this = Eq(value); }
+
+// Creates a monomorphic matcher that matches anything with type Lhs
+// and equal to rhs. A user may need to use this instead of Eq(...)
+// in order to resolve an overloading ambiguity.
+//
+// TypedEq<T>(x) is just a convenient short-hand for Matcher<T>(Eq(x))
+// or Matcher<T>(x), but more readable than the latter.
+//
+// We could define similar monomorphic matchers for other comparison
+// operations (e.g. TypedLt, TypedGe, and etc), but decided not to do
+// it yet as those are used much less than Eq() in practice. A user
+// can always write Matcher<T>(Lt(5)) to be explicit about the type,
+// for example.
+template <typename Lhs, typename Rhs>
+inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
+
+// Creates a polymorphic matcher that matches anything >= x.
+template <typename Rhs>
+inline internal::GeMatcher<Rhs> Ge(Rhs x) {
+ return internal::GeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything > x.
+template <typename Rhs>
+inline internal::GtMatcher<Rhs> Gt(Rhs x) {
+ return internal::GtMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything <= x.
+template <typename Rhs>
+inline internal::LeMatcher<Rhs> Le(Rhs x) {
+ return internal::LeMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything < x.
+template <typename Rhs>
+inline internal::LtMatcher<Rhs> Lt(Rhs x) {
+ return internal::LtMatcher<Rhs>(x);
+}
+
+// Creates a polymorphic matcher that matches anything != x.
+template <typename Rhs>
+inline internal::NeMatcher<Rhs> Ne(Rhs x) {
+ return internal::NeMatcher<Rhs>(x);
+}
+} // namespace testing
+
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
+
+#endif // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-message.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-message.h
index 30cb5ed..cbabe5d 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-message.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-message.h
@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the Message class.
//
@@ -43,14 +42,20 @@
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program!
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits>
+#include <memory>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/custom/raw-ostream.h"
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
// Ensures that there is at least one operator<< in the global namespace.
// See Message& operator<<(...) below for why.
void operator<<(const testing::internal::Secret&, int);
@@ -103,14 +108,6 @@
*ss_ << str;
}
-#if GTEST_OS_SYMBIAN
- // Streams a value (either a pointer or not) to this object.
- template <typename T>
- inline Message& operator <<(const T& value) {
- StreamHelper(typename internal::is_pointer<T>::type(), value);
- return *this;
- }
-#else
// Streams a non-pointer value to this object.
template <typename T>
inline Message& operator <<(const T& val) {
@@ -148,14 +145,13 @@
// as "(null)".
template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT
- if (pointer == NULL) {
+ if (pointer == nullptr) {
*ss_ << "(null)";
} else {
*ss_ << llvm_gtest::printable(pointer);
}
return *this;
}
-#endif // GTEST_OS_SYMBIAN
// Since the basic IO manipulators are overloaded for both narrow
// and wide streams, we have to provide this specialized definition
@@ -184,12 +180,6 @@
Message& operator <<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING
-#if GTEST_HAS_GLOBAL_WSTRING
- // Converts the given wide string to a narrow string using the UTF-8
- // encoding, and streams the result to this Message object.
- Message& operator <<(const ::wstring& wstr);
-#endif // GTEST_HAS_GLOBAL_WSTRING
-
// Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0".
//
@@ -197,32 +187,8 @@
std::string GetString() const;
private:
-
-#if GTEST_OS_SYMBIAN
- // These are needed as the Nokia Symbian Compiler cannot decide between
- // const T& and const T* in a function template. The Nokia compiler _can_
- // decide between class template specializations for T and T*, so a
- // tr1::type_traits-like is_pointer works, and we can overload on that.
- template <typename T>
- inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) {
- if (pointer == NULL) {
- *ss_ << "(null)";
- } else {
- *ss_ << pointer;
- }
- }
- template <typename T>
- inline void StreamHelper(internal::false_type /*is_pointer*/,
- const T& value) {
- // See the comments in Message& operator <<(const T&) above for why
- // we need this using statement.
- using ::operator <<;
- *ss_ << value;
- }
-#endif // GTEST_OS_SYMBIAN
-
// We'll hold the text streamed to this object here.
- const internal::scoped_ptr< ::std::stringstream> ss_;
+ const std::unique_ptr< ::std::stringstream> ss_;
// We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator.
@@ -248,4 +214,6 @@
} // namespace internal
} // namespace testing
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h
index 038f9ba..c2e6eae 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-param-test.h
@@ -1,7 +1,3 @@
-// This file was GENERATED by command:
-// pump.py gtest-param-test.h.pump
-// DO NOT EDIT BY HAND!!!
-
// Copyright 2008, Google Inc.
// All rights reserved.
//
@@ -31,13 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Authors: [email protected] (Vlad Losev)
-//
// Macros and functions for implementing parameterized tests
-// in Google C++ Testing Framework (Google Test)
+// in Google C++ Testing and Mocking Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
+// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
@@ -76,10 +71,10 @@
...
}
-// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test
+// Finally, you can use INSTANTIATE_TEST_SUITE_P to instantiate the test
// case with any set of parameters you want. Google Test defines a number
// of functions for generating test parameters. They return what we call
-// (surprise!) parameter generators. Here is a summary of them, which
+// (surprise!) parameter generators. Here is a summary of them, which
// are all in the testing namespace:
//
//
@@ -97,17 +92,17 @@
// For more details, see comments at the definitions of these functions below
// in this file.
//
-// The following statement will instantiate tests from the FooTest test case
+// The following statement will instantiate tests from the FooTest test suite
// each with parameter values "meeny", "miny", and "moe".
-INSTANTIATE_TEST_CASE_P(InstantiationName,
- FooTest,
- Values("meeny", "miny", "moe"));
+INSTANTIATE_TEST_SUITE_P(InstantiationName,
+ FooTest,
+ Values("meeny", "miny", "moe"));
// To distinguish different instances of the pattern, (yes, you
-// can instantiate it more then once) the first argument to the
-// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the
-// actual test case name. Remember to pick unique prefixes for different
+// can instantiate it more than once) the first argument to the
+// INSTANTIATE_TEST_SUITE_P macro is a prefix that will be added to the
+// actual test suite name. Remember to pick unique prefixes for different
// instantiations. The tests from the instantiation above will have
// these names:
//
@@ -124,7 +119,7 @@
// with parameter values "cat" and "dog":
const char* pets[] = {"cat", "dog"};
-INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
+INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, ValuesIn(pets));
// The tests from the instantiation above will have these names:
//
@@ -133,9 +128,9 @@
// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat"
// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog"
//
-// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests
-// in the given test case, whether their definitions come before or
-// AFTER the INSTANTIATE_TEST_CASE_P statement.
+// Please note that INSTANTIATE_TEST_SUITE_P will instantiate all tests
+// in the given test suite, whether their definitions come before or
+// AFTER the INSTANTIATE_TEST_SUITE_P statement.
//
// Please also note that generator expressions (including parameters to the
// generators) are evaluated in InitGoogleTest(), after main() has started.
@@ -179,31 +174,23 @@
#endif // 0
-#include "gtest/internal/gtest-port.h"
+#include <iterator>
+#include <utility>
-#if !GTEST_OS_SYMBIAN
-# include <utility>
-#endif
-
-// scripts/fuse_gtest.py depends on gtest's own header being #included
-// *unconditionally*. Therefore these #includes cannot be moved
-// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
-#include "gtest/internal/gtest-param-util-generated.h"
-
-#if GTEST_HAS_PARAM_TEST
+#include "gtest/internal/gtest-port.h"
namespace testing {
// Functions producing parameter generators.
//
// Google Test uses these generators to produce parameters for value-
-// parameterized tests. When a parameterized test case is instantiated
+// parameterized tests. When a parameterized test suite is instantiated
// with a particular generator, Google Test creates and runs tests
// for each element in the sequence produced by the generator.
//
-// In the following sample, tests from test case FooTest are instantiated
+// In the following sample, tests from test suite FooTest are instantiated
// each three times with parameter values 3, 5, and 8:
//
// class FooTest : public TestWithParam<int> { ... };
@@ -212,7 +199,7 @@
// }
// TEST_P(FooTest, TestThat) {
// }
-// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8));
+// INSTANTIATE_TEST_SUITE_P(TestSequence, FooTest, Values(3, 5, 8));
//
// Range() returns generators providing sequences of values in a range.
@@ -269,13 +256,13 @@
//
// Examples:
//
-// This instantiates tests from test case StringTest
+// This instantiates tests from test suite StringTest
// each with C-string values of "foo", "bar", and "baz":
//
// const char* strings[] = {"foo", "bar", "baz"};
-// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings));
+// INSTANTIATE_TEST_SUITE_P(StringSequence, StringTest, ValuesIn(strings));
//
-// This instantiates tests from test case StlStringTest
+// This instantiates tests from test suite StlStringTest
// each with STL strings with values "a" and "b":
//
// ::std::vector< ::std::string> GetParameterStrings() {
@@ -285,9 +272,9 @@
// return v;
// }
//
-// INSTANTIATE_TEST_CASE_P(CharSequence,
-// StlStringTest,
-// ValuesIn(GetParameterStrings()));
+// INSTANTIATE_TEST_SUITE_P(CharSequence,
+// StlStringTest,
+// ValuesIn(GetParameterStrings()));
//
//
// This will also instantiate tests from CharTest
@@ -300,16 +287,15 @@
// return list;
// }
// ::std::list<char> l = GetParameterChars();
-// INSTANTIATE_TEST_CASE_P(CharSequence2,
-// CharTest,
-// ValuesIn(l.begin(), l.end()));
+// INSTANTIATE_TEST_SUITE_P(CharSequence2,
+// CharTest,
+// ValuesIn(l.begin(), l.end()));
//
template <typename ForwardIterator>
internal::ParamGenerator<
- typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
+ typename std::iterator_traits<ForwardIterator>::value_type>
ValuesIn(ForwardIterator begin, ForwardIterator end) {
- typedef typename ::testing::internal::IteratorTraits<ForwardIterator>
- ::value_type ParamType;
+ typedef typename std::iterator_traits<ForwardIterator>::value_type ParamType;
return internal::ParamGenerator<ParamType>(
new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end));
}
@@ -332,869 +318,22 @@
// Values(T v1, T v2, ..., T vN)
// - returns a generator producing sequences with elements v1, v2, ..., vN.
//
-// For example, this instantiates tests from test case BarTest each
+// For example, this instantiates tests from test suite BarTest each
// with values "one", "two", and "three":
//
-// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three"));
+// INSTANTIATE_TEST_SUITE_P(NumSequence,
+// BarTest,
+// Values("one", "two", "three"));
//
-// This instantiates tests from test case BazTest each with values 1, 2, 3.5.
+// This instantiates tests from test suite BazTest each with values 1, 2, 3.5.
// The exact type of values will depend on the type of parameter in BazTest.
//
-// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
+// INSTANTIATE_TEST_SUITE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5));
//
-// Currently, Values() supports from 1 to 50 parameters.
//
-template <typename T1>
-internal::ValueArray1<T1> Values(T1 v1) {
- return internal::ValueArray1<T1>(v1);
-}
-
-template <typename T1, typename T2>
-internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) {
- return internal::ValueArray2<T1, T2>(v1, v2);
-}
-
-template <typename T1, typename T2, typename T3>
-internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) {
- return internal::ValueArray3<T1, T2, T3>(v1, v2, v3);
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) {
- return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4,
- T5 v5) {
- return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3,
- T4 v4, T5 v5, T6 v6) {
- return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
-internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3,
- T4 v4, T5 v5, T6 v6, T7 v7) {
- return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5,
- v6, v7);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
-internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2,
- T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) {
- return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4,
- v5, v6, v7, v8);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
-internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2,
- T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) {
- return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3,
- v4, v5, v6, v7, v8, v9);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1,
- T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) {
- return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1,
- v2, v3, v4, v5, v6, v7, v8, v9, v10);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11>
-internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
- T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11) {
- return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
- T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12>
-internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12) {
- return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13>
-internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12,
- T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13) {
- return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14>
-internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) {
- return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
- v14);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15>
-internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
- T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) {
- return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
- v13, v14, v15);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16>
-internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16) {
- return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
- v12, v13, v14, v15, v16);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17>
-internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17) {
- return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
- v11, v12, v13, v14, v15, v16, v17);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18>
-internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
- T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18) {
- return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
- v10, v11, v12, v13, v14, v15, v16, v17, v18);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19>
-internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
- T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
- T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) {
- return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8,
- v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20>
-internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4,
- T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
- T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) {
- return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7,
- v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21>
-internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4,
- T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
- T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) {
- return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6,
- v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22>
-internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3,
- T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
- T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
- T21 v21, T22 v22) {
- return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4,
- v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
- v20, v21, v22);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23>
-internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2,
- T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
- T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
- T21 v21, T22 v22, T23 v23) {
- return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3,
- v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
- v20, v21, v22, v23);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24>
-internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2,
- T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
- T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
- T21 v21, T22 v22, T23 v23, T24 v24) {
- return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2,
- v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
- v19, v20, v21, v22, v23, v24);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25>
-internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1,
- T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
- T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
- T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) {
- return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1,
- v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
- v18, v19, v20, v21, v22, v23, v24, v25);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26>
-internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26) {
- return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
- v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27>
-internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26,
- T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27) {
- return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
- v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28>
-internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27,
- T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28) {
- return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
- v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
- v28);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29>
-internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29) {
- return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
- v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
- v27, v28, v29);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30>
-internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
- T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
- T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
- T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) {
- return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
- v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
- v26, v27, v28, v29, v30);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31>
-internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
- T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) {
- return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
- v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
- v25, v26, v27, v28, v29, v30, v31);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32>
-internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
- T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
- T32 v32) {
- return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
- v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
- v24, v25, v26, v27, v28, v29, v30, v31, v32);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33>
-internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
- T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
- T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
- T32 v32, T33 v33) {
- return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8,
- v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
- v24, v25, v26, v27, v28, v29, v30, v31, v32, v33);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34>
-internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
- T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
- T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
- T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
- T31 v31, T32 v32, T33 v33, T34 v34) {
- return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7,
- v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
- v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35>
-internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4,
- T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
- T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
- T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
- T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) {
- return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6,
- v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
- v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36>
-internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4,
- T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
- T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
- T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
- T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) {
- return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4,
- v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
- v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
- v34, v35, v36);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37>
-internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3,
- T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
- T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
- T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
- T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
- T37 v37) {
- return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3,
- v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
- v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
- v34, v35, v36, v37);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38>
-internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2,
- T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
- T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
- T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
- T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
- T37 v37, T38 v38) {
- return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2,
- v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18,
- v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32,
- v33, v34, v35, v36, v37, v38);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39>
-internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2,
- T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12,
- T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20,
- T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28,
- T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36,
- T37 v37, T38 v38, T39 v39) {
- return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1,
- v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17,
- v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
- v32, v33, v34, v35, v36, v37, v38, v39);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40>
-internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1,
- T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11,
- T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19,
- T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27,
- T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35,
- T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) {
- return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
- v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
- v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41>
-internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40,
- T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) {
- return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14,
- v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28,
- v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42>
-internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41,
- T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42) {
- return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13,
- v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27,
- v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41,
- v42);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43>
-internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42,
- T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43) {
- return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12,
- v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26,
- v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40,
- v41, v42, v43);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44>
-internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44) {
- return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11,
- v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25,
- v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
- v40, v41, v42, v43, v44);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45>
-internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
- T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
- T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
- T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
- T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
- T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) {
- return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10,
- v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24,
- v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38,
- v39, v40, v41, v42, v43, v44, v45);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46>
-internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
- T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
- T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
- T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) {
- return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9,
- v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
- v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
- v38, v39, v40, v41, v42, v43, v44, v45, v46);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47>
-internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
- T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
- T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
- T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) {
- return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8,
- v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23,
- v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37,
- v38, v39, v40, v41, v42, v43, v44, v45, v46, v47);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47, typename T48>
-internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6,
- T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15,
- T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23,
- T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31,
- T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39,
- T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47,
- T48 v48) {
- return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7,
- v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22,
- v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36,
- v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47, typename T48, typename T49>
-internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5,
- T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14,
- T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22,
- T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30,
- T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38,
- T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46,
- T47 v47, T48 v48, T49 v49) {
- return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6,
- v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21,
- v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35,
- v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47, typename T48, typename T49, typename T50>
-internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
- T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28,
- T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43,
- T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4,
- T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13,
- T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21,
- T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29,
- T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37,
- T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45,
- T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) {
- return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
- T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25,
- T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39,
- T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4,
- v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
- v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33,
- v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
- v48, v49, v50);
+template <typename... T>
+internal::ValueArray<T...> Values(T... v) {
+ return internal::ValueArray<T...>(std::move(v)...);
}
// Bool() allows generating tests with parameters in a set of (false, true).
@@ -1207,7 +346,7 @@
// of multiple flags can be tested when several Bool()'s are combined using
// Combine() function.
//
-// In the following example all tests in the test case FlagDependentTest
+// In the following example all tests in the test suite FlagDependentTest
// will be instantiated twice with parameters false and true.
//
// class FlagDependentTest : public testing::TestWithParam<bool> {
@@ -1215,13 +354,12 @@
// external_flag = GetParam();
// }
// }
-// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool());
+// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
-# if GTEST_HAS_COMBINE
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
//
@@ -1230,215 +368,136 @@
// - returns a generator producing sequences with elements coming from
// the Cartesian product of elements from the sequences generated by
// gen1, gen2, ..., genN. The sequence elements will have a type of
-// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
+// std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
-// Combine can have up to 10 arguments. This number is currently limited
-// by the maximum number of elements in the tuple implementation used by Google
-// Test.
+// Combine can have up to 10 arguments.
//
// Example:
//
-// This will instantiate tests in test case AnimalTest each one with
+// This will instantiate tests in test suite AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// class AnimalTest
-// : public testing::TestWithParam<tuple<const char*, Color> > {...};
+// : public testing::TestWithParam<std::tuple<const char*, Color> > {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
-// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest,
-// Combine(Values("cat", "dog"),
-// Values(BLACK, WHITE)));
+// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
+// Combine(Values("cat", "dog"),
+// Values(BLACK, WHITE)));
//
// This will instantiate tests in FlagDependentTest with all variations of two
// Boolean flags:
//
// class FlagDependentTest
-// : public testing::TestWithParam<tuple<bool, bool> > {
+// : public testing::TestWithParam<std::tuple<bool, bool> > {
// virtual void SetUp() {
// // Assigns external_flag_1 and external_flag_2 values from the tuple.
-// tie(external_flag_1, external_flag_2) = GetParam();
+// std::tie(external_flag_1, external_flag_2) = GetParam();
// }
// };
//
// TEST_P(FlagDependentTest, TestFeature1) {
// // Test your code using external_flag_1 and external_flag_2 here.
// }
-// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest,
-// Combine(Bool(), Bool()));
+// INSTANTIATE_TEST_SUITE_P(TwoBoolSequence, FlagDependentTest,
+// Combine(Bool(), Bool()));
//
-template <typename Generator1, typename Generator2>
-internal::CartesianProductHolder2<Generator1, Generator2> Combine(
- const Generator1& g1, const Generator2& g2) {
- return internal::CartesianProductHolder2<Generator1, Generator2>(
- g1, g2);
+template <typename... Generator>
+internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
+ return internal::CartesianProductHolder<Generator...>(g...);
}
-template <typename Generator1, typename Generator2, typename Generator3>
-internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3) {
- return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>(
- g1, g2, g3);
-}
+#define TEST_P(test_suite_name, test_name) \
+ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ : public test_suite_name { \
+ public: \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
+ virtual void TestBody(); \
+ \
+ private: \
+ static int AddToRegistry() { \
+ ::testing::UnitTest::GetInstance() \
+ ->parameterized_test_registry() \
+ .GetTestSuitePatternHolder<test_suite_name>( \
+ #test_suite_name, \
+ ::testing::internal::CodeLocation(__FILE__, __LINE__)) \
+ ->AddTestPattern( \
+ GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \
+ new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
+ test_suite_name, test_name)>()); \
+ return 0; \
+ } \
+ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
+ test_name)); \
+ }; \
+ int GTEST_TEST_CLASS_NAME_(test_suite_name, \
+ test_name)::gtest_registering_dummy_ = \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::AddToRegistry(); \
+ void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4>
-internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
- Generator4> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4) {
- return internal::CartesianProductHolder4<Generator1, Generator2, Generator3,
- Generator4>(
- g1, g2, g3, g4);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4, typename Generator5>
-internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
- Generator4, Generator5> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4, const Generator5& g5) {
- return internal::CartesianProductHolder5<Generator1, Generator2, Generator3,
- Generator4, Generator5>(
- g1, g2, g3, g4, g5);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4, typename Generator5, typename Generator6>
-internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4, const Generator5& g5, const Generator6& g6) {
- return internal::CartesianProductHolder6<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6>(
- g1, g2, g3, g4, g5, g6);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4, typename Generator5, typename Generator6,
- typename Generator7>
-internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4, const Generator5& g5, const Generator6& g6,
- const Generator7& g7) {
- return internal::CartesianProductHolder7<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7>(
- g1, g2, g3, g4, g5, g6, g7);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4, typename Generator5, typename Generator6,
- typename Generator7, typename Generator8>
-internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7, Generator8> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4, const Generator5& g5, const Generator6& g6,
- const Generator7& g7, const Generator8& g8) {
- return internal::CartesianProductHolder8<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7, Generator8>(
- g1, g2, g3, g4, g5, g6, g7, g8);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4, typename Generator5, typename Generator6,
- typename Generator7, typename Generator8, typename Generator9>
-internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7, Generator8,
- Generator9> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4, const Generator5& g5, const Generator6& g6,
- const Generator7& g7, const Generator8& g8, const Generator9& g9) {
- return internal::CartesianProductHolder9<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>(
- g1, g2, g3, g4, g5, g6, g7, g8, g9);
-}
-
-template <typename Generator1, typename Generator2, typename Generator3,
- typename Generator4, typename Generator5, typename Generator6,
- typename Generator7, typename Generator8, typename Generator9,
- typename Generator10>
-internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
- Generator10> Combine(
- const Generator1& g1, const Generator2& g2, const Generator3& g3,
- const Generator4& g4, const Generator5& g5, const Generator6& g6,
- const Generator7& g7, const Generator8& g8, const Generator9& g9,
- const Generator10& g10) {
- return internal::CartesianProductHolder10<Generator1, Generator2, Generator3,
- Generator4, Generator5, Generator6, Generator7, Generator8, Generator9,
- Generator10>(
- g1, g2, g3, g4, g5, g6, g7, g8, g9, g10);
-}
-# endif // GTEST_HAS_COMBINE
-
-
-
-# define TEST_P(test_case_name, test_name) \
- class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
- : public test_case_name { \
- public: \
- GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \
- virtual void TestBody(); \
- private: \
- static int AddToRegistry() { \
- ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
- GetTestCasePatternHolder<test_case_name>(\
- #test_case_name, \
- ::testing::internal::CodeLocation(\
- __FILE__, __LINE__))->AddTestPattern(\
- #test_case_name, \
- #test_name, \
- new ::testing::internal::TestMetaFactory< \
- GTEST_TEST_CLASS_NAME_(\
- test_case_name, test_name)>()); \
- return 0; \
- } \
- static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
- GTEST_DISALLOW_COPY_AND_ASSIGN_(\
- GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \
- }; \
- int GTEST_TEST_CLASS_NAME_(test_case_name, \
- test_name)::gtest_registering_dummy_ = \
- GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \
- void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
-
-// The optional last argument to INSTANTIATE_TEST_CASE_P allows the user
-// to specify a function or functor that generates custom test name suffixes
-// based on the test parameters. The function should accept one argument of
-// type testing::TestParamInfo<class ParamType>, and return std::string.
+// The last argument to INSTANTIATE_TEST_SUITE_P allows the user to specify
+// generator and an optional function or functor that generates custom test name
+// suffixes based on the test parameters. Such a function or functor should
+// accept one argument of type testing::TestParamInfo<class ParamType>, and
+// return std::string.
//
// testing::PrintToStringParamName is a builtin test suffix generator that
-// returns the value of testing::PrintToString(GetParam()). It does not work
-// for std::string or C strings.
+// returns the value of testing::PrintToString(GetParam()).
//
// Note: test names must be non-empty, unique, and may only contain ASCII
-// alphanumeric characters or underscore.
+// alphanumeric characters or underscore. Because PrintToString adds quotes
+// to std::string and C strings, it won't work for these types.
-# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator, ...) \
- ::testing::internal::ParamGenerator<test_case_name::ParamType> \
- gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \
- ::std::string gtest_##prefix##test_case_name##_EvalGenerateName_( \
- const ::testing::TestParamInfo<test_case_name::ParamType>& info) { \
- return ::testing::internal::GetParamNameGen<test_case_name::ParamType> \
- (__VA_ARGS__)(info); \
- } \
- int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \
- ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \
- GetTestCasePatternHolder<test_case_name>(\
- #test_case_name, \
- ::testing::internal::CodeLocation(\
- __FILE__, __LINE__))->AddTestCaseInstantiation(\
- #prefix, \
- >est_##prefix##test_case_name##_EvalGenerator_, \
- >est_##prefix##test_case_name##_EvalGenerateName_, \
- __FILE__, __LINE__)
+#define GTEST_EXPAND_(arg) arg
+#define GTEST_GET_FIRST_(first, ...) first
+#define GTEST_GET_SECOND_(first, second, ...) second
+
+#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
+ static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
+ gtest_##prefix##test_suite_name##_EvalGenerator_() { \
+ return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
+ } \
+ static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
+ const ::testing::TestParamInfo<test_suite_name::ParamType>& info) { \
+ if (::testing::internal::AlwaysFalse()) { \
+ ::testing::internal::TestNotEmpty(GTEST_EXPAND_(GTEST_GET_SECOND_( \
+ __VA_ARGS__, \
+ ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
+ DUMMY_PARAM_))); \
+ auto t = std::make_tuple(__VA_ARGS__); \
+ static_assert(std::tuple_size<decltype(t)>::value <= 2, \
+ "Too Many Args!"); \
+ } \
+ return ((GTEST_EXPAND_(GTEST_GET_SECOND_( \
+ __VA_ARGS__, \
+ ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
+ DUMMY_PARAM_))))(info); \
+ } \
+ static int gtest_##prefix##test_suite_name##_dummy_ \
+ GTEST_ATTRIBUTE_UNUSED_ = \
+ ::testing::UnitTest::GetInstance() \
+ ->parameterized_test_registry() \
+ .GetTestSuitePatternHolder<test_suite_name>( \
+ #test_suite_name, \
+ ::testing::internal::CodeLocation(__FILE__, __LINE__)) \
+ ->AddTestSuiteInstantiation( \
+ #prefix, >est_##prefix##test_suite_name##_EvalGenerator_, \
+ >est_##prefix##test_suite_name##_EvalGenerateName_, \
+ __FILE__, __LINE__)
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define INSTANTIATE_TEST_CASE_P \
+ static_assert(::testing::internal::InstantiateTestCase_P_IsDeprecated(), \
+ ""); \
+ INSTANTIATE_TEST_SUITE_P
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
} // namespace testing
-#endif // GTEST_HAS_PARAM_TEST
-
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-printers.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-printers.h
index be793bb..956f079 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-printers.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-printers.h
@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
-// Google Test - The Google C++ Testing Framework
+
+// Google Test - The Google C++ Testing and Mocking Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
@@ -46,6 +45,10 @@
// 2. operator<<(ostream&, const T&) defined in either foo or the
// global namespace.
//
+// However if T is an STL-style container then it is printed element-wise
+// unless foo::PrintTo(const T&, ostream*) is defined. Note that
+// operator<<() is ignored for container types.
+//
// If none of the above is defined, it will print the debug string of
// the value if it is a protocol buffer, or print the raw bytes in the
// value otherwise.
@@ -92,21 +95,28 @@
// being defined as many user-defined container types don't have
// value_type.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
+#include <functional>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
+#include <tuple>
+#include <type_traits>
#include <utility>
#include <vector>
-#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-internal.h"
+#include "gtest/internal/gtest-port.h"
#include "gtest/internal/custom/raw-ostream.h"
-#if GTEST_HAS_STD_TUPLE_
-# include <tuple>
-#endif
+#if GTEST_HAS_ABSL
+#include "absl/strings/string_view.h"
+#include "absl/types/optional.h"
+#include "absl/types/variant.h"
+#endif // GTEST_HAS_ABSL
namespace testing {
@@ -126,7 +136,11 @@
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
- kOtherType // anything else
+#if GTEST_HAS_ABSL
+ kConvertibleToStringView, // a type implicitly convertible to
+ // absl::string_view
+#endif
+ kOtherType // anything else
};
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
@@ -138,8 +152,10 @@
public:
// This default version is called when kTypeKind is kOtherType.
static void PrintValue(const T& value, ::std::ostream* os) {
- PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value),
- sizeof(value), os);
+ PrintBytesInObjectTo(
+ static_cast<const unsigned char*>(
+ reinterpret_cast<const void*>(std::addressof(value))),
+ sizeof(value), os);
}
};
@@ -152,10 +168,10 @@
class TypeWithoutFormatter<T, kProtobuf> {
public:
static void PrintValue(const T& value, ::std::ostream* os) {
- const ::testing::internal::string short_str = value.ShortDebugString();
- const ::testing::internal::string pretty_str =
- short_str.length() <= kProtobufOneLinerMaxLength ?
- short_str : ("\n" + value.DebugString());
+ std::string pretty_str = value.ShortDebugString();
+ if (pretty_str.length() > kProtobufOneLinerMaxLength) {
+ pretty_str = "\n" + value.DebugString();
+ }
*os << ("<" + pretty_str + ">");
}
};
@@ -176,6 +192,19 @@
}
};
+#if GTEST_HAS_ABSL
+template <typename T>
+class TypeWithoutFormatter<T, kConvertibleToStringView> {
+ public:
+ // Since T has neither operator<< nor PrintTo() but can be implicitly
+ // converted to absl::string_view, we print it as a absl::string_view.
+ //
+ // Note: the implementation is further below, as it depends on
+ // internal::PrintTo symbol which is defined later in the file.
+ static void PrintValue(const T& value, ::std::ostream* os);
+};
+#endif
+
// Prints the given value to the given ostream. If the value is a
// protocol message, its debug string is printed; if it's an enum or
// of a type implicitly convertible to BiggestInt, it's printed as an
@@ -203,10 +232,19 @@
template <typename Char, typename CharTraits, typename T>
::std::basic_ostream<Char, CharTraits>& operator<<(
::std::basic_ostream<Char, CharTraits>& os, const T& x) {
- TypeWithoutFormatter<T,
- (internal::IsAProtocolMessage<T>::value ? kProtobuf :
- internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ?
- kConvertibleToInteger : kOtherType)>::PrintValue(x, &os);
+ TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
+ ? kProtobuf
+ : std::is_convertible<
+ const T&, internal::BiggestInt>::value
+ ? kConvertibleToInteger
+ :
+#if GTEST_HAS_ABSL
+ std::is_convertible<
+ const T&, absl::string_view>::value
+ ? kConvertibleToStringView
+ :
+#endif
+ kOtherType)>::PrintValue(x, &os);
return os;
}
@@ -321,16 +359,6 @@
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
-#if GTEST_HAS_GLOBAL_STRING
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::string);
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::string);
-#endif
-
-#if GTEST_HAS_GLOBAL_WSTRING
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::wstring);
-GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::wstring);
-#endif
-
#if GTEST_HAS_STD_WSTRING
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
@@ -365,11 +393,18 @@
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
+enum DefaultPrinterType {
+ kPrintContainer,
+ kPrintPointer,
+ kPrintFunctionPointer,
+ kPrintOther,
+};
+template <DefaultPrinterType type> struct WrapPrinterType {};
+
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
template <typename C>
-void DefaultPrintTo(IsContainer /* dummy */,
- false_type /* is not a pointer */,
+void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */,
const C& container, ::std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
@@ -402,40 +437,34 @@
// implementation-defined. Therefore they will be printed as raw
// bytes.)
template <typename T>
-void DefaultPrintTo(IsNotContainer /* dummy */,
- true_type /* is a pointer */,
+void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
T* p, ::std::ostream* os) {
- if (p == NULL) {
+ if (p == nullptr) {
*os << "NULL";
} else {
- // C++ doesn't allow casting from a function pointer to any object
- // pointer.
- //
- // IsTrue() silences warnings: "Condition is always true",
- // "unreachable code".
- if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) {
- // T is not a function type. We just call << to print p,
- // relying on ADL to pick up user-defined << for their pointer
- // types, if any.
- *os << p;
- } else {
- // T is a function type, so '*os << p' doesn't do what we want
- // (it just prints p as bool). We want to print p as a const
- // void*. However, we cannot cast it to const void* directly,
- // even using reinterpret_cast, as earlier versions of gcc
- // (e.g. 3.4.5) cannot compile the cast when p is a function
- // pointer. Casting to UInt64 first solves the problem.
- *os << reinterpret_cast<const void*>(
- reinterpret_cast<internal::UInt64>(p));
- }
+ // T is not a function type. We just call << to print p,
+ // relying on ADL to pick up user-defined << for their pointer
+ // types, if any.
+ *os << p;
+ }
+}
+template <typename T>
+void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
+ T* p, ::std::ostream* os) {
+ if (p == nullptr) {
+ *os << "NULL";
+ } else {
+ // T is a function type, so '*os << p' doesn't do what we want
+ // (it just prints p as bool). We want to print p as a const
+ // void*.
+ *os << reinterpret_cast<const void*>(p);
}
}
// Used to print a non-container, non-pointer value when the user
// doesn't define PrintTo() for it.
template <typename T>
-void DefaultPrintTo(IsNotContainer /* dummy */,
- false_type /* is not a pointer */,
+void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
const T& value, ::std::ostream* os) {
::testing_internal::DefaultPrintNonContainerTo(value, os);
}
@@ -453,11 +482,8 @@
// wants).
template <typename T>
void PrintTo(const T& value, ::std::ostream* os) {
- // DefaultPrintTo() is overloaded. The type of its first two
- // arguments determine which version will be picked. If T is an
- // STL-style container, the version for container will be called; if
- // T is a pointer, the pointer version will be called; otherwise the
- // generic version will be called.
+ // DefaultPrintTo() is overloaded. The type of its first argument
+ // determines which version will be picked.
//
// Note that we check for container types here, prior to we check
// for protocol message types in our operator<<. The rationale is:
@@ -469,13 +495,23 @@
// elements; therefore we check for container types here to ensure
// that our format is used.
//
- // The second argument of DefaultPrintTo() is needed to bypass a bug
- // in Symbian's C++ compiler that prevents it from picking the right
- // overload between:
- //
- // PrintTo(const T& x, ...);
- // PrintTo(T* x, ...);
- DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os);
+ // Note that MSVC and clang-cl do allow an implicit conversion from
+ // pointer-to-function to pointer-to-object, but clang-cl warns on it.
+ // So don't use ImplicitlyConvertible if it can be helped since it will
+ // cause this warning, and use a separate overload of DefaultPrintTo for
+ // function pointers so that the `*os << p` in the object pointer overload
+ // doesn't cause that warning either.
+ DefaultPrintTo(
+ WrapPrinterType <
+ (sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
+ !IsRecursiveContainer<T>::value
+ ? kPrintContainer
+ : !std::is_pointer<T>::value
+ ? kPrintOther
+ : std::is_function<typename std::remove_pointer<T>::type>::value
+ ? kPrintFunctionPointer
+ : kPrintPointer > (),
+ value, os);
}
// The following list of PrintTo() overloads tells
@@ -554,27 +590,13 @@
}
}
-// Overloads for ::string and ::std::string.
-#if GTEST_HAS_GLOBAL_STRING
-GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os);
-inline void PrintTo(const ::string& s, ::std::ostream* os) {
- PrintStringTo(s, os);
-}
-#endif // GTEST_HAS_GLOBAL_STRING
-
+// Overloads for ::std::string.
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os);
}
-// Overloads for ::wstring and ::std::wstring.
-#if GTEST_HAS_GLOBAL_WSTRING
-GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os);
-inline void PrintTo(const ::wstring& s, ::std::ostream* os) {
- PrintWideStringTo(s, os);
-}
-#endif // GTEST_HAS_GLOBAL_WSTRING
-
+// Overloads for ::std::wstring.
#if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
@@ -582,95 +604,45 @@
}
#endif // GTEST_HAS_STD_WSTRING
-#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
+#if GTEST_HAS_ABSL
+// Overload for absl::string_view.
+inline void PrintTo(absl::string_view sp, ::std::ostream* os) {
+ PrintTo(::std::string(sp), os);
+}
+#endif // GTEST_HAS_ABSL
+
+inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
+
+template <typename T>
+void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
+ UniversalPrinter<T&>::Print(ref.get(), os);
+}
+
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>
-void PrintTupleTo(const T& t, ::std::ostream* os);
-#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
+void PrintTupleTo(const T&, std::integral_constant<size_t, 0>,
+ ::std::ostream*) {}
-#if GTEST_HAS_TR1_TUPLE
-// Overload for ::std::tr1::tuple. Needed for printing function arguments,
-// which are packed as tuples.
-
-// Overloaded PrintTo() for tuples of various arities. We support
-// tuples of up-to 10 fields. The following implementation works
-// regardless of whether tr1::tuple is implemented using the
-// non-standard variadic template feature or not.
-
-inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) {
- PrintTupleTo(t, os);
+template <typename T, size_t I>
+void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
+ ::std::ostream* os) {
+ PrintTupleTo(t, std::integral_constant<size_t, I - 1>(), os);
+ GTEST_INTENTIONAL_CONST_COND_PUSH_()
+ if (I > 1) {
+ GTEST_INTENTIONAL_CONST_COND_POP_()
+ *os << ", ";
+ }
+ UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
+ std::get<I - 1>(t), os);
}
-template <typename T1>
-void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2>
-void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t,
- ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t,
- ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t,
- ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t,
- ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
-void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t,
- ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-void PrintTo(
- const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t,
- ::std::ostream* os) {
- PrintTupleTo(t, os);
-}
-#endif // GTEST_HAS_TR1_TUPLE
-
-#if GTEST_HAS_STD_TUPLE_
template <typename... Types>
void PrintTo(const ::std::tuple<Types...>& t, ::std::ostream* os) {
- PrintTupleTo(t, os);
+ *os << "(";
+ PrintTupleTo(t, std::integral_constant<size_t, sizeof...(Types)>(), os);
+ *os << ")";
}
-#endif // GTEST_HAS_STD_TUPLE_
// Overload for std::pair.
template <typename T1, typename T2>
@@ -711,6 +683,48 @@
GTEST_DISABLE_MSC_WARNINGS_POP_()
};
+#if GTEST_HAS_ABSL
+
+// Printer for absl::optional
+
+template <typename T>
+class UniversalPrinter<::absl::optional<T>> {
+ public:
+ static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
+ *os << '(';
+ if (!value) {
+ *os << "nullopt";
+ } else {
+ UniversalPrint(*value, os);
+ }
+ *os << ')';
+ }
+};
+
+// Printer for absl::variant
+
+template <typename... T>
+class UniversalPrinter<::absl::variant<T...>> {
+ public:
+ static void Print(const ::absl::variant<T...>& value, ::std::ostream* os) {
+ *os << '(';
+ absl::visit(Visitor{os}, value);
+ *os << ')';
+ }
+
+ private:
+ struct Visitor {
+ template <typename U>
+ void operator()(const U& u) const {
+ *os << "'" << GetTypeName<U>() << "' with value ";
+ UniversalPrint(u, os);
+ }
+ ::std::ostream* os;
+ };
+};
+
+#endif // GTEST_HAS_ABSL
+
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
template <typename T>
@@ -724,7 +738,6 @@
// If the array has more than kThreshold elements, we'll have to
// omit some details by printing only the first and the last
// kChunkSize elements.
- // TODO([email protected]): let the user control the threshold using a flag.
if (len <= kThreshold) {
PrintRawArrayTo(begin, len, os);
} else {
@@ -803,10 +816,10 @@
class UniversalTersePrinter<const char*> {
public:
static void Print(const char* str, ::std::ostream* os) {
- if (str == NULL) {
+ if (str == nullptr) {
*os << "NULL";
} else {
- UniversalPrint(string(str), os);
+ UniversalPrint(std::string(str), os);
}
}
};
@@ -823,7 +836,7 @@
class UniversalTersePrinter<const wchar_t*> {
public:
static void Print(const wchar_t* str, ::std::ostream* os) {
- if (str == NULL) {
+ if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::wstring(str), os);
@@ -857,110 +870,22 @@
UniversalPrinter<T1>::Print(value, os);
}
-typedef ::std::vector<string> Strings;
-
-// TuplePolicy<TupleT> must provide:
-// - tuple_size
-// size of tuple TupleT.
-// - get<size_t I>(const TupleT& t)
-// static function extracting element I of tuple TupleT.
-// - tuple_element<size_t I>::type
-// type of element I of tuple TupleT.
-template <typename TupleT>
-struct TuplePolicy;
-
-#if GTEST_HAS_TR1_TUPLE
-template <typename TupleT>
-struct TuplePolicy {
- typedef TupleT Tuple;
- static const size_t tuple_size = ::std::tr1::tuple_size<Tuple>::value;
-
- template <size_t I>
- struct tuple_element : ::std::tr1::tuple_element<I, Tuple> {};
-
- template <size_t I>
- static typename AddReference<
- const typename ::std::tr1::tuple_element<I, Tuple>::type>::type get(
- const Tuple& tuple) {
- return ::std::tr1::get<I>(tuple);
- }
-};
-template <typename TupleT>
-const size_t TuplePolicy<TupleT>::tuple_size;
-#endif // GTEST_HAS_TR1_TUPLE
-
-#if GTEST_HAS_STD_TUPLE_
-template <typename... Types>
-struct TuplePolicy< ::std::tuple<Types...> > {
- typedef ::std::tuple<Types...> Tuple;
- static const size_t tuple_size = ::std::tuple_size<Tuple>::value;
-
- template <size_t I>
- struct tuple_element : ::std::tuple_element<I, Tuple> {};
-
- template <size_t I>
- static const typename ::std::tuple_element<I, Tuple>::type& get(
- const Tuple& tuple) {
- return ::std::get<I>(tuple);
- }
-};
-template <typename... Types>
-const size_t TuplePolicy< ::std::tuple<Types...> >::tuple_size;
-#endif // GTEST_HAS_STD_TUPLE_
-
-#if GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
-// This helper template allows PrintTo() for tuples and
-// UniversalTersePrintTupleFieldsToStrings() to be defined by
-// induction on the number of tuple fields. The idea is that
-// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N
-// fields in tuple t, and can be defined in terms of
-// TuplePrefixPrinter<N - 1>.
-//
-// The inductive case.
-template <size_t N>
-struct TuplePrefixPrinter {
- // Prints the first N fields of a tuple.
- template <typename Tuple>
- static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) {
- TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os);
- GTEST_INTENTIONAL_CONST_COND_PUSH_()
- if (N > 1) {
- GTEST_INTENTIONAL_CONST_COND_POP_()
- *os << ", ";
- }
- UniversalPrinter<
- typename TuplePolicy<Tuple>::template tuple_element<N - 1>::type>
- ::Print(TuplePolicy<Tuple>::template get<N - 1>(t), os);
- }
+typedef ::std::vector< ::std::string> Strings;
// Tersely prints the first N fields of a tuple to a string vector,
// one element for each field.
- template <typename Tuple>
- static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) {
- TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings);
- ::std::stringstream ss;
- UniversalTersePrint(TuplePolicy<Tuple>::template get<N - 1>(t), &ss);
- strings->push_back(ss.str());
- }
-};
-
-// Base case.
-template <>
-struct TuplePrefixPrinter<0> {
- template <typename Tuple>
- static void PrintPrefixTo(const Tuple&, ::std::ostream*) {}
-
- template <typename Tuple>
- static void TersePrintPrefixToStrings(const Tuple&, Strings*) {}
-};
-
-// Helper function for printing a tuple.
-// Tuple must be either std::tr1::tuple or std::tuple type.
template <typename Tuple>
-void PrintTupleTo(const Tuple& t, ::std::ostream* os) {
- *os << "(";
- TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::PrintPrefixTo(t, os);
- *os << ")";
+void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
+ Strings*) {}
+template <typename Tuple, size_t I>
+void TersePrintPrefixToStrings(const Tuple& t,
+ std::integral_constant<size_t, I>,
+ Strings* strings) {
+ TersePrintPrefixToStrings(t, std::integral_constant<size_t, I - 1>(),
+ strings);
+ ::std::stringstream ss;
+ UniversalTersePrint(std::get<I - 1>(t), &ss);
+ strings->push_back(ss.str());
}
// Prints the fields of a tuple tersely to a string vector, one
@@ -969,14 +894,24 @@
template <typename Tuple>
Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
Strings result;
- TuplePrefixPrinter<TuplePolicy<Tuple>::tuple_size>::
- TersePrintPrefixToStrings(value, &result);
+ TersePrintPrefixToStrings(
+ value, std::integral_constant<size_t, std::tuple_size<Tuple>::value>(),
+ &result);
return result;
}
-#endif // GTEST_HAS_TR1_TUPLE || GTEST_HAS_STD_TUPLE_
} // namespace internal
+#if GTEST_HAS_ABSL
+namespace internal2 {
+template <typename T>
+void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
+ const T& value, ::std::ostream* os) {
+ internal::PrintTo(absl::string_view(value), os);
+}
+} // namespace internal2
+#endif
+
template <typename T>
::std::string PrintToString(const T& value) {
::std::stringstream ss;
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h
index f63fa9a..aa38870 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-spi.h
@@ -26,17 +26,21 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
//
// Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test).
+// GOOGLETEST_CM0004 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#include "gtest/gtest.h"
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
namespace testing {
// This helper class can be used to mock out Google Test failure reporting
@@ -68,14 +72,15 @@
TestPartResultArray* result);
// The d'tor restores the previous test part result reporter.
- virtual ~ScopedFakeTestPartResultReporter();
+ ~ScopedFakeTestPartResultReporter() override;
// Appends the TestPartResult object to the TestPartResultArray
// received in the constructor.
//
// This method is from the TestPartResultReporterInterface
// interface.
- virtual void ReportTestPartResult(const TestPartResult& result);
+ void ReportTestPartResult(const TestPartResult& result) override;
+
private:
void Init();
@@ -97,13 +102,12 @@
public:
// The constructor remembers the arguments.
SingleFailureChecker(const TestPartResultArray* results,
- TestPartResult::Type type,
- const string& substr);
+ TestPartResult::Type type, const std::string& substr);
~SingleFailureChecker();
private:
const TestPartResultArray* const results_;
const TestPartResult::Type type_;
- const string substr_;
+ const std::string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
};
@@ -112,6 +116,8 @@
} // namespace testing
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
// A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given
// statement will cause exactly one fatal Google Test failure with 'substr'
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h
index 77eb844..05a7985 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-test-part.h
@@ -27,8 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Author: [email protected] (Markus Heule)
-//
+// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
@@ -38,6 +37,9 @@
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
namespace testing {
// A copyable object representing the result of a test part (i.e. an
@@ -51,22 +53,20 @@
enum Type {
kSuccess, // Succeeded.
kNonFatalFailure, // Failed but the test can continue.
- kFatalFailure // Failed and the test should be terminated.
+ kFatalFailure, // Failed and the test should be terminated.
+ kSkip // Skipped.
};
// C'tor. TestPartResult does NOT have a default constructor.
// Always use this constructor (with parameters) to create a
// TestPartResult object.
- TestPartResult(Type a_type,
- const char* a_file_name,
- int a_line_number,
+ TestPartResult(Type a_type, const char* a_file_name, int a_line_number,
const char* a_message)
: type_(a_type),
- file_name_(a_file_name == NULL ? "" : a_file_name),
+ file_name_(a_file_name == nullptr ? "" : a_file_name),
line_number_(a_line_number),
summary_(ExtractSummary(a_message)),
- message_(a_message) {
- }
+ message_(a_message) {}
// Gets the outcome of the test part.
Type type() const { return type_; }
@@ -74,7 +74,7 @@
// Gets the name of the source file where the test part took place, or
// NULL if it's unknown.
const char* file_name() const {
- return file_name_.empty() ? NULL : file_name_.c_str();
+ return file_name_.empty() ? nullptr : file_name_.c_str();
}
// Gets the line in the source file where the test part took place,
@@ -87,18 +87,21 @@
// Gets the message associated with the test part.
const char* message() const { return message_.c_str(); }
- // Returns true iff the test part passed.
+ // Returns true if and only if the test part was skipped.
+ bool skipped() const { return type_ == kSkip; }
+
+ // Returns true if and only if the test part passed.
bool passed() const { return type_ == kSuccess; }
- // Returns true iff the test part failed.
- bool failed() const { return type_ != kSuccess; }
-
- // Returns true iff the test part non-fatally failed.
+ // Returns true if and only if the test part non-fatally failed.
bool nonfatally_failed() const { return type_ == kNonFatalFailure; }
- // Returns true iff the test part fatally failed.
+ // Returns true if and only if the test part fatally failed.
bool fatally_failed() const { return type_ == kFatalFailure; }
+ // Returns true if and only if the test part failed.
+ bool failed() const { return fatally_failed() || nonfatally_failed(); }
+
private:
Type type_;
@@ -143,7 +146,7 @@
};
// This interface knows how to report a test part result.
-class TestPartResultReporterInterface {
+class GTEST_API_ TestPartResultReporterInterface {
public:
virtual ~TestPartResultReporterInterface() {}
@@ -162,8 +165,8 @@
: public TestPartResultReporterInterface {
public:
HasNewFatalFailureHelper();
- virtual ~HasNewFatalFailureHelper();
- virtual void ReportTestPartResult(const TestPartResult& result);
+ ~HasNewFatalFailureHelper() override;
+ void ReportTestPartResult(const TestPartResult& result) override;
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private:
bool has_new_fatal_failure_;
@@ -176,4 +179,6 @@
} // namespace testing
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h
index 5f69d56..095ce05 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest-typed-test.h
@@ -26,8 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
+
+// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
@@ -51,22 +52,22 @@
T value_;
};
-// Next, associate a list of types with the test case, which will be
+// Next, associate a list of types with the test suite, which will be
// repeated for each type in the list. The typedef is necessary for
// the macro to parse correctly.
typedef testing::Types<char, int, unsigned int> MyTypes;
-TYPED_TEST_CASE(FooTest, MyTypes);
+TYPED_TEST_SUITE(FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
-// TYPED_TEST_CASE(FooTest, int);
+// TYPED_TEST_SUITE(FooTest, int);
// Then, use TYPED_TEST() instead of TEST_F() to define as many typed
-// tests for this test case as you want.
+// tests for this test suite as you want.
TYPED_TEST(FooTest, DoesBlah) {
- // Inside a test, refer to TypeParam to get the type parameter.
- // Since we are inside a derived class template, C++ requires use to
- // visit the members of FooTest via 'this'.
+ // Inside a test, refer to the special name TypeParam to get the type
+ // parameter. Since we are inside a derived class template, C++ requires
+ // us to visit the members of FooTest via 'this'.
TypeParam n = this->value_;
// To visit static members of the fixture, add the TestFixture::
@@ -82,6 +83,24 @@
TYPED_TEST(FooTest, HasPropertyA) { ... }
+// TYPED_TEST_SUITE takes an optional third argument which allows to specify a
+// class that generates custom test name suffixes based on the type. This should
+// be a class which has a static template function GetName(int index) returning
+// a string for each type. The provided integer index equals the index of the
+// type in the provided type list. In many cases the index can be ignored.
+//
+// For example:
+// class MyTypeNames {
+// public:
+// template <typename T>
+// static std::string GetName(int) {
+// if (std::is_same<T, char>()) return "char";
+// if (std::is_same<T, int>()) return "int";
+// if (std::is_same<T, unsigned int>()) return "unsignedInt";
+// }
+// };
+// TYPED_TEST_SUITE(FooTest, MyTypes, MyTypeNames);
+
#endif // 0
// Type-parameterized tests are abstract test patterns parameterized
@@ -107,13 +126,13 @@
...
};
-// Next, declare that you will define a type-parameterized test case
+// Next, declare that you will define a type-parameterized test suite
// (the _P suffix is for "parameterized" or "pattern", whichever you
// prefer):
-TYPED_TEST_CASE_P(FooTest);
+TYPED_TEST_SUITE_P(FooTest);
// Then, use TYPED_TEST_P() to define as many type-parameterized tests
-// for this type-parameterized test case as you want.
+// for this type-parameterized test suite as you want.
TYPED_TEST_P(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type parameter.
TypeParam n = 0;
@@ -124,10 +143,10 @@
// Now the tricky part: you need to register all test patterns before
// you can instantiate them. The first argument of the macro is the
-// test case name; the rest are the names of the tests in this test
+// test suite name; the rest are the names of the tests in this test
// case.
-REGISTER_TYPED_TEST_CASE_P(FooTest,
- DoesBlah, HasPropertyA);
+REGISTER_TYPED_TEST_SUITE_P(FooTest,
+ DoesBlah, HasPropertyA);
// Finally, you are free to instantiate the pattern with the types you
// want. If you put the above code in a header file, you can #include
@@ -135,14 +154,19 @@
//
// To distinguish different instances of the pattern, the first
// argument to the INSTANTIATE_* macro is a prefix that will be added
-// to the actual test case name. Remember to pick unique prefixes for
+// to the actual test suite name. Remember to pick unique prefixes for
// different instances.
typedef testing::Types<char, int, unsigned int> MyTypes;
-INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
+INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// If the type list contains only one type, you can write that type
// directly without Types<...>:
-// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
+// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, int);
+//
+// Similar to the optional argument of TYPED_TEST_SUITE above,
+// INSTANTIATE_TEST_SUITE_P takes an optional fourth argument which allows to
+// generate custom names.
+// INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes, MyTypeNames);
#endif // 0
@@ -156,35 +180,53 @@
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the typedef for the type parameters of the
-// given test case.
-# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_
+// given test suite.
+#define GTEST_TYPE_PARAMS_(TestSuiteName) gtest_type_params_##TestSuiteName##_
-// The 'Types' template argument below must have spaces around it
-// since some compilers may choke on '>>' when passing a template
-// instance (e.g. Types<int>)
-# define TYPED_TEST_CASE(CaseName, Types) \
- typedef ::testing::internal::TypeList< Types >::type \
- GTEST_TYPE_PARAMS_(CaseName)
+// Expands to the name of the typedef for the NameGenerator, responsible for
+// creating the suffixes of the name.
+#define GTEST_NAME_GENERATOR_(TestSuiteName) \
+ gtest_type_params_##TestSuiteName##_NameGenerator
-# define TYPED_TEST(CaseName, TestName) \
- template <typename gtest_TypeParam_> \
- class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
- : public CaseName<gtest_TypeParam_> { \
- private: \
- typedef CaseName<gtest_TypeParam_> TestFixture; \
- typedef gtest_TypeParam_ TypeParam; \
- virtual void TestBody(); \
- }; \
- bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \
- ::testing::internal::TypeParameterizedTest< \
- CaseName, \
- ::testing::internal::TemplateSel< \
- GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \
- GTEST_TYPE_PARAMS_(CaseName)>::Register(\
- "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \
- #CaseName, #TestName, 0); \
- template <typename gtest_TypeParam_> \
- void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody()
+#define TYPED_TEST_SUITE(CaseName, Types, ...) \
+ typedef ::testing::internal::TypeList<Types>::type GTEST_TYPE_PARAMS_( \
+ CaseName); \
+ typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
+ GTEST_NAME_GENERATOR_(CaseName)
+
+# define TYPED_TEST(CaseName, TestName) \
+ template <typename gtest_TypeParam_> \
+ class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \
+ : public CaseName<gtest_TypeParam_> { \
+ private: \
+ typedef CaseName<gtest_TypeParam_> TestFixture; \
+ typedef gtest_TypeParam_ TypeParam; \
+ virtual void TestBody(); \
+ }; \
+ static bool gtest_##CaseName##_##TestName##_registered_ \
+ GTEST_ATTRIBUTE_UNUSED_ = \
+ ::testing::internal::TypeParameterizedTest< \
+ CaseName, \
+ ::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
+ TestName)>, \
+ GTEST_TYPE_PARAMS_( \
+ CaseName)>::Register("", \
+ ::testing::internal::CodeLocation( \
+ __FILE__, __LINE__), \
+ #CaseName, #TestName, 0, \
+ ::testing::internal::GenerateNames< \
+ GTEST_NAME_GENERATOR_(CaseName), \
+ GTEST_TYPE_PARAMS_(CaseName)>()); \
+ template <typename gtest_TypeParam_> \
+ void GTEST_TEST_CLASS_NAME_(CaseName, \
+ TestName)<gtest_TypeParam_>::TestBody()
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define TYPED_TEST_CASE \
+ static_assert(::testing::internal::TypedTestCaseIsDeprecated(), ""); \
+ TYPED_TEST_SUITE
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_HAS_TYPED_TEST
@@ -195,68 +237,93 @@
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the namespace name that the type-parameterized tests for
-// the given type-parameterized test case are defined in. The exact
+// the given type-parameterized test suite are defined in. The exact
// name of the namespace is subject to change without notice.
-# define GTEST_CASE_NAMESPACE_(TestCaseName) \
- gtest_case_##TestCaseName##_
+#define GTEST_SUITE_NAMESPACE_(TestSuiteName) gtest_suite_##TestSuiteName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the variable used to remember the names of
-// the defined tests in the given test case.
-# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \
- gtest_typed_test_case_p_state_##TestCaseName##_
+// the defined tests in the given test suite.
+#define GTEST_TYPED_TEST_SUITE_P_STATE_(TestSuiteName) \
+ gtest_typed_test_suite_p_state_##TestSuiteName##_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY.
//
// Expands to the name of the variable used to remember the names of
-// the registered tests in the given test case.
-# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \
- gtest_registered_test_names_##TestCaseName##_
+// the registered tests in the given test suite.
+#define GTEST_REGISTERED_TEST_NAMES_(TestSuiteName) \
+ gtest_registered_test_names_##TestSuiteName##_
// The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together.
-# define TYPED_TEST_CASE_P(CaseName) \
- static ::testing::internal::TypedTestCasePState \
- GTEST_TYPED_TEST_CASE_P_STATE_(CaseName)
+#define TYPED_TEST_SUITE_P(SuiteName) \
+ static ::testing::internal::TypedTestSuitePState \
+ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
-# define TYPED_TEST_P(CaseName, TestName) \
- namespace GTEST_CASE_NAMESPACE_(CaseName) { \
- template <typename gtest_TypeParam_> \
- class TestName : public CaseName<gtest_TypeParam_> { \
- private: \
- typedef CaseName<gtest_TypeParam_> TestFixture; \
- typedef gtest_TypeParam_ TypeParam; \
- virtual void TestBody(); \
- }; \
- static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
- GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\
- __FILE__, __LINE__, #CaseName, #TestName); \
- } \
- template <typename gtest_TypeParam_> \
- void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody()
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define TYPED_TEST_CASE_P \
+ static_assert(::testing::internal::TypedTestCase_P_IsDeprecated(), ""); \
+ TYPED_TEST_SUITE_P
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
-# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \
- namespace GTEST_CASE_NAMESPACE_(CaseName) { \
- typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
- } \
- static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \
- GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\
+#define TYPED_TEST_P(SuiteName, TestName) \
+ namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
+ template <typename gtest_TypeParam_> \
+ class TestName : public SuiteName<gtest_TypeParam_> { \
+ private: \
+ typedef SuiteName<gtest_TypeParam_> TestFixture; \
+ typedef gtest_TypeParam_ TypeParam; \
+ virtual void TestBody(); \
+ }; \
+ static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
+ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
+ __FILE__, __LINE__, #SuiteName, #TestName); \
+ } \
+ template <typename gtest_TypeParam_> \
+ void GTEST_SUITE_NAMESPACE_( \
+ SuiteName)::TestName<gtest_TypeParam_>::TestBody()
+
+#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
+ namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
+ typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \
+ } \
+ static const char* const GTEST_REGISTERED_TEST_NAMES_( \
+ SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
+ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
__FILE__, __LINE__, #__VA_ARGS__)
-// The 'Types' template argument below must have spaces around it
-// since some compilers may choke on '>>' when passing a template
-// instance (e.g. Types<int>)
-# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \
- bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \
- ::testing::internal::TypeParameterizedTestCase<CaseName, \
- GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \
- ::testing::internal::TypeList< Types >::type>::Register(\
- #Prefix, \
- ::testing::internal::CodeLocation(__FILE__, __LINE__), \
- >EST_TYPED_TEST_CASE_P_STATE_(CaseName), \
- #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName))
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define REGISTER_TYPED_TEST_CASE_P \
+ static_assert(::testing::internal::RegisterTypedTestCase_P_IsDeprecated(), \
+ ""); \
+ REGISTER_TYPED_TEST_SUITE_P
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
+ static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
+ ::testing::internal::TypeParameterizedTestSuite< \
+ SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
+ ::testing::internal::TypeList<Types>::type>:: \
+ Register(#Prefix, \
+ ::testing::internal::CodeLocation(__FILE__, __LINE__), \
+ >EST_TYPED_TEST_SUITE_P_STATE_(SuiteName), #SuiteName, \
+ GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
+ ::testing::internal::GenerateNames< \
+ ::testing::internal::NameGeneratorSelector< \
+ __VA_ARGS__>::type, \
+ ::testing::internal::TypeList<Types>::type>())
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+#define INSTANTIATE_TYPED_TEST_CASE_P \
+ static_assert( \
+ ::testing::internal::InstantiateTypedTestCase_P_IsDeprecated(), ""); \
+ INSTANTIATE_TYPED_TEST_SUITE_P
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_HAS_TYPED_TEST_P
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h
index f846c5b..dbe5b1c 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest.h
@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the public API for Google Test. It should be
// included by any test program that uses Google Test.
@@ -48,16 +47,22 @@
// registration from Barthelemy Dagenais' ([email protected])
// easyUnit framework.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_H_
+#include <cstddef>
#include <limits>
+#include <memory>
#include <ostream>
+#include <type_traits>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
#include "gtest/gtest-death-test.h"
+#include "gtest/gtest-matchers.h"
#include "gtest/gtest-message.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest-printers.h"
@@ -65,23 +70,20 @@
#include "gtest/gtest-test-part.h"
#include "gtest/gtest-typed-test.h"
-// Depending on the platform, different string classes are available.
-// On Linux, in addition to ::std::string, Google also makes use of
-// class ::string, which has the same interface as ::std::string, but
-// has a different implementation.
-//
-// You can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that
-// ::string is available AND is a distinct type to ::std::string, or
-// define it to 0 to indicate otherwise.
-//
-// If ::std::string and ::string are the same class on your platform
-// due to aliasing, you should define GTEST_HAS_GLOBAL_STRING to 0.
-//
-// If you do not define GTEST_HAS_GLOBAL_STRING, it is defined
-// heuristically.
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing {
+// Silence C4100 (unreferenced formal parameter) and 4805
+// unsafe mix of type 'const int' and type 'const bool'
+#ifdef _MSC_VER
+# pragma warning(push)
+# pragma warning(disable:4805)
+# pragma warning(disable:4100)
+#endif
+
+
// Declares the flags.
// This flag temporary enables the disabled tests.
@@ -103,6 +105,10 @@
// the tests to run. If the filter is not given all tests are executed.
GTEST_DECLARE_string_(filter);
+// This flag controls whether Google Test installs a signal handler that dumps
+// debugging information when fatal signals are raised.
+GTEST_DECLARE_bool_(install_failure_signal_handler);
+
// This flag causes the Google Test to list tests. None of the tests listed
// are actually run if the flag is provided.
GTEST_DECLARE_bool_(list_tests);
@@ -115,6 +121,9 @@
// test.
GTEST_DECLARE_bool_(print_time);
+// This flags control whether Google Test prints UTF8 characters as text.
+GTEST_DECLARE_bool_(print_utf8);
+
// This flag specifies the random number seed.
GTEST_DECLARE_int32_(random_seed);
@@ -135,7 +144,7 @@
// When this flag is specified, a failed assertion will throw an
// exception if exceptions are enabled, or exit the program with a
-// non-zero code otherwise.
+// non-zero code otherwise. For use with an external test framework.
GTEST_DECLARE_bool_(throw_on_failure);
// When this flag is set with a "host:port" string, on supported
@@ -143,6 +152,10 @@
// the specified host machine.
GTEST_DECLARE_string_(stream_result_to);
+#if GTEST_USE_OWN_FLAGFILE_FLAG_
+GTEST_DECLARE_string_(flagfile);
+#endif // GTEST_USE_OWN_FLAGFILE_FLAG_
+
// The upper limit for valid stack trace depths.
const int kMaxStackTraceDepth = 100;
@@ -160,6 +173,7 @@
class TestEventRepeater;
class UnitTestRecordPropertyTestHelper;
class WindowsDeathTest;
+class FuchsiaDeathTest;
class UnitTestImpl* GetUnitTestImpl();
void ReportFailureInUnknownLocation(TestPartResult::Type result_type,
const std::string& message);
@@ -170,7 +184,12 @@
// If we don't forward declare them the compiler might confuse the classes
// in friendship clauses with same named classes on the scope.
class Test;
-class TestCase;
+class TestSuite;
+
+// Old API is still available but deprecated
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+using TestCase = TestSuite;
+#endif
class TestInfo;
class UnitTest;
@@ -259,7 +278,9 @@
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult(const AssertionResult& other);
+#if defined(_MSC_VER) && _MSC_VER < 1910
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
+#endif
// Used in the EXPECT_TRUE/FALSE(bool_expression).
//
@@ -271,12 +292,15 @@
template <typename T>
explicit AssertionResult(
const T& success,
- typename internal::EnableIf<
- !internal::ImplicitlyConvertible<T, AssertionResult>::value>::type*
- /*enabler*/ = NULL)
+ typename std::enable_if<
+ !std::is_convertible<T, AssertionResult>::value>::type*
+ /*enabler*/
+ = nullptr)
: success_(success) {}
+#if defined(_MSC_VER) && _MSC_VER < 1910
GTEST_DISABLE_MSC_WARNINGS_POP_()
+#endif
// Assignment operator.
AssertionResult& operator=(AssertionResult other) {
@@ -284,7 +308,7 @@
return *this;
}
- // Returns true iff the assertion succeeded.
+ // Returns true if and only if the assertion succeeded.
operator bool() const { return success_; } // NOLINT
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
@@ -295,9 +319,8 @@
// assertion's expectation). When nothing has been streamed into the
// object, returns an empty string.
const char* message() const {
- return message_.get() != NULL ? message_->c_str() : "";
+ return message_.get() != nullptr ? message_->c_str() : "";
}
- // TODO([email protected]): Remove this after making sure no clients use it.
// Deprecated; please use message() instead.
const char* failure_message() const { return message(); }
@@ -318,8 +341,7 @@
private:
// Appends the contents of message to message_.
void AppendMessage(const Message& a_message) {
- if (message_.get() == NULL)
- message_.reset(new ::std::string);
+ if (message_.get() == nullptr) message_.reset(new ::std::string);
message_->append(a_message.GetString().c_str());
}
@@ -332,7 +354,7 @@
// construct is not satisfied with the predicate's outcome.
// Referenced via a pointer to avoid taking too much stack frame space
// with test assertions.
- internal::scoped_ptr< ::std::string> message_;
+ std::unique_ptr< ::std::string> message_;
};
// Makes a successful assertion result.
@@ -345,17 +367,26 @@
// Deprecated; use AssertionFailure() << msg.
GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
+} // namespace testing
+
+// Includes the auto-generated header that implements a family of generic
+// predicate assertion macros. This include comes late because it relies on
+// APIs declared above.
+#include "gtest/gtest_pred_impl.h"
+
+namespace testing {
+
// The abstract class that all tests inherit from.
//
-// In Google Test, a unit test program contains one or many TestCases, and
-// each TestCase contains one or many Tests.
+// In Google Test, a unit test program contains one or many TestSuites, and
+// each TestSuite contains one or many Tests.
//
// When you define a test using the TEST macro, you don't need to
// explicitly derive from Test - the TEST macro automatically does
// this for you.
//
// The only time you derive from Test is when defining a test fixture
-// to be used a TEST_F. For example:
+// to be used in a TEST_F. For example:
//
// class FooTest : public testing::Test {
// protected:
@@ -372,49 +403,57 @@
public:
friend class TestInfo;
- // Defines types for pointers to functions that set up and tear down
- // a test case.
- typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc;
- typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc;
-
// The d'tor is virtual as we intend to inherit from Test.
virtual ~Test();
// Sets up the stuff shared by all tests in this test case.
//
- // Google Test will call Foo::SetUpTestCase() before running the first
+ // Google Test will call Foo::SetUpTestSuite() before running the first
// test in test case Foo. Hence a sub-class can define its own
- // SetUpTestCase() method to shadow the one defined in the super
+ // SetUpTestSuite() method to shadow the one defined in the super
// class.
- static void SetUpTestCase() {}
+ // Failures that happen during SetUpTestSuite are logged but otherwise
+ // ignored.
+ static void SetUpTestSuite() {}
- // Tears down the stuff shared by all tests in this test case.
+ // Tears down the stuff shared by all tests in this test suite.
//
- // Google Test will call Foo::TearDownTestCase() after running the last
+ // Google Test will call Foo::TearDownTestSuite() after running the last
// test in test case Foo. Hence a sub-class can define its own
- // TearDownTestCase() method to shadow the one defined in the super
+ // TearDownTestSuite() method to shadow the one defined in the super
// class.
- static void TearDownTestCase() {}
+ // Failures that happen during TearDownTestSuite are logged but otherwise
+ // ignored.
+ static void TearDownTestSuite() {}
- // Returns true iff the current test has a fatal failure.
+ // Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ static void TearDownTestCase() {}
+ static void SetUpTestCase() {}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+ // Returns true if and only if the current test has a fatal failure.
static bool HasFatalFailure();
- // Returns true iff the current test has a non-fatal failure.
+ // Returns true if and only if the current test has a non-fatal failure.
static bool HasNonfatalFailure();
- // Returns true iff the current test has a (either fatal or
+ // Returns true if and only if the current test was skipped.
+ static bool IsSkipped();
+
+ // Returns true if and only if the current test has a (either fatal or
// non-fatal) failure.
static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); }
- // Logs a property for the current test, test case, or for the entire
+ // Logs a property for the current test, test suite, or for the entire
// invocation of the test program when used outside of the context of a
- // test case. Only the last value for a given key is remembered. These
+ // test suite. Only the last value for a given key is remembered. These
// are public static so they can be called from utility functions that are
// not members of the test fixture. Calls to RecordProperty made during
// lifespan of the test (from the moment its constructor starts to the
// moment its destructor finishes) will be output in XML as attributes of
// the <testcase> element. Properties recorded from fixture's
- // SetUpTestCase or TearDownTestCase are logged as attributes of the
+ // SetUpTestSuite or TearDownTestSuite are logged as attributes of the
// corresponding <testsuite> element. Calls to RecordProperty made in the
// global context (before or after invocation of RUN_ALL_TESTS and from
// SetUp/TearDown method of Environment objects registered with Google
@@ -433,8 +472,8 @@
virtual void TearDown();
private:
- // Returns true iff the current test has the same fixture class as
- // the first test in the current test case.
+ // Returns true if and only if the current test has the same fixture class
+ // as the first test in the current test suite.
static bool HasSameFixtureClass();
// Runs the test after the test fixture has been set up.
@@ -452,7 +491,7 @@
// internal method to avoid clashing with names used in user TESTs.
void DeleteSelf_() { delete this; }
- const internal::scoped_ptr< GTEST_FLAG_SAVER_ > gtest_flag_saver_;
+ const std::unique_ptr<GTEST_FLAG_SAVER_> gtest_flag_saver_;
// Often a user misspells SetUp() as Setup() and spends a long time
// wondering why it is never called by Google Test. The declaration of
@@ -471,7 +510,7 @@
// If you see an error about overriding the following function or
// about it being private, you have mis-spelled SetUp() as Setup().
struct Setup_should_be_spelled_SetUp {};
- virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+ virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
// We disallow copying Tests.
GTEST_DISALLOW_COPY_AND_ASSIGN_(Test);
@@ -535,24 +574,30 @@
// Returns the number of the test properties.
int test_property_count() const;
- // Returns true iff the test passed (i.e. no test part failed).
- bool Passed() const { return !Failed(); }
+ // Returns true if and only if the test passed (i.e. no test part failed).
+ bool Passed() const { return !Skipped() && !Failed(); }
- // Returns true iff the test failed.
+ // Returns true if and only if the test was skipped.
+ bool Skipped() const;
+
+ // Returns true if and only if the test failed.
bool Failed() const;
- // Returns true iff the test fatally failed.
+ // Returns true if and only if the test fatally failed.
bool HasFatalFailure() const;
- // Returns true iff the test has a non-fatal failure.
+ // Returns true if and only if the test has a non-fatal failure.
bool HasNonfatalFailure() const;
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
- // Returns the i-th test part result among all the results. i can range
- // from 0 to test_property_count() - 1. If i is not in that range, aborts
- // the program.
+ // Gets the time of the test case start, in ms from the start of the
+ // UNIX epoch.
+ TimeInMillis start_timestamp() const { return start_timestamp_; }
+
+ // Returns the i-th test part result among all the results. i can range from 0
+ // to total_part_count() - 1. If i is not in that range, aborts the program.
const TestPartResult& GetTestPartResult(int i) const;
// Returns the i-th test property. i can range from 0 to
@@ -562,13 +607,14 @@
private:
friend class TestInfo;
- friend class TestCase;
+ friend class TestSuite;
friend class UnitTest;
friend class internal::DefaultGlobalTestPartResultReporter;
friend class internal::ExecDeathTest;
friend class internal::TestResultAccessor;
friend class internal::UnitTestImpl;
friend class internal::WindowsDeathTest;
+ friend class internal::FuchsiaDeathTest;
// Gets the vector of TestPartResults.
const std::vector<TestPartResult>& test_part_results() const {
@@ -580,6 +626,9 @@
return test_properties_;
}
+ // Sets the start time.
+ void set_start_timestamp(TimeInMillis start) { start_timestamp_ = start; }
+
// Sets the elapsed time.
void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; }
@@ -593,8 +642,8 @@
const TestProperty& test_property);
// Adds a failure if the key is a reserved attribute of Google Test
- // testcase tags. Returns true if the property is valid.
- // TODO(russr): Validate attribute names are legal and human readable.
+ // testsuite tags. Returns true if the property is valid.
+ // FIXME: Validate attribute names are legal and human readable.
static bool ValidateTestProperty(const std::string& xml_element,
const TestProperty& test_property);
@@ -623,6 +672,8 @@
std::vector<TestProperty> test_properties_;
// Running count of death tests.
int death_test_count_;
+ // The start time, in milliseconds since UNIX Epoch.
+ TimeInMillis start_timestamp_;
// The elapsed time, in milliseconds.
TimeInMillis elapsed_time_;
@@ -632,7 +683,7 @@
// A TestInfo object stores the following information about a test:
//
-// Test case name
+// Test suite name
// Test name
// Whether the test should be run
// A function pointer that creates the test object when invoked
@@ -647,8 +698,13 @@
// don't inherit from TestInfo.
~TestInfo();
- // Returns the test case name.
- const char* test_case_name() const { return test_case_name_.c_str(); }
+ // Returns the test suite name.
+ const char* test_suite_name() const { return test_suite_name_.c_str(); }
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ const char* test_case_name() const { return test_suite_name(); }
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Returns the test name.
const char* name() const { return name_.c_str(); }
@@ -656,17 +712,15 @@
// Returns the name of the parameter type, or NULL if this is not a typed
// or a type-parameterized test.
const char* type_param() const {
- if (type_param_.get() != NULL)
- return type_param_->c_str();
- return NULL;
+ if (type_param_.get() != nullptr) return type_param_->c_str();
+ return nullptr;
}
// Returns the text representation of the value parameter, or NULL if this
// is not a value-parameterized test.
const char* value_param() const {
- if (value_param_.get() != NULL)
- return value_param_->c_str();
- return NULL;
+ if (value_param_.get() != nullptr) return value_param_->c_str();
+ return nullptr;
}
// Returns the file name where this test is defined.
@@ -675,12 +729,15 @@
// Returns the line where this test is defined.
int line() const { return location_.line; }
+ // Return true if this test should not be run because it's in another shard.
+ bool is_in_another_shard() const { return is_in_another_shard_; }
+
// Returns true if this test should run, that is if the test is not
// disabled (or it is disabled but the also_run_disabled_tests flag has
// been specified) and its full name matches the user-specified filter.
//
// Google Test allows the user to filter the tests by their full names.
- // The full name of a test Bar in test case Foo is defined as
+ // The full name of a test Bar in test suite Foo is defined as
// "Foo.Bar". Only the tests that match the filter will run.
//
// A filter is a colon-separated list of glob (not regex) patterns,
@@ -693,12 +750,11 @@
// contains the character 'A' or starts with "Foo.".
bool should_run() const { return should_run_; }
- // Returns true iff this test will appear in the XML report.
+ // Returns true if and only if this test will appear in the XML report.
bool is_reportable() const {
- // For now, the XML report includes all tests matching the filter.
- // In the future, we may trim tests that are excluded because of
- // sharding.
- return matches_filter_;
+ // The XML report includes tests matching the filter, excluding those
+ // run in other shards.
+ return matches_filter_ && !is_in_another_shard_;
}
// Returns the result of the test.
@@ -709,24 +765,19 @@
friend class internal::DefaultDeathTestFactory;
#endif // GTEST_HAS_DEATH_TEST
friend class Test;
- friend class TestCase;
+ friend class TestSuite;
friend class internal::UnitTestImpl;
friend class internal::StreamingListenerTest;
friend TestInfo* internal::MakeAndRegisterTestInfo(
- const char* test_case_name,
- const char* name,
- const char* type_param,
- const char* value_param,
- internal::CodeLocation code_location,
- internal::TypeId fixture_class_id,
- Test::SetUpTestCaseFunc set_up_tc,
- Test::TearDownTestCaseFunc tear_down_tc,
+ const char* test_suite_name, const char* name, const char* type_param,
+ const char* value_param, internal::CodeLocation code_location,
+ internal::TypeId fixture_class_id, internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc,
internal::TestFactoryBase* factory);
// Constructs a TestInfo object. The newly constructed instance assumes
// ownership of the factory object.
- TestInfo(const std::string& test_case_name,
- const std::string& name,
+ TestInfo(const std::string& test_suite_name, const std::string& name,
const char* a_type_param, // NULL if not a type-parameterized test
const char* a_value_param, // NULL if not a value-parameterized test
internal::CodeLocation a_code_location,
@@ -748,20 +799,21 @@
}
// These fields are immutable properties of the test.
- const std::string test_case_name_; // Test case name
+ const std::string test_suite_name_; // test suite name
const std::string name_; // Test name
// Name of the parameter type, or NULL if this is not a typed or a
// type-parameterized test.
- const internal::scoped_ptr<const ::std::string> type_param_;
+ const std::unique_ptr<const ::std::string> type_param_;
// Text representation of the value parameter, or NULL if this is not a
// value-parameterized test.
- const internal::scoped_ptr<const ::std::string> value_param_;
+ const std::unique_ptr<const ::std::string> value_param_;
internal::CodeLocation location_;
- const internal::TypeId fixture_class_id_; // ID of the test fixture class
- bool should_run_; // True iff this test should run
- bool is_disabled_; // True iff this test is disabled
- bool matches_filter_; // True if this test matches the
- // user-specified filter.
+ const internal::TypeId fixture_class_id_; // ID of the test fixture class
+ bool should_run_; // True if and only if this test should run
+ bool is_disabled_; // True if and only if this test is disabled
+ bool matches_filter_; // True if this test matches the
+ // user-specified filter.
+ bool is_in_another_shard_; // Will be run in another shard.
internal::TestFactoryBase* const factory_; // The factory that creates
// the test object
@@ -772,90 +824,96 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo);
};
-// A test case, which consists of a vector of TestInfos.
+// A test suite, which consists of a vector of TestInfos.
//
-// TestCase is not copyable.
-class GTEST_API_ TestCase {
+// TestSuite is not copyable.
+class GTEST_API_ TestSuite {
public:
- // Creates a TestCase with the given name.
+ // Creates a TestSuite with the given name.
//
- // TestCase does NOT have a default constructor. Always use this
- // constructor to create a TestCase object.
+ // TestSuite does NOT have a default constructor. Always use this
+ // constructor to create a TestSuite object.
//
// Arguments:
//
- // name: name of the test case
+ // name: name of the test suite
// a_type_param: the name of the test's type parameter, or NULL if
// this is not a type-parameterized test.
- // set_up_tc: pointer to the function that sets up the test case
- // tear_down_tc: pointer to the function that tears down the test case
- TestCase(const char* name, const char* a_type_param,
- Test::SetUpTestCaseFunc set_up_tc,
- Test::TearDownTestCaseFunc tear_down_tc);
+ // set_up_tc: pointer to the function that sets up the test suite
+ // tear_down_tc: pointer to the function that tears down the test suite
+ TestSuite(const char* name, const char* a_type_param,
+ internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc);
- // Destructor of TestCase.
- virtual ~TestCase();
+ // Destructor of TestSuite.
+ virtual ~TestSuite();
- // Gets the name of the TestCase.
+ // Gets the name of the TestSuite.
const char* name() const { return name_.c_str(); }
// Returns the name of the parameter type, or NULL if this is not a
- // type-parameterized test case.
+ // type-parameterized test suite.
const char* type_param() const {
- if (type_param_.get() != NULL)
- return type_param_->c_str();
- return NULL;
+ if (type_param_.get() != nullptr) return type_param_->c_str();
+ return nullptr;
}
- // Returns true if any test in this test case should run.
+ // Returns true if any test in this test suite should run.
bool should_run() const { return should_run_; }
- // Gets the number of successful tests in this test case.
+ // Gets the number of successful tests in this test suite.
int successful_test_count() const;
- // Gets the number of failed tests in this test case.
+ // Gets the number of skipped tests in this test suite.
+ int skipped_test_count() const;
+
+ // Gets the number of failed tests in this test suite.
int failed_test_count() const;
// Gets the number of disabled tests that will be reported in the XML report.
int reportable_disabled_test_count() const;
- // Gets the number of disabled tests in this test case.
+ // Gets the number of disabled tests in this test suite.
int disabled_test_count() const;
// Gets the number of tests to be printed in the XML report.
int reportable_test_count() const;
- // Get the number of tests in this test case that should run.
+ // Get the number of tests in this test suite that should run.
int test_to_run_count() const;
- // Gets the number of all tests in this test case.
+ // Gets the number of all tests in this test suite.
int total_test_count() const;
- // Returns true iff the test case passed.
+ // Returns true if and only if the test suite passed.
bool Passed() const { return !Failed(); }
- // Returns true iff the test case failed.
+ // Returns true if and only if the test suite failed.
bool Failed() const { return failed_test_count() > 0; }
// Returns the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
+ // Gets the time of the test suite start, in ms from the start of the
+ // UNIX epoch.
+ TimeInMillis start_timestamp() const { return start_timestamp_; }
+
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
const TestInfo* GetTestInfo(int i) const;
// Returns the TestResult that holds test properties recorded during
- // execution of SetUpTestCase and TearDownTestCase.
+ // execution of SetUpTestSuite and TearDownTestSuite.
const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; }
private:
friend class Test;
friend class internal::UnitTestImpl;
- // Gets the (mutable) vector of TestInfos in this TestCase.
+ // Gets the (mutable) vector of TestInfos in this TestSuite.
std::vector<TestInfo*>& test_info_list() { return test_info_list_; }
- // Gets the (immutable) vector of TestInfos in this TestCase.
+ // Gets the (immutable) vector of TestInfos in this TestSuite.
const std::vector<TestInfo*>& test_info_list() const {
return test_info_list_;
}
@@ -867,51 +925,64 @@
// Sets the should_run member.
void set_should_run(bool should) { should_run_ = should; }
- // Adds a TestInfo to this test case. Will delete the TestInfo upon
- // destruction of the TestCase object.
+ // Adds a TestInfo to this test suite. Will delete the TestInfo upon
+ // destruction of the TestSuite object.
void AddTestInfo(TestInfo * test_info);
- // Clears the results of all tests in this test case.
+ // Clears the results of all tests in this test suite.
void ClearResult();
- // Clears the results of all tests in the given test case.
- static void ClearTestCaseResult(TestCase* test_case) {
- test_case->ClearResult();
+ // Clears the results of all tests in the given test suite.
+ static void ClearTestSuiteResult(TestSuite* test_suite) {
+ test_suite->ClearResult();
}
- // Runs every test in this TestCase.
+ // Runs every test in this TestSuite.
void Run();
- // Runs SetUpTestCase() for this TestCase. This wrapper is needed
- // for catching exceptions thrown from SetUpTestCase().
- void RunSetUpTestCase() { (*set_up_tc_)(); }
+ // Runs SetUpTestSuite() for this TestSuite. This wrapper is needed
+ // for catching exceptions thrown from SetUpTestSuite().
+ void RunSetUpTestSuite() {
+ if (set_up_tc_ != nullptr) {
+ (*set_up_tc_)();
+ }
+ }
- // Runs TearDownTestCase() for this TestCase. This wrapper is
- // needed for catching exceptions thrown from TearDownTestCase().
- void RunTearDownTestCase() { (*tear_down_tc_)(); }
+ // Runs TearDownTestSuite() for this TestSuite. This wrapper is
+ // needed for catching exceptions thrown from TearDownTestSuite().
+ void RunTearDownTestSuite() {
+ if (tear_down_tc_ != nullptr) {
+ (*tear_down_tc_)();
+ }
+ }
- // Returns true iff test passed.
+ // Returns true if and only if test passed.
static bool TestPassed(const TestInfo* test_info) {
return test_info->should_run() && test_info->result()->Passed();
}
- // Returns true iff test failed.
+ // Returns true if and only if test skipped.
+ static bool TestSkipped(const TestInfo* test_info) {
+ return test_info->should_run() && test_info->result()->Skipped();
+ }
+
+ // Returns true if and only if test failed.
static bool TestFailed(const TestInfo* test_info) {
return test_info->should_run() && test_info->result()->Failed();
}
- // Returns true iff the test is disabled and will be reported in the XML
- // report.
+ // Returns true if and only if the test is disabled and will be reported in
+ // the XML report.
static bool TestReportableDisabled(const TestInfo* test_info) {
return test_info->is_reportable() && test_info->is_disabled_;
}
- // Returns true iff test is disabled.
+ // Returns true if and only if test is disabled.
static bool TestDisabled(const TestInfo* test_info) {
return test_info->is_disabled_;
}
- // Returns true iff this test will appear in the XML report.
+ // Returns true if and only if this test will appear in the XML report.
static bool TestReportable(const TestInfo* test_info) {
return test_info->is_reportable();
}
@@ -921,17 +992,17 @@
return test_info->should_run();
}
- // Shuffles the tests in this test case.
+ // Shuffles the tests in this test suite.
void ShuffleTests(internal::Random* random);
// Restores the test order to before the first shuffle.
void UnshuffleTests();
- // Name of the test case.
+ // Name of the test suite.
std::string name_;
// Name of the parameter type, or NULL if this is not a typed or a
// type-parameterized test.
- const internal::scoped_ptr<const ::std::string> type_param_;
+ const std::unique_ptr<const ::std::string> type_param_;
// The vector of TestInfos in their original order. It owns the
// elements in the vector.
std::vector<TestInfo*> test_info_list_;
@@ -939,20 +1010,22 @@
// shuffling and restoring the test order. The i-th element in this
// vector is the index of the i-th test in the shuffled test list.
std::vector<int> test_indices_;
- // Pointer to the function that sets up the test case.
- Test::SetUpTestCaseFunc set_up_tc_;
- // Pointer to the function that tears down the test case.
- Test::TearDownTestCaseFunc tear_down_tc_;
- // True iff any test in this test case should run.
+ // Pointer to the function that sets up the test suite.
+ internal::SetUpTestSuiteFunc set_up_tc_;
+ // Pointer to the function that tears down the test suite.
+ internal::TearDownTestSuiteFunc tear_down_tc_;
+ // True if and only if any test in this test suite should run.
bool should_run_;
+ // The start time, in milliseconds since UNIX Epoch.
+ TimeInMillis start_timestamp_;
// Elapsed time, in milliseconds.
TimeInMillis elapsed_time_;
- // Holds test properties recorded during execution of SetUpTestCase and
- // TearDownTestCase.
+ // Holds test properties recorded during execution of SetUpTestSuite and
+ // TearDownTestSuite.
TestResult ad_hoc_test_result_;
- // We disallow copying TestCases.
- GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase);
+ // We disallow copying TestSuites.
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(TestSuite);
};
// An Environment object is capable of setting up and tearing down an
@@ -983,9 +1056,21 @@
// If you see an error about overriding the following function or
// about it being private, you have mis-spelled SetUp() as Setup().
struct Setup_should_be_spelled_SetUp {};
- virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; }
+ virtual Setup_should_be_spelled_SetUp* Setup() { return nullptr; }
};
+#if GTEST_HAS_EXCEPTIONS
+
+// Exception which can be thrown from TestEventListener::OnTestPartResult.
+class GTEST_API_ AssertionException
+ : public internal::GoogleTestFailureException {
+ public:
+ explicit AssertionException(const TestPartResult& result)
+ : GoogleTestFailureException(result) {}
+};
+
+#endif // GTEST_HAS_EXCEPTIONS
+
// The interface for tracing execution of tests. The methods are organized in
// the order the corresponding events are fired.
class TestEventListener {
@@ -1007,20 +1092,32 @@
// Fired after environment set-up for each iteration of tests ends.
virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
- // Fired before the test case starts.
- virtual void OnTestCaseStart(const TestCase& test_case) = 0;
+ // Fired before the test suite starts.
+ virtual void OnTestSuiteStart(const TestSuite& /*test_suite*/) {}
+
+ // Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Fired before the test starts.
virtual void OnTestStart(const TestInfo& test_info) = 0;
// Fired after a failed assertion or a SUCCEED() invocation.
+ // If you want to throw an exception from this function to skip to the next
+ // TEST, it must be AssertionException defined above, or inherited from it.
virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
// Fired after the test ends.
virtual void OnTestEnd(const TestInfo& test_info) = 0;
- // Fired after the test case ends.
- virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
+ // Fired after the test suite ends.
+ virtual void OnTestSuiteEnd(const TestSuite& /*test_suite*/) {}
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Fired before environment tear-down for each iteration of tests starts.
virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
@@ -1043,21 +1140,30 @@
// above.
class EmptyTestEventListener : public TestEventListener {
public:
- virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
- virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
- int /*iteration*/) {}
- virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
- virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
- virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
- virtual void OnTestStart(const TestInfo& /*test_info*/) {}
- virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
- virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
- virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
- virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
- virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
- virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
- int /*iteration*/) {}
- virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+ void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
+ void OnTestIterationStart(const UnitTest& /*unit_test*/,
+ int /*iteration*/) override {}
+ void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) override {}
+ void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
+ void OnTestSuiteStart(const TestSuite& /*test_suite*/) override {}
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestCaseStart(const TestCase& /*test_case*/) override {}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+ void OnTestStart(const TestInfo& /*test_info*/) override {}
+ void OnTestPartResult(const TestPartResult& /*test_part_result*/) override {}
+ void OnTestEnd(const TestInfo& /*test_info*/) override {}
+ void OnTestSuiteEnd(const TestSuite& /*test_suite*/) override {}
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestCaseEnd(const TestCase& /*test_case*/) override {}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+ void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) override {}
+ void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
+ void OnTestIterationEnd(const UnitTest& /*unit_test*/,
+ int /*iteration*/) override {}
+ void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
};
// TestEventListeners lets users add listeners to track events in Google Test.
@@ -1097,7 +1203,7 @@
}
private:
- friend class TestCase;
+ friend class TestSuite;
friend class TestInfo;
friend class internal::DefaultGlobalTestPartResultReporter;
friend class internal::NoExecDeathTest;
@@ -1138,7 +1244,7 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners);
};
-// A UnitTest consists of a vector of TestCases.
+// A UnitTest consists of a vector of TestSuites.
//
// This is a singleton class. The only instance of UnitTest is
// created when UnitTest::GetInstance() is first called. This
@@ -1167,10 +1273,14 @@
// was executed. The UnitTest object owns the string.
const char* original_working_dir() const;
- // Returns the TestCase object for the test that's currently running,
+ // Returns the TestSuite object for the test that's currently running,
// or NULL if no test is running.
- const TestCase* current_test_case() const
- GTEST_LOCK_EXCLUDED_(mutex_);
+ const TestSuite* current_test_suite() const GTEST_LOCK_EXCLUDED_(mutex_);
+
+// Legacy API is still available but deprecated
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ const TestCase* current_test_case() const GTEST_LOCK_EXCLUDED_(mutex_);
+#endif
// Returns the TestInfo object for the test that's currently running,
// or NULL if no test is running.
@@ -1180,31 +1290,40 @@
// Returns the random seed used at the start of the current test run.
int random_seed() const;
-#if GTEST_HAS_PARAM_TEST
- // Returns the ParameterizedTestCaseRegistry object used to keep track of
+ // Returns the ParameterizedTestSuiteRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
- internal::ParameterizedTestCaseRegistry& parameterized_test_registry()
+ internal::ParameterizedTestSuiteRegistry& parameterized_test_registry()
GTEST_LOCK_EXCLUDED_(mutex_);
-#endif // GTEST_HAS_PARAM_TEST
- // Gets the number of successful test cases.
- int successful_test_case_count() const;
+ // Gets the number of successful test suites.
+ int successful_test_suite_count() const;
- // Gets the number of failed test cases.
- int failed_test_case_count() const;
+ // Gets the number of failed test suites.
+ int failed_test_suite_count() const;
- // Gets the number of all test cases.
- int total_test_case_count() const;
+ // Gets the number of all test suites.
+ int total_test_suite_count() const;
- // Gets the number of all test cases that contain at least one test
+ // Gets the number of all test suites that contain at least one test
// that should run.
+ int test_suite_to_run_count() const;
+
+ // Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ int successful_test_case_count() const;
+ int failed_test_case_count() const;
+ int total_test_case_count() const;
int test_case_to_run_count() const;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Gets the number of successful tests.
int successful_test_count() const;
+ // Gets the number of skipped tests.
+ int skipped_test_count() const;
+
// Gets the number of failed tests.
int failed_test_count() const;
@@ -1230,19 +1349,25 @@
// Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const;
- // Returns true iff the unit test passed (i.e. all test cases passed).
+ // Returns true if and only if the unit test passed (i.e. all test suites
+ // passed).
bool Passed() const;
- // Returns true iff the unit test failed (i.e. some test case failed
- // or something outside of all tests failed).
+ // Returns true if and only if the unit test failed (i.e. some test suite
+ // failed or something outside of all tests failed).
bool Failed() const;
- // Gets the i-th test case among all the test cases. i can range from 0 to
- // total_test_case_count() - 1. If i is not in that range, returns NULL.
+ // Gets the i-th test suite among all the test suites. i can range from 0 to
+ // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+ const TestSuite* GetTestSuite(int i) const;
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
const TestCase* GetTestCase(int i) const;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Returns the TestResult containing information on test failures and
- // properties logged outside of individual test cases.
+ // properties logged outside of individual test suites.
const TestResult& ad_hoc_test_result() const;
// Returns the list of event listeners that can be used to track events
@@ -1273,25 +1398,25 @@
GTEST_LOCK_EXCLUDED_(mutex_);
// Adds a TestProperty to the current TestResult object when invoked from
- // inside a test, to current TestCase's ad_hoc_test_result_ when invoked
- // from SetUpTestCase or TearDownTestCase, or to the global property set
+ // inside a test, to current TestSuite's ad_hoc_test_result_ when invoked
+ // from SetUpTestSuite or TearDownTestSuite, or to the global property set
// when invoked elsewhere. If the result already contains a property with
// the same key, the value will be updated.
void RecordProperty(const std::string& key, const std::string& value);
- // Gets the i-th test case among all the test cases. i can range from 0 to
- // total_test_case_count() - 1. If i is not in that range, returns NULL.
- TestCase* GetMutableTestCase(int i);
+ // Gets the i-th test suite among all the test suites. i can range from 0 to
+ // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+ TestSuite* GetMutableTestSuite(int i);
// Accessors for the implementation object.
internal::UnitTestImpl* impl() { return impl_; }
const internal::UnitTestImpl* impl() const { return impl_; }
- // These classes and funcions are friends as they need to access private
+ // These classes and functions are friends as they need to access private
// members of UnitTest.
+ friend class ScopedTrace;
friend class Test;
friend class internal::AssertHelper;
- friend class internal::ScopedTrace;
friend class internal::StreamingListenerTest;
friend class internal::UnitTestRecordPropertyTestHelper;
friend Environment* AddGlobalTestEnvironment(Environment* env);
@@ -1366,6 +1491,10 @@
// UNICODE mode.
GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv);
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+GTEST_API_ void InitGoogleTest();
+
namespace internal {
// Separate the error generating code from the code path to reduce the stack
@@ -1382,17 +1511,22 @@
false);
}
+// This block of code defines operator==/!=
+// to block lexical scope lookup.
+// It prevents using invalid operator==/!= defined at namespace scope.
+struct faketype {};
+inline bool operator==(faketype, faketype) { return true; }
+inline bool operator!=(faketype, faketype) { return false; }
+
// The helper function for {ASSERT|EXPECT}_EQ.
template <typename T1, typename T2>
AssertionResult CmpHelperEQ(const char* lhs_expression,
const char* rhs_expression,
const T1& lhs,
const T2& rhs) {
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */)
if (lhs == rhs) {
return AssertionSuccess();
}
-GTEST_DISABLE_MSC_WARNINGS_POP_()
return CmpHelperEQFailure(lhs_expression, rhs_expression, lhs, rhs);
}
@@ -1405,18 +1539,17 @@
BiggestInt lhs,
BiggestInt rhs);
-// The helper class for {ASSERT|EXPECT}_EQ. The template argument
-// lhs_is_null_literal is true iff the first argument to ASSERT_EQ()
-// is a null pointer literal. The following default implementation is
-// for lhs_is_null_literal being false.
-template <bool lhs_is_null_literal>
class EqHelper {
public:
// This templatized version is for the general case.
- template <typename T1, typename T2>
+ template <
+ typename T1, typename T2,
+ // Disable this overload for cases where one argument is a pointer
+ // and the other is the null pointer constant.
+ typename std::enable_if<!std::is_integral<T1>::value ||
+ !std::is_pointer<T2>::value>::type* = nullptr>
static AssertionResult Compare(const char* lhs_expression,
- const char* rhs_expression,
- const T1& lhs,
+ const char* rhs_expression, const T1& lhs,
const T2& rhs) {
return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
}
@@ -1433,49 +1566,15 @@
BiggestInt rhs) {
return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
}
-};
-// This specialization is used when the first argument to ASSERT_EQ()
-// is a null pointer literal, like NULL, false, or 0.
-template <>
-class EqHelper<true> {
- public:
- // We define two overloaded versions of Compare(). The first
- // version will be picked when the second argument to ASSERT_EQ() is
- // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or
- // EXPECT_EQ(false, a_bool).
- template <typename T1, typename T2>
- static AssertionResult Compare(
- const char* lhs_expression,
- const char* rhs_expression,
- const T1& lhs,
- const T2& rhs,
- // The following line prevents this overload from being considered if T2
- // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr)
- // expands to Compare("", "", NULL, my_ptr), which requires a conversion
- // to match the Secret* in the other overload, which would otherwise make
- // this template match better.
- typename EnableIf<!is_pointer<T2>::value>::type* = 0) {
- return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
- }
-
- // This version will be picked when the second argument to ASSERT_EQ() is a
- // pointer, e.g. ASSERT_EQ(NULL, a_pointer).
template <typename T>
static AssertionResult Compare(
- const char* lhs_expression,
- const char* rhs_expression,
- // We used to have a second template parameter instead of Secret*. That
- // template parameter would deduce to 'long', making this a better match
- // than the first overload even without the first overload's EnableIf.
- // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to
- // non-pointer argument" (even a deduced integral argument), so the old
- // implementation caused warnings in user code.
- Secret* /* lhs (NULL) */,
- T* rhs) {
+ const char* lhs_expression, const char* rhs_expression,
+ // Handle cases where '0' is used as a null pointer literal.
+ std::nullptr_t /* lhs */, T* rhs) {
// We already know that 'lhs' is a null pointer.
- return CmpHelperEQ(lhs_expression, rhs_expression,
- static_cast<T*>(NULL), rhs);
+ return CmpHelperEQ(lhs_expression, rhs_expression, static_cast<T*>(nullptr),
+ rhs);
}
};
@@ -1704,9 +1803,14 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
};
+enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW };
+
+GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color,
+ const char* fmt,
+ ...);
+
} // namespace internal
-#if GTEST_HAS_PARAM_TEST
// The pure interface class that all value-parameterized tests inherit from.
// A value-parameterized class must inherit from both ::testing::Test and
// ::testing::WithParamInterface. In most cases that just means inheriting
@@ -1724,13 +1828,13 @@
// FooTest() {
// // Can use GetParam() here.
// }
-// virtual ~FooTest() {
+// ~FooTest() override {
// // Can use GetParam() here.
// }
-// virtual void SetUp() {
+// void SetUp() override {
// // Can use GetParam() here.
// }
-// virtual void TearDown {
+// void TearDown override {
// // Can use GetParam() here.
// }
// };
@@ -1739,7 +1843,7 @@
// Foo foo;
// ASSERT_TRUE(foo.DoesBar(GetParam()));
// }
-// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
+// INSTANTIATE_TEST_SUITE_P(OneToTenRange, FooTest, ::testing::Range(1, 10));
template <typename T>
class WithParamInterface {
@@ -1748,12 +1852,9 @@
virtual ~WithParamInterface() {}
// The current parameter value. Is also available in the test fixture's
- // constructor. This member function is non-static, even though it only
- // references static data, to reduce the opportunity for incorrect uses
- // like writing 'WithParamInterface<bool>::GetParam()' for a test that
- // uses a fixture whose parameter type is int.
- const ParamType& GetParam() const {
- GTEST_CHECK_(parameter_ != NULL)
+ // constructor.
+ static const ParamType& GetParam() {
+ GTEST_CHECK_(parameter_ != nullptr)
<< "GetParam() can only be called inside a value-parameterized test "
<< "-- did you intend to write TEST_P instead of TEST_F?";
return *parameter_;
@@ -1774,7 +1875,7 @@
};
template <typename T>
-const T* WithParamInterface<T>::parameter_ = NULL;
+const T* WithParamInterface<T>::parameter_ = nullptr;
// Most value-parameterized classes can ignore the existence of
// WithParamInterface, and can just inherit from ::testing::TestWithParam.
@@ -1783,10 +1884,13 @@
class TestWithParam : public Test, public WithParamInterface<T> {
};
-#endif // GTEST_HAS_PARAM_TEST
-
// Macros for indicating success/failure in test code.
+// Skips test in runtime.
+// Skipping test aborts current function.
+// Skipped tests are neither successful nor failed.
+#define GTEST_SKIP() GTEST_SKIP_("Skipped")
+
// ADD_FAILURE unconditionally adds a failure to the current test.
// SUCCEED generates a success - it doesn't automatically make the
// current test successful, as a test is only successful when it has
@@ -1816,6 +1920,11 @@
// Generates a fatal failure with a generic message.
#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed")
+// Like GTEST_FAIL(), but at the given source file location.
+#define GTEST_FAIL_AT(file, line) \
+ GTEST_MESSAGE_AT_(file, line, "Failed", \
+ ::testing::TestPartResult::kFatalFailure)
+
// Define this macro to 1 to omit the definition of FAIL(), which is a
// generic name and clashes with some other libraries.
#if !GTEST_DONT_DEFINE_FAIL
@@ -1857,22 +1966,18 @@
// AssertionResult. For more information on how to use AssertionResult with
// these macros see comments on that class.
#define EXPECT_TRUE(condition) \
- GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
+ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_NONFATAL_FAILURE_)
#define EXPECT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_NONFATAL_FAILURE_)
#define ASSERT_TRUE(condition) \
- GTEST_TEST_BOOLEAN_((condition), #condition, false, true, \
+ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \
GTEST_FATAL_FAILURE_)
#define ASSERT_FALSE(condition) \
GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \
GTEST_FATAL_FAILURE_)
-// Includes the auto-generated header that implements a family of
-// generic predicate assertion macros.
-#include "gtest/gtest_pred_impl.h"
-
// Macros for testing equalities and inequalities.
//
// * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2
@@ -1914,15 +2019,13 @@
//
// Examples:
//
-// EXPECT_NE(5, Foo());
-// EXPECT_EQ(NULL, a_pointer);
+// EXPECT_NE(Foo(), 5);
+// EXPECT_EQ(a_pointer, NULL);
// ASSERT_LT(i, array_size);
// ASSERT_GT(records.size(), 0) << "There is no record left.";
#define EXPECT_EQ(val1, val2) \
- EXPECT_PRED_FORMAT2(::testing::internal:: \
- EqHelper<GTEST_IS_NULL_LITERAL_(val1)>::Compare, \
- val1, val2)
+ EXPECT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
#define EXPECT_NE(val1, val2) \
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
#define EXPECT_LE(val1, val2) \
@@ -1935,9 +2038,7 @@
EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2)
#define GTEST_ASSERT_EQ(val1, val2) \
- ASSERT_PRED_FORMAT2(::testing::internal:: \
- EqHelper<GTEST_IS_NULL_LITERAL_(val1)>::Compare, \
- val1, val2)
+ ASSERT_PRED_FORMAT2(::testing::internal::EqHelper::Compare, val1, val2)
#define GTEST_ASSERT_NE(val1, val2) \
ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2)
#define GTEST_ASSERT_LE(val1, val2) \
@@ -2101,6 +2202,51 @@
#define EXPECT_NO_FATAL_FAILURE(statement) \
GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_)
+// Causes a trace (including the given source file path and line number,
+// and the given message) to be included in every test failure message generated
+// by code in the scope of the lifetime of an instance of this class. The effect
+// is undone with the destruction of the instance.
+//
+// The message argument can be anything streamable to std::ostream.
+//
+// Example:
+// testing::ScopedTrace trace("file.cc", 123, "message");
+//
+class GTEST_API_ ScopedTrace {
+ public:
+ // The c'tor pushes the given source file location and message onto
+ // a trace stack maintained by Google Test.
+
+ // Template version. Uses Message() to convert the values into strings.
+ // Slow, but flexible.
+ template <typename T>
+ ScopedTrace(const char* file, int line, const T& message) {
+ PushTrace(file, line, (Message() << message).GetString());
+ }
+
+ // Optimize for some known types.
+ ScopedTrace(const char* file, int line, const char* message) {
+ PushTrace(file, line, message ? message : "(null)");
+ }
+
+ ScopedTrace(const char* file, int line, const std::string& message) {
+ PushTrace(file, line, message);
+ }
+
+ // The d'tor pops the info pushed by the c'tor.
+ //
+ // Note that the d'tor is not virtual in order to be efficient.
+ // Don't inherit from ScopedTrace!
+ ~ScopedTrace();
+
+ private:
+ void PushTrace(const char* file, int line, std::string message);
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
+} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
+ // c'tor and d'tor. Therefore it doesn't
+ // need to be used otherwise.
+
// Causes a trace (including the source file path, the current line
// number, and the given message) to be included in every test failure
// message generated by code in the current scope. The effect is
@@ -2112,13 +2258,17 @@
// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s
// to appear in the same block - as long as they are on different
// lines.
+//
+// Assuming that each thread maintains its own stack of traces.
+// Therefore, a SCOPED_TRACE() would (correctly) only affect the
+// assertions in its own thread.
#define SCOPED_TRACE(message) \
- ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
- __FILE__, __LINE__, ::testing::Message() << (message))
+ ::testing::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\
+ __FILE__, __LINE__, (message))
// Compile-time assertion for type equality.
-// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are
-// the same type. The value it returns is not interesting.
+// StaticAssertTypeEq<type1, type2>() compiles if and only if type1 and type2
+// are the same type. The value it returns is not interesting.
//
// Instead of making StaticAssertTypeEq a class template, we make it a
// function template that invokes a helper class template. This
@@ -2147,18 +2297,19 @@
//
// to cause a compiler error.
template <typename T1, typename T2>
-bool StaticAssertTypeEq() {
- (void)internal::StaticAssertTypeEqHelper<T1, T2>();
+constexpr bool StaticAssertTypeEq() noexcept {
+ static_assert(std::is_same<T1, T2>::value,
+ "type1 and type2 are not the same type");
return true;
}
// Defines a test.
//
-// The first parameter is the name of the test case, and the second
-// parameter is the name of the test within the test case.
+// The first parameter is the name of the test suite, and the second
+// parameter is the name of the test within the test suite.
//
-// The convention is to end the test case name with "Test". For
-// example, a test case for the Foo class can be named FooTest.
+// The convention is to end the test suite name with "Test". For
+// example, a test suite for the Foo class can be named FooTest.
//
// Test code should appear between braces after an invocation of
// this macro. Example:
@@ -2177,28 +2328,28 @@
// code. GetTestTypeId() is guaranteed to always return the same
// value, as it always calls GetTypeId<>() from the Google Test
// framework.
-#define GTEST_TEST(test_case_name, test_name)\
- GTEST_TEST_(test_case_name, test_name, \
- ::testing::Test, ::testing::internal::GetTestTypeId())
+#define GTEST_TEST(test_suite_name, test_name) \
+ GTEST_TEST_(test_suite_name, test_name, ::testing::Test, \
+ ::testing::internal::GetTestTypeId())
// Define this macro to 1 to omit the definition of TEST(), which
// is a generic name and clashes with some other libraries.
#if !GTEST_DONT_DEFINE_TEST
-# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)
+#define TEST(test_suite_name, test_name) GTEST_TEST(test_suite_name, test_name)
#endif
// Defines a test that uses a test fixture.
//
// The first parameter is the name of the test fixture class, which
-// also doubles as the test case name. The second parameter is the
-// name of the test within the test case.
+// also doubles as the test suite name. The second parameter is the
+// name of the test within the test suite.
//
// A test fixture class must be declared earlier. The user should put
-// his test code between braces after using this macro. Example:
+// the test code between braces after using this macro. Example:
//
// class FooTest : public testing::Test {
// protected:
-// virtual void SetUp() { b_.AddElement(3); }
+// void SetUp() override { b_.AddElement(3); }
//
// Foo a_;
// Foo b_;
@@ -2209,14 +2360,103 @@
// }
//
// TEST_F(FooTest, ReturnsElementCountCorrectly) {
-// EXPECT_EQ(0, a_.size());
-// EXPECT_EQ(1, b_.size());
+// EXPECT_EQ(a_.size(), 0);
+// EXPECT_EQ(b_.size(), 1);
// }
-
+//
+// GOOGLETEST_CM0011 DO NOT DELETE
#define TEST_F(test_fixture, test_name)\
GTEST_TEST_(test_fixture, test_name, test_fixture, \
::testing::internal::GetTypeId<test_fixture>())
+// Returns a path to temporary directory.
+// Tries to determine an appropriate directory for the platform.
+GTEST_API_ std::string TempDir();
+
+#ifdef _MSC_VER
+# pragma warning(pop)
+#endif
+
+// Dynamically registers a test with the framework.
+//
+// This is an advanced API only to be used when the `TEST` macros are
+// insufficient. The macros should be preferred when possible, as they avoid
+// most of the complexity of calling this function.
+//
+// The `factory` argument is a factory callable (move-constructible) object or
+// function pointer that creates a new instance of the Test object. It
+// handles ownership to the caller. The signature of the callable is
+// `Fixture*()`, where `Fixture` is the test fixture class for the test. All
+// tests registered with the same `test_suite_name` must return the same
+// fixture type. This is checked at runtime.
+//
+// The framework will infer the fixture class from the factory and will call
+// the `SetUpTestSuite` and `TearDownTestSuite` for it.
+//
+// Must be called before `RUN_ALL_TESTS()` is invoked, otherwise behavior is
+// undefined.
+//
+// Use case example:
+//
+// class MyFixture : public ::testing::Test {
+// public:
+// // All of these optional, just like in regular macro usage.
+// static void SetUpTestSuite() { ... }
+// static void TearDownTestSuite() { ... }
+// void SetUp() override { ... }
+// void TearDown() override { ... }
+// };
+//
+// class MyTest : public MyFixture {
+// public:
+// explicit MyTest(int data) : data_(data) {}
+// void TestBody() override { ... }
+//
+// private:
+// int data_;
+// };
+//
+// void RegisterMyTests(const std::vector<int>& values) {
+// for (int v : values) {
+// ::testing::RegisterTest(
+// "MyFixture", ("Test" + std::to_string(v)).c_str(), nullptr,
+// std::to_string(v).c_str(),
+// __FILE__, __LINE__,
+// // Important to use the fixture type as the return type here.
+// [=]() -> MyFixture* { return new MyTest(v); });
+// }
+// }
+// ...
+// int main(int argc, char** argv) {
+// std::vector<int> values_to_test = LoadValuesFromConfig();
+// RegisterMyTests(values_to_test);
+// ...
+// return RUN_ALL_TESTS();
+// }
+//
+template <int&... ExplicitParameterBarrier, typename Factory>
+TestInfo* RegisterTest(const char* test_suite_name, const char* test_name,
+ const char* type_param, const char* value_param,
+ const char* file, int line, Factory factory) {
+ using TestT = typename std::remove_pointer<decltype(factory())>::type;
+
+ class FactoryImpl : public internal::TestFactoryBase {
+ public:
+ explicit FactoryImpl(Factory f) : factory_(std::move(f)) {}
+ Test* CreateTest() override { return factory_(); }
+
+ private:
+ Factory factory_;
+ };
+
+ return internal::MakeAndRegisterTestInfo(
+ test_suite_name, test_name, type_param, value_param,
+ internal::CodeLocation(file, line), internal::GetTypeId<TestT>(),
+ internal::SuiteApiResolver<TestT>::GetSetUpCaseOrSuite(file, line),
+ internal::SuiteApiResolver<TestT>::GetTearDownCaseOrSuite(file, line),
+ new FactoryImpl{std::move(factory)});
+}
+
} // namespace testing
// Use this function in main() to run all tests. It returns 0 if all
@@ -2233,4 +2473,6 @@
return ::testing::UnitTest::GetInstance()->Run();
}
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
#endif // GTEST_INCLUDE_GTEST_GTEST_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h
index 30ae712..d514255 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_pred_impl.h
@@ -27,18 +27,18 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// This file is AUTOMATICALLY GENERATED on 10/31/2011 by command
+// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
+// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
-// Makes sure this header is not included before gtest.h.
-#ifndef GTEST_INCLUDE_GTEST_GTEST_H_
-# error Do not include gtest_pred_impl.h directly. Include gtest.h instead.
-#endif // GTEST_INCLUDE_GTEST_GTEST_H_
+#include "gtest/gtest.h"
+
+namespace testing {
// This header implements a family of generic predicate assertion
// macros:
@@ -90,9 +90,10 @@
const T1& v1) {
if (pred(v1)) return AssertionSuccess();
- return AssertionFailure() << pred_text << "("
- << e1 << ") evaluates to false, where"
- << "\n" << e1 << " evaluates to " << v1;
+ return AssertionFailure()
+ << pred_text << "(" << e1 << ") evaluates to false, where"
+ << "\n"
+ << e1 << " evaluates to " << ::testing::PrintToString(v1);
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
@@ -134,11 +135,12 @@
const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess();
- return AssertionFailure() << pred_text << "("
- << e1 << ", "
- << e2 << ") evaluates to false, where"
- << "\n" << e1 << " evaluates to " << v1
- << "\n" << e2 << " evaluates to " << v2;
+ return AssertionFailure()
+ << pred_text << "(" << e1 << ", " << e2
+ << ") evaluates to false, where"
+ << "\n"
+ << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+ << e2 << " evaluates to " << ::testing::PrintToString(v2);
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
@@ -185,13 +187,13 @@
const T3& v3) {
if (pred(v1, v2, v3)) return AssertionSuccess();
- return AssertionFailure() << pred_text << "("
- << e1 << ", "
- << e2 << ", "
- << e3 << ") evaluates to false, where"
- << "\n" << e1 << " evaluates to " << v1
- << "\n" << e2 << " evaluates to " << v2
- << "\n" << e3 << " evaluates to " << v3;
+ return AssertionFailure()
+ << pred_text << "(" << e1 << ", " << e2 << ", " << e3
+ << ") evaluates to false, where"
+ << "\n"
+ << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+ << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
+ << e3 << " evaluates to " << ::testing::PrintToString(v3);
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
@@ -243,15 +245,14 @@
const T4& v4) {
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
- return AssertionFailure() << pred_text << "("
- << e1 << ", "
- << e2 << ", "
- << e3 << ", "
- << e4 << ") evaluates to false, where"
- << "\n" << e1 << " evaluates to " << v1
- << "\n" << e2 << " evaluates to " << v2
- << "\n" << e3 << " evaluates to " << v3
- << "\n" << e4 << " evaluates to " << v4;
+ return AssertionFailure()
+ << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
+ << ") evaluates to false, where"
+ << "\n"
+ << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+ << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
+ << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
+ << e4 << " evaluates to " << ::testing::PrintToString(v4);
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
@@ -308,17 +309,15 @@
const T5& v5) {
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
- return AssertionFailure() << pred_text << "("
- << e1 << ", "
- << e2 << ", "
- << e3 << ", "
- << e4 << ", "
- << e5 << ") evaluates to false, where"
- << "\n" << e1 << " evaluates to " << v1
- << "\n" << e2 << " evaluates to " << v2
- << "\n" << e3 << " evaluates to " << v3
- << "\n" << e4 << " evaluates to " << v4
- << "\n" << e5 << " evaluates to " << v5;
+ return AssertionFailure()
+ << pred_text << "(" << e1 << ", " << e2 << ", " << e3 << ", " << e4
+ << ", " << e5 << ") evaluates to false, where"
+ << "\n"
+ << e1 << " evaluates to " << ::testing::PrintToString(v1) << "\n"
+ << e2 << " evaluates to " << ::testing::PrintToString(v2) << "\n"
+ << e3 << " evaluates to " << ::testing::PrintToString(v3) << "\n"
+ << e4 << " evaluates to " << ::testing::PrintToString(v4) << "\n"
+ << e5 << " evaluates to " << ::testing::PrintToString(v5);
}
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
@@ -355,4 +354,6 @@
+} // namespace testing
+
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h
index da80ddc..e651671 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/gtest_prod.h
@@ -26,10 +26,10 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Zhanyong Wan)
-//
-// Google C++ Testing Framework definitions useful in production code.
+// Google C++ Testing and Mocking Framework definitions useful in production code.
+// GOOGLETEST_CM0003 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
@@ -40,17 +40,20 @@
//
// class MyClass {
// private:
-// void MyMethod();
-// FRIEND_TEST(MyClassTest, MyMethod);
+// void PrivateMethod();
+// FRIEND_TEST(MyClassTest, PrivateMethodWorks);
// };
//
// class MyClassTest : public testing::Test {
// // ...
// };
//
-// TEST_F(MyClassTest, MyMethod) {
-// // Can call MyClass::MyMethod() here.
+// TEST_F(MyClassTest, PrivateMethodWorks) {
+// // Can call MyClass::PrivateMethod() here.
// }
+//
+// Note: The test class must be in the same namespace as the class being tested.
+// For example, putting MyClassTest in an anonymous namespace will not work.
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-port.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-port.h
index 7e744bd..cd85d95 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-port.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-port.h
@@ -27,39 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Injection point for custom user configurations.
-// The following macros can be defined:
-//
-// Flag related macros:
-// GTEST_FLAG(flag_name)
-// GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its
-// own flagfile flag parsing.
-// GTEST_DECLARE_bool_(name)
-// GTEST_DECLARE_int32_(name)
-// GTEST_DECLARE_string_(name)
-// GTEST_DEFINE_bool_(name, default_val, doc)
-// GTEST_DEFINE_int32_(name, default_val, doc)
-// GTEST_DEFINE_string_(name, default_val, doc)
-//
-// Test filtering:
-// GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that
-// will be used if --GTEST_FLAG(test_filter)
-// is not provided.
-//
-// Logging:
-// GTEST_LOG_(severity)
-// GTEST_CHECK_(condition)
-// Functions LogToStderr() and FlushInfoLog() have to be provided too.
-//
-// Threading:
-// GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided.
-// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are
-// already provided.
-// Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and
-// GTEST_DEFINE_STATIC_MUTEX_(mutex)
-//
-// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)
-// GTEST_LOCK_EXCLUDED_(locks)
+// Injection point for custom user configurations. See README for details
//
// ** Custom implementation starts here **
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-printers.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-printers.h
index d4ae083..b732092 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-printers.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest-printers.h
@@ -31,8 +31,8 @@
// installation of gTest.
// It will be included from gtest-printers.h and the overrides in this file
// will be visible to everyone.
-// See documentation at gtest/gtest-printers.h for details on how to define a
-// custom printer.
+//
+// Injection point for custom user configurations. See README for details
//
// ** Custom implementation starts here **
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest.h
index c27412a..4c8e07b 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/custom/gtest.h
@@ -27,11 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Injection point for custom user configurations.
-// The following macros can be defined:
-//
-// GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of
-// OsStackTraceGetterInterface.
+// Injection point for custom user configurations. See README for details
//
// ** Custom implementation starts here **
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
index 01b5d5e..12bb050 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-death-test-internal.h
@@ -27,19 +27,20 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Authors: [email protected] (Zhanyong Wan), [email protected] (Sean Mcafee)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice.
+// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
+#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h"
#include <stdio.h>
+#include <memory>
namespace testing {
namespace internal {
@@ -53,6 +54,9 @@
#if GTEST_HAS_DEATH_TEST
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
// DeathTest is a class that hides much of the complexity of the
// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method
// returns a concrete class that depends on the prevailing death test
@@ -76,7 +80,7 @@
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
- static bool Create(const char* statement, const RE* regex,
+ static bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() { }
@@ -136,25 +140,50 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
};
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
public:
virtual ~DeathTestFactory() { }
- virtual bool Create(const char* statement, const RE* regex,
- const char* file, int line, DeathTest** test) = 0;
+ virtual bool Create(const char* statement,
+ Matcher<const std::string&> matcher, const char* file,
+ int line, DeathTest** test) = 0;
};
// A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory {
public:
- virtual bool Create(const char* statement, const RE* regex,
- const char* file, int line, DeathTest** test);
+ bool Create(const char* statement, Matcher<const std::string&> matcher,
+ const char* file, int line, DeathTest** test) override;
};
// Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
+// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
+// and interpreted as a regex (rather than an Eq matcher) for legacy
+// compatibility.
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+ ::testing::internal::RE regex) {
+ return ContainsRegex(regex.pattern());
+}
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
+ return ContainsRegex(regex);
+}
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+ const ::std::string& regex) {
+ return ContainsRegex(regex);
+}
+
+// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
+// used directly.
+inline Matcher<const ::std::string&> MakeDeathTestMatcher(
+ Matcher<const ::std::string&> matcher) {
+ return matcher;
+}
+
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
@@ -182,48 +211,51 @@
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
-# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (::testing::internal::AlwaysTrue()) { \
- const ::testing::internal::RE& gtest_regex = (regex); \
- ::testing::internal::DeathTest* gtest_dt; \
- if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \
- __FILE__, __LINE__, >est_dt)) { \
- goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
- } \
- if (gtest_dt != NULL) { \
- ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
- gtest_dt_ptr(gtest_dt); \
- switch (gtest_dt->AssumeRole()) { \
- case ::testing::internal::DeathTest::OVERSEE_TEST: \
- if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
- goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
- } \
- break; \
- case ::testing::internal::DeathTest::EXECUTE_TEST: { \
- ::testing::internal::DeathTest::ReturnSentinel \
- gtest_sentinel(gtest_dt); \
- GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
- gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
- break; \
- } \
- } \
- } \
- } else \
- GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
- fail(::testing::internal::DeathTest::LastMessage())
+#define GTEST_DEATH_TEST_(statement, predicate, regex_or_matcher, fail) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::AlwaysTrue()) { \
+ ::testing::internal::DeathTest* gtest_dt; \
+ if (!::testing::internal::DeathTest::Create( \
+ #statement, \
+ ::testing::internal::MakeDeathTestMatcher(regex_or_matcher), \
+ __FILE__, __LINE__, >est_dt)) { \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+ } \
+ if (gtest_dt != nullptr) { \
+ std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt); \
+ switch (gtest_dt->AssumeRole()) { \
+ case ::testing::internal::DeathTest::OVERSEE_TEST: \
+ if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
+ goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
+ } \
+ break; \
+ case ::testing::internal::DeathTest::EXECUTE_TEST: { \
+ ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
+ gtest_dt); \
+ GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
+ gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
+ break; \
+ } \
+ } \
+ } \
+ } else \
+ GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
+ : fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message
// can be streamed.
// This macro is for implementing ASSERT/EXPECT_DEBUG_DEATH when compiled in
-// NDEBUG mode. In this case we need the statements to be executed, the regex is
-// ignored, and the macro must accept a streamed message even though the message
-// is never printed.
-# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (::testing::internal::AlwaysTrue()) { \
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
- } else \
+// NDEBUG mode. In this case we need the statements to be executed and the macro
+// must accept a streamed message even though the message is never printed.
+// The regex object is not evaluated, but it is used to prevent "unused"
+// warnings and to avoid an expression that doesn't compile in debug mode.
+#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
+ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
+ if (::testing::internal::AlwaysTrue()) { \
+ GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
+ } else if (!::testing::internal::AlwaysTrue()) { \
+ ::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
+ } else \
::testing::Message()
// A class representing the parsed contents of the
@@ -262,53 +294,6 @@
// the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
-#else // GTEST_HAS_DEATH_TEST
-
-// This macro is used for implementing macros such as
-// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where
-// death tests are not supported. Those macros must compile on such systems
-// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on
-// systems that support death tests. This allows one to write such a macro
-// on a system that does not support death tests and be sure that it will
-// compile on a death-test supporting system.
-//
-// Parameters:
-// statement - A statement that a macro such as EXPECT_DEATH would test
-// for program termination. This macro has to make sure this
-// statement is compiled but not executed, to ensure that
-// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
-// parameter iff EXPECT_DEATH compiles with it.
-// regex - A regex that a macro such as EXPECT_DEATH would use to test
-// the output of statement. This parameter has to be
-// compiled but not evaluated by this macro, to ensure that
-// this macro only accepts expressions that a macro such as
-// EXPECT_DEATH would accept.
-// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED
-// and a return statement for ASSERT_DEATH_IF_SUPPORTED.
-// This ensures that ASSERT_DEATH_IF_SUPPORTED will not
-// compile inside functions where ASSERT_DEATH doesn't
-// compile.
-//
-// The branch that has an always false condition is used to ensure that
-// statement and regex are compiled (and thus syntactically correct) but
-// never executed. The unreachable code macro protects the terminator
-// statement from generating an 'unreachable code' warning in case
-// statement unconditionally returns or throws. The Message constructor at
-// the end allows the syntax of streaming additional messages into the
-// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
-# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
- GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
- if (::testing::internal::AlwaysTrue()) { \
- GTEST_LOG_(WARNING) \
- << "Death tests are not supported on this platform.\n" \
- << "Statement '" #statement "' cannot be verified."; \
- } else if (::testing::internal::AlwaysFalse()) { \
- ::testing::internal::RE::PartialMatch(".*", (regex)); \
- GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
- terminator; \
- } else \
- ::testing::Message()
-
#endif // GTEST_HAS_DEATH_TEST
} // namespace internal
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h
index 1844506..c11b101 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-filepath.h
@@ -27,21 +27,24 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Author: [email protected] (Keith Ray)
-//
// Google Test filepath utilities
//
// This header file declares classes and functions used internally by
// Google Test. They are subject to change without notice.
//
-// This file is #included in <gtest/internal/gtest-internal.h>.
+// This file is #included in gtest/internal/gtest-internal.h.
// Do not include this header file separately!
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include "gtest/internal/gtest-string.h"
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
namespace testing {
namespace internal {
@@ -107,7 +110,7 @@
const FilePath& base_name,
const char* extension);
- // Returns true iff the path is "".
+ // Returns true if and only if the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns
@@ -192,7 +195,7 @@
void Normalize();
- // Returns a pointer to the last occurrence of a valid path separator in
+ // Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
@@ -203,4 +206,6 @@
} // namespace internal
} // namespace testing
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
index ebd1cf6..94c816a 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h
@@ -27,13 +27,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Authors: [email protected] (Zhanyong Wan), [email protected] (Sean Mcafee)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file declares functions and macros used internally by
// Google Test. They are subject to change without notice.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
@@ -58,11 +58,12 @@
#include <map>
#include <set>
#include <string>
+#include <type_traits>
#include <vector>
#include "gtest/gtest-message.h"
-#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-filepath.h"
+#include "gtest/internal/gtest-string.h"
#include "gtest/internal/gtest-type-util.h"
// Due to C++ preprocessor weirdness, we need double indirection to
@@ -76,7 +77,9 @@
#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar)
#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar
-class ProtocolMessage;
+// Stringifies its argument.
+#define GTEST_STRINGIFY_(name) #name
+
namespace proto2 { class Message; }
namespace testing {
@@ -88,7 +91,7 @@
class Test; // Represents a test.
class TestInfo; // Information about a test.
class TestPartResult; // Result of a test part.
-class UnitTest; // A collection of test cases.
+class UnitTest; // A collection of test suites.
template <typename T>
::std::string PrintToString(const T& value);
@@ -96,7 +99,6 @@
namespace internal {
struct TraceInfo; // Information about a trace point.
-class ScopedTrace; // Implements scoped trace.
class TestInfoImpl; // Opaque implementation of TestInfo
class UnitTestImpl; // Opaque implementation of UnitTest
@@ -104,34 +106,22 @@
// stack trace.
GTEST_API_ extern const char kStackTraceMarker[];
-// Two overloaded helpers for checking at compile time whether an
-// expression is a null pointer literal (i.e. NULL or any 0-valued
-// compile-time integral constant). Their return values have
-// different sizes, so we can use sizeof() to test which version is
-// picked by the compiler. These helpers have no implementations, as
-// we only need their signatures.
-//
-// Given IsNullLiteralHelper(x), the compiler will pick the first
-// version if x can be implicitly converted to Secret*, and pick the
-// second version otherwise. Since Secret is a secret and incomplete
-// type, the only expression a user can write that has type Secret* is
-// a null pointer literal. Therefore, we know that x is a null
-// pointer literal if and only if the first version is picked by the
-// compiler.
-char IsNullLiteralHelper(Secret* p);
-char (&IsNullLiteralHelper(...))[2]; // NOLINT
-
-// A compile-time bool constant that is true if and only if x is a
-// null pointer literal (i.e. NULL or any 0-valued compile-time
-// integral constant).
-#ifdef GTEST_ELLIPSIS_NEEDS_POD_
-// We lose support for NULL detection where the compiler doesn't like
-// passing non-POD classes through ellipsis (...).
-# define GTEST_IS_NULL_LITERAL_(x) false
-#else
-# define GTEST_IS_NULL_LITERAL_(x) \
- (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1)
-#endif // GTEST_ELLIPSIS_NEEDS_POD_
+// An IgnoredValue object can be implicitly constructed from ANY value.
+class IgnoredValue {
+ struct Sink {};
+ public:
+ // This constructor template allows any value to be implicitly
+ // converted to IgnoredValue. The object has no data member and
+ // doesn't try to remember anything about the argument. We
+ // deliberately omit the 'explicit' keyword in order to allow the
+ // conversion to be implicit.
+ // Disable the conversion if T already has a magical conversion operator.
+ // Otherwise we get ambiguity.
+ template <typename T,
+ typename std::enable_if<!std::is_convertible<T, Sink>::value,
+ int>::type = 0>
+ IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit)
+};
// Appends the user-supplied message to the Google-Test-generated message.
GTEST_API_ std::string AppendUserMessage(
@@ -139,6 +129,9 @@
#if GTEST_HAS_EXCEPTIONS
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4275 \
+/* an exported class was derived from a class that was not exported */)
+
// This exception is thrown by (and only by) a failed Google Test
// assertion when GTEST_FLAG(throw_on_failure) is true (if exceptions
// are enabled). We derive it from std::runtime_error, which is for
@@ -150,32 +143,15 @@
explicit GoogleTestFailureException(const TestPartResult& failure);
};
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4275
+
#endif // GTEST_HAS_EXCEPTIONS
-// A helper class for creating scoped traces in user programs.
-class GTEST_API_ ScopedTrace {
- public:
- // The c'tor pushes the given source file location and message onto
- // a trace stack maintained by Google Test.
- ScopedTrace(const char* file, int line, const Message& message);
-
- // The d'tor pops the info pushed by the c'tor.
- //
- // Note that the d'tor is not virtual in order to be efficient.
- // Don't inherit from ScopedTrace!
- ~ScopedTrace();
-
- private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace);
-} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its
- // c'tor and d'tor. Therefore it doesn't
- // need to be used otherwise.
-
namespace edit_distance {
// Returns the optimal edits to go from 'left' to 'right'.
// All edits cost the same, with replace having lower priority than
// add/remove.
-// Simple implementation of the Wagner–Fischer algorithm.
+// Simple implementation of the Wagner-Fischer algorithm.
// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm
enum EditType { kMatch, kAdd, kRemove, kReplace };
GTEST_API_ std::vector<EditType> CalculateOptimalEdits(
@@ -213,7 +189,7 @@
// expected_value: "5"
// actual_value: "6"
//
-// The ignoring_case parameter is true iff the assertion is a
+// The ignoring_case parameter is true if and only if the assertion is a
// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will
// be inserted into the message.
GTEST_API_ AssertionResult EqFailure(const char* expected_expression,
@@ -342,15 +318,15 @@
// Returns the sign bit of this number.
Bits sign_bit() const { return kSignBitMask & u_.bits_; }
- // Returns true iff this is NAN (not a number).
+ // Returns true if and only if this is NAN (not a number).
bool is_nan() const {
// It's a NAN if the exponent bits are all ones and the fraction
// bits are not entirely zeros.
return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0);
}
- // Returns true iff this number is at most kMaxUlps ULP's away from
- // rhs. In particular, this function:
+ // Returns true if and only if this number is at most kMaxUlps ULP's away
+ // from rhs. In particular, this function:
//
// - returns false if either number is (or both are) NAN.
// - treats really large numbers as almost equal to infinity.
@@ -421,7 +397,7 @@
typedef FloatingPoint<double> Double;
// In order to catch the mistake of putting tests that use different
-// test fixture classes in the same test case, we need to assign
+// test fixture classes in the same test suite, we need to assign
// unique IDs to fixture classes and compare them. The TypeId type is
// used to hold such IDs. The user should treat TypeId as an opaque
// type: the only operation allowed on TypeId values is to compare
@@ -481,7 +457,7 @@
template <class TestClass>
class TestFactoryImpl : public TestFactoryBase {
public:
- virtual Test* CreateTest() { return new TestClass; }
+ Test* CreateTest() override { return new TestClass; }
};
#if GTEST_OS_WINDOWS
@@ -497,23 +473,76 @@
#endif // GTEST_OS_WINDOWS
-// Types of SetUpTestCase() and TearDownTestCase() functions.
-typedef void (*SetUpTestCaseFunc)();
-typedef void (*TearDownTestCaseFunc)();
+// Types of SetUpTestSuite() and TearDownTestSuite() functions.
+using SetUpTestSuiteFunc = void (*)();
+using TearDownTestSuiteFunc = void (*)();
struct CodeLocation {
- CodeLocation(const string& a_file, int a_line) : file(a_file), line(a_line) {}
+ CodeLocation(const std::string& a_file, int a_line)
+ : file(a_file), line(a_line) {}
- string file;
+ std::string file;
int line;
};
+// Helper to identify which setup function for TestCase / TestSuite to call.
+// Only one function is allowed, either TestCase or TestSute but not both.
+
+// Utility functions to help SuiteApiResolver
+using SetUpTearDownSuiteFuncType = void (*)();
+
+inline SetUpTearDownSuiteFuncType GetNotDefaultOrNull(
+ SetUpTearDownSuiteFuncType a, SetUpTearDownSuiteFuncType def) {
+ return a == def ? nullptr : a;
+}
+
+template <typename T>
+// Note that SuiteApiResolver inherits from T because
+// SetUpTestSuite()/TearDownTestSuite() could be protected. Ths way
+// SuiteApiResolver can access them.
+struct SuiteApiResolver : T {
+ // testing::Test is only forward declared at this point. So we make it a
+ // dependend class for the compiler to be OK with it.
+ using Test =
+ typename std::conditional<sizeof(T) != 0, ::testing::Test, void>::type;
+
+ static SetUpTearDownSuiteFuncType GetSetUpCaseOrSuite(const char* filename,
+ int line_num) {
+ SetUpTearDownSuiteFuncType test_case_fp =
+ GetNotDefaultOrNull(&T::SetUpTestCase, &Test::SetUpTestCase);
+ SetUpTearDownSuiteFuncType test_suite_fp =
+ GetNotDefaultOrNull(&T::SetUpTestSuite, &Test::SetUpTestSuite);
+
+ GTEST_CHECK_(!test_case_fp || !test_suite_fp)
+ << "Test can not provide both SetUpTestSuite and SetUpTestCase, please "
+ "make sure there is only one present at "
+ << filename << ":" << line_num;
+
+ return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
+ }
+
+ static SetUpTearDownSuiteFuncType GetTearDownCaseOrSuite(const char* filename,
+ int line_num) {
+ SetUpTearDownSuiteFuncType test_case_fp =
+ GetNotDefaultOrNull(&T::TearDownTestCase, &Test::TearDownTestCase);
+ SetUpTearDownSuiteFuncType test_suite_fp =
+ GetNotDefaultOrNull(&T::TearDownTestSuite, &Test::TearDownTestSuite);
+
+ GTEST_CHECK_(!test_case_fp || !test_suite_fp)
+ << "Test can not provide both TearDownTestSuite and TearDownTestCase,"
+ " please make sure there is only one present at"
+ << filename << ":" << line_num;
+
+ return test_case_fp != nullptr ? test_case_fp : test_suite_fp;
+ }
+};
+
// Creates a new TestInfo object and registers it with Google Test;
// returns the created object.
//
// Arguments:
//
-// test_case_name: name of the test case
+// test_suite_name: name of the test suite
// name: name of the test
// type_param the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
@@ -521,21 +550,16 @@
// or NULL if this is not a type-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class
-// set_up_tc: pointer to the function that sets up the test case
-// tear_down_tc: pointer to the function that tears down the test case
+// set_up_tc: pointer to the function that sets up the test suite
+// tear_down_tc: pointer to the function that tears down the test suite
// factory: pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume
// ownership of the factory object.
GTEST_API_ TestInfo* MakeAndRegisterTestInfo(
- const char* test_case_name,
- const char* name,
- const char* type_param,
- const char* value_param,
- CodeLocation code_location,
- TypeId fixture_class_id,
- SetUpTestCaseFunc set_up_tc,
- TearDownTestCaseFunc tear_down_tc,
- TestFactoryBase* factory);
+ const char* test_suite_name, const char* name, const char* type_param,
+ const char* value_param, CodeLocation code_location,
+ TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
+ TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory);
// If *pstr starts with the given prefix, modifies *pstr to be right
// past the prefix and returns true; otherwise leaves *pstr unchanged
@@ -544,19 +568,23 @@
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
-// State of the definition of a type-parameterized test case.
-class GTEST_API_ TypedTestCasePState {
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
+// State of the definition of a type-parameterized test suite.
+class GTEST_API_ TypedTestSuitePState {
public:
- TypedTestCasePState() : registered_(false) {}
+ TypedTestSuitePState() : registered_(false) {}
// Adds the given test name to defined_test_names_ and return true
- // if the test case hasn't been registered; otherwise aborts the
+ // if the test suite hasn't been registered; otherwise aborts the
// program.
bool AddTestName(const char* file, int line, const char* case_name,
const char* test_name) {
if (registered_) {
- fprintf(stderr, "%s Test %s must be defined before "
- "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n",
+ fprintf(stderr,
+ "%s Test %s must be defined before "
+ "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n",
FormatFileLocation(file, line).c_str(), test_name, case_name);
fflush(stderr);
posix::Abort();
@@ -589,12 +617,19 @@
RegisteredTestsMap registered_tests_;
};
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+using TypedTestCasePState = TypedTestSuitePState;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
// Skips to the first non-space char after the first comma in 'str';
// returns NULL if no comma is found in 'str'.
inline const char* SkipComma(const char* str) {
const char* comma = strchr(str, ',');
- if (comma == NULL) {
- return NULL;
+ if (comma == nullptr) {
+ return nullptr;
}
while (IsSpace(*(++comma))) {}
return comma;
@@ -604,7 +639,7 @@
// the entire string if it contains no comma.
inline std::string GetPrefixUntilComma(const char* str) {
const char* comma = strchr(str, ',');
- return comma == NULL ? str : std::string(str, comma);
+ return comma == nullptr ? str : std::string(str, comma);
}
// Splits a given string on a given delimiter, populating a given
@@ -612,6 +647,37 @@
void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest);
+// The default argument to the template below for the case when the user does
+// not provide a name generator.
+struct DefaultNameGenerator {
+ template <typename T>
+ static std::string GetName(int i) {
+ return StreamableToString(i);
+ }
+};
+
+template <typename Provided = DefaultNameGenerator>
+struct NameGeneratorSelector {
+ typedef Provided type;
+};
+
+template <typename NameGenerator>
+void GenerateNamesRecursively(Types0, std::vector<std::string>*, int) {}
+
+template <typename NameGenerator, typename Types>
+void GenerateNamesRecursively(Types, std::vector<std::string>* result, int i) {
+ result->push_back(NameGenerator::template GetName<typename Types::Head>(i));
+ GenerateNamesRecursively<NameGenerator>(typename Types::Tail(), result,
+ i + 1);
+}
+
+template <typename NameGenerator, typename Types>
+std::vector<std::string> GenerateNames() {
+ std::vector<std::string> result;
+ GenerateNamesRecursively<NameGenerator>(Types(), &result, 0);
+ return result;
+}
+
// TypeParameterizedTest<Fixture, TestSel, Types>::Register()
// registers a list of type-parameterized tests with Google Test. The
// return value is insignificant - we just need to return something
@@ -623,13 +689,13 @@
class TypeParameterizedTest {
public:
// 'index' is the index of the test in the type list 'Types'
- // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase,
+ // specified in INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, TestSuite,
// Types). Valid values for 'index' are [0, N - 1] where N is the
// length of Types.
- static bool Register(const char* prefix,
- CodeLocation code_location,
- const char* case_name, const char* test_names,
- int index) {
+ static bool Register(const char* prefix, const CodeLocation& code_location,
+ const char* case_name, const char* test_names, int index,
+ const std::vector<std::string>& type_names =
+ GenerateNames<DefaultNameGenerator, Types>()) {
typedef typename Types::Head Type;
typedef Fixture<Type> FixtureClass;
typedef typename GTEST_BIND_(TestSel, Type) TestClass;
@@ -637,20 +703,27 @@
// First, registers the first type-parameterized test in the type
// list.
MakeAndRegisterTestInfo(
- (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/"
- + StreamableToString(index)).c_str(),
+ (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name +
+ "/" + type_names[static_cast<size_t>(index)])
+ .c_str(),
StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(),
GetTypeName<Type>().c_str(),
- NULL, // No value parameter.
- code_location,
- GetTypeId<FixtureClass>(),
- TestClass::SetUpTestCase,
- TestClass::TearDownTestCase,
+ nullptr, // No value parameter.
+ code_location, GetTypeId<FixtureClass>(),
+ SuiteApiResolver<TestClass>::GetSetUpCaseOrSuite(
+ code_location.file.c_str(), code_location.line),
+ SuiteApiResolver<TestClass>::GetTearDownCaseOrSuite(
+ code_location.file.c_str(), code_location.line),
new TestFactoryImpl<TestClass>);
// Next, recurses (at compile time) with the tail of the type list.
- return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail>
- ::Register(prefix, code_location, case_name, test_names, index + 1);
+ return TypeParameterizedTest<Fixture, TestSel,
+ typename Types::Tail>::Register(prefix,
+ code_location,
+ case_name,
+ test_names,
+ index + 1,
+ type_names);
}
};
@@ -658,23 +731,27 @@
template <GTEST_TEMPLATE_ Fixture, class TestSel>
class TypeParameterizedTest<Fixture, TestSel, Types0> {
public:
- static bool Register(const char* /*prefix*/, CodeLocation,
+ static bool Register(const char* /*prefix*/, const CodeLocation&,
const char* /*case_name*/, const char* /*test_names*/,
- int /*index*/) {
+ int /*index*/,
+ const std::vector<std::string>& =
+ std::vector<std::string>() /*type_names*/) {
return true;
}
};
-// TypeParameterizedTestCase<Fixture, Tests, Types>::Register()
+// TypeParameterizedTestSuite<Fixture, Tests, Types>::Register()
// registers *all combinations* of 'Tests' and 'Types' with Google
// Test. The return value is insignificant - we just need to return
// something such that we can call this function in a namespace scope.
template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types>
-class TypeParameterizedTestCase {
+class TypeParameterizedTestSuite {
public:
static bool Register(const char* prefix, CodeLocation code_location,
- const TypedTestCasePState* state,
- const char* case_name, const char* test_names) {
+ const TypedTestSuitePState* state, const char* case_name,
+ const char* test_names,
+ const std::vector<std::string>& type_names =
+ GenerateNames<DefaultNameGenerator, Types>()) {
std::string test_name = StripTrailingSpaces(
GetPrefixUntilComma(test_names));
if (!state->TestExists(test_name)) {
@@ -691,22 +768,26 @@
// First, register the first test in 'Test' for each type in 'Types'.
TypeParameterizedTest<Fixture, Head, Types>::Register(
- prefix, test_location, case_name, test_names, 0);
+ prefix, test_location, case_name, test_names, 0, type_names);
// Next, recurses (at compile time) with the tail of the test list.
- return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types>
- ::Register(prefix, code_location, state,
- case_name, SkipComma(test_names));
+ return TypeParameterizedTestSuite<Fixture, typename Tests::Tail,
+ Types>::Register(prefix, code_location,
+ state, case_name,
+ SkipComma(test_names),
+ type_names);
}
};
// The base case for the compile time recursion.
template <GTEST_TEMPLATE_ Fixture, typename Types>
-class TypeParameterizedTestCase<Fixture, Templates0, Types> {
+class TypeParameterizedTestSuite<Fixture, Templates0, Types> {
public:
- static bool Register(const char* /*prefix*/, CodeLocation,
- const TypedTestCasePState* /*state*/,
- const char* /*case_name*/, const char* /*test_names*/) {
+ static bool Register(const char* /*prefix*/, const CodeLocation&,
+ const TypedTestSuitePState* /*state*/,
+ const char* /*case_name*/, const char* /*test_names*/,
+ const std::vector<std::string>& =
+ std::vector<std::string>() /*type_names*/) {
return true;
}
};
@@ -766,145 +847,16 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(Random);
};
-// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a
-// compiler error iff T1 and T2 are different types.
-template <typename T1, typename T2>
-struct CompileAssertTypesEqual;
-
-template <typename T>
-struct CompileAssertTypesEqual<T, T> {
-};
-
-// Removes the reference from a type if it is a reference type,
-// otherwise leaves it unchanged. This is the same as
-// tr1::remove_reference, which is not widely available yet.
-template <typename T>
-struct RemoveReference { typedef T type; }; // NOLINT
-template <typename T>
-struct RemoveReference<T&> { typedef T type; }; // NOLINT
-
-// A handy wrapper around RemoveReference that works when the argument
-// T depends on template parameters.
-#define GTEST_REMOVE_REFERENCE_(T) \
- typename ::testing::internal::RemoveReference<T>::type
-
-// Removes const from a type if it is a const type, otherwise leaves
-// it unchanged. This is the same as tr1::remove_const, which is not
-// widely available yet.
-template <typename T>
-struct RemoveConst { typedef T type; }; // NOLINT
-template <typename T>
-struct RemoveConst<const T> { typedef T type; }; // NOLINT
-
-// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above
-// definition to fail to remove the const in 'const int[3]' and 'const
-// char[3][4]'. The following specialization works around the bug.
-template <typename T, size_t N>
-struct RemoveConst<const T[N]> {
- typedef typename RemoveConst<T>::type type[N];
-};
-
-#if defined(_MSC_VER) && _MSC_VER < 1400
-// This is the only specialization that allows VC++ 7.1 to remove const in
-// 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC
-// and thus needs to be conditionally compiled.
-template <typename T, size_t N>
-struct RemoveConst<T[N]> {
- typedef typename RemoveConst<T>::type type[N];
-};
-#endif
-
-// A handy wrapper around RemoveConst that works when the argument
-// T depends on template parameters.
-#define GTEST_REMOVE_CONST_(T) \
- typename ::testing::internal::RemoveConst<T>::type
-
// Turns const U&, U&, const U, and U all into U.
#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \
- GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T))
-
-// Adds reference to a type if it is not a reference type,
-// otherwise leaves it unchanged. This is the same as
-// tr1::add_reference, which is not widely available yet.
-template <typename T>
-struct AddReference { typedef T& type; }; // NOLINT
-template <typename T>
-struct AddReference<T&> { typedef T& type; }; // NOLINT
-
-// A handy wrapper around AddReference that works when the argument T
-// depends on template parameters.
-#define GTEST_ADD_REFERENCE_(T) \
- typename ::testing::internal::AddReference<T>::type
-
-// Adds a reference to const on top of T as necessary. For example,
-// it transforms
-//
-// char ==> const char&
-// const char ==> const char&
-// char& ==> const char&
-// const char& ==> const char&
-//
-// The argument T must depend on some template parameters.
-#define GTEST_REFERENCE_TO_CONST_(T) \
- GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T))
-
-// ImplicitlyConvertible<From, To>::value is a compile-time bool
-// constant that's true iff type From can be implicitly converted to
-// type To.
-template <typename From, typename To>
-class ImplicitlyConvertible {
- private:
- // We need the following helper functions only for their types.
- // They have no implementations.
-
- // MakeFrom() is an expression whose type is From. We cannot simply
- // use From(), as the type From may not have a public default
- // constructor.
- static typename AddReference<From>::type MakeFrom();
-
- // These two functions are overloaded. Given an expression
- // Helper(x), the compiler will pick the first version if x can be
- // implicitly converted to type To; otherwise it will pick the
- // second version.
- //
- // The first version returns a value of size 1, and the second
- // version returns a value of size 2. Therefore, by checking the
- // size of Helper(x), which can be done at compile time, we can tell
- // which version of Helper() is used, and hence whether x can be
- // implicitly converted to type To.
- static char Helper(To);
- static char (&Helper(...))[2]; // NOLINT
-
- // We have to put the 'public' section after the 'private' section,
- // or MSVC refuses to compile the code.
- public:
-#if defined(__BORLANDC__)
- // C++Builder cannot use member overload resolution during template
- // instantiation. The simplest workaround is to use its C++0x type traits
- // functions (C++Builder 2009 and above only).
- static const bool value = __is_convertible(From, To);
-#else
- // MSVC warns about implicitly converting from double to int for
- // possible loss of data, so we need to temporarily disable the
- // warning.
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244)
- static const bool value =
- sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
- GTEST_DISABLE_MSC_WARNINGS_POP_()
-#endif // __BORLANDC__
-};
-template <typename From, typename To>
-const bool ImplicitlyConvertible<From, To>::value;
+ typename std::remove_const<typename std::remove_reference<T>::type>::type
// IsAProtocolMessage<T>::value is a compile-time bool constant that's
-// true iff T is type ProtocolMessage, proto2::Message, or a subclass
-// of those.
+// true if and only if T is type proto2::Message or a subclass of it.
template <typename T>
struct IsAProtocolMessage
: public bool_constant<
- ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value ||
- ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> {
-};
+ std::is_convertible<const T*, const ::proto2::Message*>::value> {};
// When the compiler sees expression IsContainerTest<C>(0), if C is an
// STL-style container class, the first overload of IsContainerTest
@@ -917,8 +869,11 @@
// a container class by checking the type of IsContainerTest<C>(0).
// The value of the expression is insignificant.
//
-// Note that we look for both C::iterator and C::const_iterator. The
-// reason is that C++ injects the name of a class as a member of the
+// In C++11 mode we check the existence of a const_iterator and that an
+// iterator is properly implemented for the container.
+//
+// For pre-C++11 that we look for both C::iterator and C::const_iterator.
+// The reason is that C++ injects the name of a class as a member of the
// class itself (e.g. you can refer to class iterator as either
// 'iterator' or 'iterator::iterator'). If we look for C::iterator
// only, for example, we would mistakenly think that a class named
@@ -928,10 +883,13 @@
// IsContainerTest(typename C::const_iterator*) and
// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++.
typedef int IsContainer;
-template <class C>
-IsContainer IsContainerTest(int /* dummy */,
- typename C::iterator* /* it */ = NULL,
- typename C::const_iterator* /* const_it */ = NULL) {
+template <class C,
+ class Iterator = decltype(::std::declval<const C&>().begin()),
+ class = decltype(::std::declval<const C&>().end()),
+ class = decltype(++::std::declval<Iterator&>()),
+ class = decltype(*::std::declval<Iterator>()),
+ class = typename C::const_iterator>
+IsContainer IsContainerTest(int /* dummy */) {
return 0;
}
@@ -939,12 +897,55 @@
template <class C>
IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; }
-// EnableIf<condition>::type is void when 'Cond' is true, and
-// undefined when 'Cond' is false. To use SFINAE to make a function
-// overload only apply when a particular expression is true, add
-// "typename EnableIf<expression>::type* = 0" as the last parameter.
-template<bool> struct EnableIf;
-template<> struct EnableIf<true> { typedef void type; }; // NOLINT
+// Trait to detect whether a type T is a hash table.
+// The heuristic used is that the type contains an inner type `hasher` and does
+// not contain an inner type `reverse_iterator`.
+// If the container is iterable in reverse, then order might actually matter.
+template <typename T>
+struct IsHashTable {
+ private:
+ template <typename U>
+ static char test(typename U::hasher*, typename U::reverse_iterator*);
+ template <typename U>
+ static int test(typename U::hasher*, ...);
+ template <typename U>
+ static char test(...);
+
+ public:
+ static const bool value = sizeof(test<T>(nullptr, nullptr)) == sizeof(int);
+};
+
+template <typename T>
+const bool IsHashTable<T>::value;
+
+template <typename C,
+ bool = sizeof(IsContainerTest<C>(0)) == sizeof(IsContainer)>
+struct IsRecursiveContainerImpl;
+
+template <typename C>
+struct IsRecursiveContainerImpl<C, false> : public std::false_type {};
+
+// Since the IsRecursiveContainerImpl depends on the IsContainerTest we need to
+// obey the same inconsistencies as the IsContainerTest, namely check if
+// something is a container is relying on only const_iterator in C++11 and
+// is relying on both const_iterator and iterator otherwise
+template <typename C>
+struct IsRecursiveContainerImpl<C, true> {
+ using value_type = decltype(*std::declval<typename C::const_iterator>());
+ using type =
+ std::is_same<typename std::remove_const<
+ typename std::remove_reference<value_type>::type>::type,
+ C>;
+};
+
+// IsRecursiveContainer<Type> is a unary compile-time predicate that
+// evaluates whether C is a recursive container type. A recursive container
+// type is a container type whose value_type is equal to the container type
+// itself. An example for a recursive container type is
+// boost::filesystem::path, whose iterator has a value_type that is equal to
+// boost::filesystem::path.
+template <typename C>
+struct IsRecursiveContainer : public IsRecursiveContainerImpl<C>::type {};
// Utilities for native arrays.
@@ -1068,10 +1069,9 @@
}
private:
- enum {
- kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper<
- Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value,
- };
+ static_assert(!std::is_const<Element>::value, "Type must not be const");
+ static_assert(!std::is_reference<Element>::value,
+ "Type must not be a reference");
// Initializes this object with a copy of the input.
void InitCopy(const Element* array, size_t a_size) {
@@ -1096,6 +1096,139 @@
GTEST_DISALLOW_ASSIGN_(NativeArray);
};
+// Backport of std::index_sequence.
+template <size_t... Is>
+struct IndexSequence {
+ using type = IndexSequence;
+};
+
+// Double the IndexSequence, and one if plus_one is true.
+template <bool plus_one, typename T, size_t sizeofT>
+struct DoubleSequence;
+template <size_t... I, size_t sizeofT>
+struct DoubleSequence<true, IndexSequence<I...>, sizeofT> {
+ using type = IndexSequence<I..., (sizeofT + I)..., 2 * sizeofT>;
+};
+template <size_t... I, size_t sizeofT>
+struct DoubleSequence<false, IndexSequence<I...>, sizeofT> {
+ using type = IndexSequence<I..., (sizeofT + I)...>;
+};
+
+// Backport of std::make_index_sequence.
+// It uses O(ln(N)) instantiation depth.
+template <size_t N>
+struct MakeIndexSequence
+ : DoubleSequence<N % 2 == 1, typename MakeIndexSequence<N / 2>::type,
+ N / 2>::type {};
+
+template <>
+struct MakeIndexSequence<0> : IndexSequence<> {};
+
+// FIXME: This implementation of ElemFromList is O(1) in instantiation depth,
+// but it is O(N^2) in total instantiations. Not sure if this is the best
+// tradeoff, as it will make it somewhat slow to compile.
+template <typename T, size_t, size_t>
+struct ElemFromListImpl {};
+
+template <typename T, size_t I>
+struct ElemFromListImpl<T, I, I> {
+ using type = T;
+};
+
+// Get the Nth element from T...
+// It uses O(1) instantiation depth.
+template <size_t N, typename I, typename... T>
+struct ElemFromList;
+
+template <size_t N, size_t... I, typename... T>
+struct ElemFromList<N, IndexSequence<I...>, T...>
+ : ElemFromListImpl<T, N, I>... {};
+
+template <typename... T>
+class FlatTuple;
+
+template <typename Derived, size_t I>
+struct FlatTupleElemBase;
+
+template <typename... T, size_t I>
+struct FlatTupleElemBase<FlatTuple<T...>, I> {
+ using value_type =
+ typename ElemFromList<I, typename MakeIndexSequence<sizeof...(T)>::type,
+ T...>::type;
+ FlatTupleElemBase() = default;
+ explicit FlatTupleElemBase(value_type t) : value(std::move(t)) {}
+ value_type value;
+};
+
+template <typename Derived, typename Idx>
+struct FlatTupleBase;
+
+template <size_t... Idx, typename... T>
+struct FlatTupleBase<FlatTuple<T...>, IndexSequence<Idx...>>
+ : FlatTupleElemBase<FlatTuple<T...>, Idx>... {
+ using Indices = IndexSequence<Idx...>;
+ FlatTupleBase() = default;
+ explicit FlatTupleBase(T... t)
+ : FlatTupleElemBase<FlatTuple<T...>, Idx>(std::move(t))... {}
+};
+
+// Analog to std::tuple but with different tradeoffs.
+// This class minimizes the template instantiation depth, thus allowing more
+// elements that std::tuple would. std::tuple has been seen to require an
+// instantiation depth of more than 10x the number of elements in some
+// implementations.
+// FlatTuple and ElemFromList are not recursive and have a fixed depth
+// regardless of T...
+// MakeIndexSequence, on the other hand, it is recursive but with an
+// instantiation depth of O(ln(N)).
+template <typename... T>
+class FlatTuple
+ : private FlatTupleBase<FlatTuple<T...>,
+ typename MakeIndexSequence<sizeof...(T)>::type> {
+ using Indices = typename FlatTuple::FlatTupleBase::Indices;
+
+ public:
+ FlatTuple() = default;
+ explicit FlatTuple(T... t) : FlatTuple::FlatTupleBase(std::move(t)...) {}
+
+ template <size_t I>
+ const typename ElemFromList<I, Indices, T...>::type& Get() const {
+ return static_cast<const FlatTupleElemBase<FlatTuple, I>*>(this)->value;
+ }
+
+ template <size_t I>
+ typename ElemFromList<I, Indices, T...>::type& Get() {
+ return static_cast<FlatTupleElemBase<FlatTuple, I>*>(this)->value;
+ }
+};
+
+// Utility functions to be called with static_assert to induce deprecation
+// warnings.
+GTEST_INTERNAL_DEPRECATED(
+ "INSTANTIATE_TEST_CASE_P is deprecated, please use "
+ "INSTANTIATE_TEST_SUITE_P")
+constexpr bool InstantiateTestCase_P_IsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+ "TYPED_TEST_CASE_P is deprecated, please use "
+ "TYPED_TEST_SUITE_P")
+constexpr bool TypedTestCase_P_IsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+ "TYPED_TEST_CASE is deprecated, please use "
+ "TYPED_TEST_SUITE")
+constexpr bool TypedTestCaseIsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+ "REGISTER_TYPED_TEST_CASE_P is deprecated, please use "
+ "REGISTER_TYPED_TEST_SUITE_P")
+constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
+
+GTEST_INTERNAL_DEPRECATED(
+ "INSTANTIATE_TYPED_TEST_CASE_P is deprecated, please use "
+ "INSTANTIATE_TYPED_TEST_SUITE_P")
+constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
+
} // namespace internal
} // namespace testing
@@ -1115,7 +1248,10 @@
#define GTEST_SUCCESS_(message) \
GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess)
-// Suppresses MSVC warnings 4072 (unreachable code) for the code following
+#define GTEST_SKIP_(message) \
+ return GTEST_MESSAGE_(message, ::testing::TestPartResult::kSkip)
+
+// Suppress MSVC warning 4072 (unreachable code) for the code following
// statement if it returns or throws (or doesn't return or throw in some
// situations).
#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \
@@ -1207,32 +1343,38 @@
" Actual: it does.")
// Expands to the name of the class that implements the given test.
-#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \
- test_case_name##_##test_name##_Test
+#define GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ test_suite_name##_##test_name##_Test
// Helper macro for defining tests.
-#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
-class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
- public:\
- GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
- private:\
- virtual void TestBody();\
- static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
- GTEST_DISALLOW_COPY_AND_ASSIGN_(\
- GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
-};\
-\
-::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
- ::test_info_ =\
- ::testing::internal::MakeAndRegisterTestInfo(\
- #test_case_name, #test_name, NULL, NULL, \
- ::testing::internal::CodeLocation(__FILE__, __LINE__), \
- (parent_id), \
- parent_class::SetUpTestCase, \
- parent_class::TearDownTestCase, \
- new ::testing::internal::TestFactoryImpl<\
- GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
-void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()
+#define GTEST_TEST_(test_suite_name, test_name, parent_class, parent_id) \
+ static_assert(sizeof(GTEST_STRINGIFY_(test_suite_name)) > 1, \
+ "test_suite_name must not be empty"); \
+ static_assert(sizeof(GTEST_STRINGIFY_(test_name)) > 1, \
+ "test_name must not be empty"); \
+ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
+ : public parent_class { \
+ public: \
+ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
+ \
+ private: \
+ virtual void TestBody(); \
+ static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
+ test_name)); \
+ }; \
+ \
+ ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_suite_name, \
+ test_name)::test_info_ = \
+ ::testing::internal::MakeAndRegisterTestInfo( \
+ #test_suite_name, #test_name, nullptr, nullptr, \
+ ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
+ ::testing::internal::SuiteApiResolver< \
+ parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
+ ::testing::internal::SuiteApiResolver< \
+ parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
+ new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
+ test_suite_name, test_name)>); \
+ void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
-
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h
deleted file mode 100644
index 3602942..0000000
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-linked_ptr.h
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2003 Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: Dan Egnor ([email protected])
-//
-// A "smart" pointer type with reference tracking. Every pointer to a
-// particular object is kept on a circular linked list. When the last pointer
-// to an object is destroyed or reassigned, the object is deleted.
-//
-// Used properly, this deletes the object when the last reference goes away.
-// There are several caveats:
-// - Like all reference counting schemes, cycles lead to leaks.
-// - Each smart pointer is actually two pointers (8 bytes instead of 4).
-// - Every time a pointer is assigned, the entire list of pointers to that
-// object is traversed. This class is therefore NOT SUITABLE when there
-// will often be more than two or three pointers to a particular object.
-// - References are only tracked as long as linked_ptr<> objects are copied.
-// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS
-// will happen (double deletion).
-//
-// A good use of this class is storing object references in STL containers.
-// You can safely put linked_ptr<> in a vector<>.
-// Other uses may not be as good.
-//
-// Note: If you use an incomplete type with linked_ptr<>, the class
-// *containing* linked_ptr<> must have a constructor and destructor (even
-// if they do nothing!).
-//
-// Bill Gibbons suggested we use something like this.
-//
-// Thread Safety:
-// Unlike other linked_ptr implementations, in this implementation
-// a linked_ptr object is thread-safe in the sense that:
-// - it's safe to copy linked_ptr objects concurrently,
-// - it's safe to copy *from* a linked_ptr and read its underlying
-// raw pointer (e.g. via get()) concurrently, and
-// - it's safe to write to two linked_ptrs that point to the same
-// shared object concurrently.
-// TODO([email protected]): rename this to safe_linked_ptr to avoid
-// confusion with normal linked_ptr.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
-
-#include <stdlib.h>
-#include <assert.h>
-
-#include "gtest/internal/gtest-port.h"
-
-namespace testing {
-namespace internal {
-
-// Protects copying of all linked_ptr objects.
-GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
-
-// This is used internally by all instances of linked_ptr<>. It needs to be
-// a non-template class because different types of linked_ptr<> can refer to
-// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)).
-// So, it needs to be possible for different types of linked_ptr to participate
-// in the same circular linked list, so we need a single class type here.
-//
-// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
-class linked_ptr_internal {
- public:
- // Create a new circle that includes only this instance.
- void join_new() {
- next_ = this;
- }
-
- // Many linked_ptr operations may change p.link_ for some linked_ptr
- // variable p in the same circle as this object. Therefore we need
- // to prevent two such operations from occurring concurrently.
- //
- // Note that different types of linked_ptr objects can coexist in a
- // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
- // linked_ptr<Derived2>). Therefore we must use a single mutex to
- // protect all linked_ptr objects. This can create serious
- // contention in production code, but is acceptable in a testing
- // framework.
-
- // Join an existing circle.
- void join(linked_ptr_internal const* ptr)
- GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
- MutexLock lock(&g_linked_ptr_mutex);
-
- linked_ptr_internal const* p = ptr;
- while (p->next_ != ptr) {
- assert(p->next_ != this &&
- "Trying to join() a linked ring we are already in. "
- "Is GMock thread safety enabled?");
- p = p->next_;
- }
- p->next_ = this;
- next_ = ptr;
- }
-
- // Leave whatever circle we're part of. Returns true if we were the
- // last member of the circle. Once this is done, you can join() another.
- bool depart()
- GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
- MutexLock lock(&g_linked_ptr_mutex);
-
- if (next_ == this) return true;
- linked_ptr_internal const* p = next_;
- while (p->next_ != this) {
- assert(p->next_ != next_ &&
- "Trying to depart() a linked ring we are not in. "
- "Is GMock thread safety enabled?");
- p = p->next_;
- }
- p->next_ = next_;
- return false;
- }
-
- private:
- mutable linked_ptr_internal const* next_;
-};
-
-template <typename T>
-class linked_ptr {
- public:
- typedef T element_type;
-
- // Take over ownership of a raw pointer. This should happen as soon as
- // possible after the object is created.
- explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
- ~linked_ptr() { depart(); }
-
- // Copy an existing linked_ptr<>, adding ourselves to the list of references.
- template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
- linked_ptr(linked_ptr const& ptr) { // NOLINT
- assert(&ptr != this);
- copy(&ptr);
- }
-
- // Assignment releases the old value and acquires the new.
- template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
- depart();
- copy(&ptr);
- return *this;
- }
-
- linked_ptr& operator=(linked_ptr const& ptr) {
- if (&ptr != this) {
- depart();
- copy(&ptr);
- }
- return *this;
- }
-
- // Smart pointer members.
- void reset(T* ptr = NULL) {
- depart();
- capture(ptr);
- }
- T* get() const { return value_; }
- T* operator->() const { return value_; }
- T& operator*() const { return *value_; }
-
- bool operator==(T* p) const { return value_ == p; }
- bool operator!=(T* p) const { return value_ != p; }
- template <typename U>
- bool operator==(linked_ptr<U> const& ptr) const {
- return value_ == ptr.get();
- }
- template <typename U>
- bool operator!=(linked_ptr<U> const& ptr) const {
- return value_ != ptr.get();
- }
-
- private:
- template <typename U>
- friend class linked_ptr;
-
- T* value_;
- linked_ptr_internal link_;
-
- void depart() {
- if (link_.depart()) delete value_;
- }
-
- void capture(T* ptr) {
- value_ = ptr;
- link_.join_new();
- }
-
- template <typename U> void copy(linked_ptr<U> const* ptr) {
- value_ = ptr->get();
- if (value_)
- link_.join(&ptr->link_);
- else
- link_.join_new();
- }
-};
-
-template<typename T> inline
-bool operator==(T* ptr, const linked_ptr<T>& x) {
- return ptr == x.get();
-}
-
-template<typename T> inline
-bool operator!=(T* ptr, const linked_ptr<T>& x) {
- return ptr != x.get();
-}
-
-// A function to convert T* into linked_ptr<T>
-// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
-// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
-template <typename T>
-linked_ptr<T> make_linked_ptr(T* ptr) {
- return linked_ptr<T>(ptr);
-}
-
-} // namespace internal
-} // namespace testing
-
-#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h
deleted file mode 100644
index f6b8429..0000000
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util-generated.h
+++ /dev/null
@@ -1,5146 +0,0 @@
-// This file was GENERATED by command:
-// pump.py gtest-param-util-generated.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 2008 Google Inc.
-// All Rights Reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Vlad Losev)
-
-// Type and function utilities for implementing parameterized tests.
-// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
-//
-// Currently Google Test supports at most 50 arguments in Values,
-// and at most 10 arguments in Combine. Please contact
-// [email protected] if you need more.
-// Please note that the number of arguments to Combine is limited
-// by the maximum arity of the implementation of tuple which is
-// currently set at 10.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
-
-// scripts/fuse_gtest.py depends on gtest's own header being #included
-// *unconditionally*. Therefore these #includes cannot be moved
-// inside #if GTEST_HAS_PARAM_TEST.
-#include "gtest/internal/gtest-param-util.h"
-#include "gtest/internal/gtest-port.h"
-
-#if GTEST_HAS_PARAM_TEST
-
-namespace testing {
-
-// Forward declarations of ValuesIn(), which is implemented in
-// include/gtest/gtest-param-test.h.
-template <typename ForwardIterator>
-internal::ParamGenerator<
- typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type>
-ValuesIn(ForwardIterator begin, ForwardIterator end);
-
-template <typename T, size_t N>
-internal::ParamGenerator<T> ValuesIn(const T (&array)[N]);
-
-template <class Container>
-internal::ParamGenerator<typename Container::value_type> ValuesIn(
- const Container& container);
-
-namespace internal {
-
-// Used in the Values() function to provide polymorphic capabilities.
-template <typename T1>
-class ValueArray1 {
- public:
- explicit ValueArray1(T1 v1) : v1_(v1) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray1& other) = delete;
-
- const T1 v1_;
-};
-
-template <typename T1, typename T2>
-class ValueArray2 {
- public:
- ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray2& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
-};
-
-template <typename T1, typename T2, typename T3>
-class ValueArray3 {
- public:
- ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray3& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4>
-class ValueArray4 {
- public:
- ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray4& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-class ValueArray5 {
- public:
- ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4), v5_(v5) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray5& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-class ValueArray6 {
- public:
- ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2),
- v3_(v3), v4_(v4), v5_(v5), v6_(v6) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray6& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
-class ValueArray7 {
- public:
- ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1),
- v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray7& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
-class ValueArray8 {
- public:
- ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7,
- T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray8& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
-class ValueArray9 {
- public:
- ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8,
- T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray9& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-class ValueArray10 {
- public:
- ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray10& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11>
-class ValueArray11 {
- public:
- ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
- v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray11& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12>
-class ValueArray12 {
- public:
- ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
- v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray12& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13>
-class ValueArray13 {
- public:
- ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
- v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
- v12_(v12), v13_(v13) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray13& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14>
-class ValueArray14 {
- public:
- ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray14& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15>
-class ValueArray15 {
- public:
- ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2),
- v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray15& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16>
-class ValueArray16 {
- public:
- ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1),
- v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
- v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
- v16_(v16) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray16& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17>
-class ValueArray17 {
- public:
- ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16,
- T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray17& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18>
-class ValueArray18 {
- public:
- ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray18& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19>
-class ValueArray19 {
- public:
- ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
- v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
- v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray19& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20>
-class ValueArray20 {
- public:
- ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
- v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
- v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
- v19_(v19), v20_(v20) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray20& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21>
-class ValueArray21 {
- public:
- ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
- v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
- v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
- v18_(v18), v19_(v19), v20_(v20), v21_(v21) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray21& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22>
-class ValueArray22 {
- public:
- ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray22& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23>
-class ValueArray23 {
- public:
- ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2),
- v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray23& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24>
-class ValueArray24 {
- public:
- ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1),
- v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
- v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
- v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
- v22_(v22), v23_(v23), v24_(v24) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray24& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25>
-class ValueArray25 {
- public:
- ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24,
- T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray25& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26>
-class ValueArray26 {
- public:
- ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray26& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27>
-class ValueArray27 {
- public:
- ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
- v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
- v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
- v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
- v26_(v26), v27_(v27) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray27& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28>
-class ValueArray28 {
- public:
- ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
- v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
- v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
- v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
- v25_(v25), v26_(v26), v27_(v27), v28_(v28) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray28& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29>
-class ValueArray29 {
- public:
- ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
- v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
- v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
- v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
- v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray29& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30>
-class ValueArray30 {
- public:
- ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
- v29_(v29), v30_(v30) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray30& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31>
-class ValueArray31 {
- public:
- ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2),
- v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
- v29_(v29), v30_(v30), v31_(v31) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray31& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32>
-class ValueArray32 {
- public:
- ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1),
- v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
- v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
- v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
- v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
- v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray32& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33>
-class ValueArray33 {
- public:
- ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32,
- T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
- v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
- v33_(v33) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray33& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34>
-class ValueArray34 {
- public:
- ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
- v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
- v33_(v33), v34_(v34) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray34& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35>
-class ValueArray35 {
- public:
- ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
- v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
- v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
- v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
- v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
- v32_(v32), v33_(v33), v34_(v34), v35_(v35) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray35& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36>
-class ValueArray36 {
- public:
- ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
- v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
- v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
- v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
- v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
- v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray36& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37>
-class ValueArray37 {
- public:
- ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
- v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
- v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
- v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
- v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
- v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
- v36_(v36), v37_(v37) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray37& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38>
-class ValueArray38 {
- public:
- ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
- v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
- v35_(v35), v36_(v36), v37_(v37), v38_(v38) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray38& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39>
-class ValueArray39 {
- public:
- ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2),
- v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
- v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
- v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray39& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40>
-class ValueArray40 {
- public:
- ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1),
- v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
- v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
- v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
- v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
- v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
- v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
- v40_(v40) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray40& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41>
-class ValueArray41 {
- public:
- ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40,
- T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
- v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
- v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
- v39_(v39), v40_(v40), v41_(v41) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray41& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42>
-class ValueArray42 {
- public:
- ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
- v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
- v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
- v39_(v39), v40_(v40), v41_(v41), v42_(v42) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray42& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43>
-class ValueArray43 {
- public:
- ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6),
- v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13),
- v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19),
- v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25),
- v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31),
- v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37),
- v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray43& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44>
-class ValueArray44 {
- public:
- ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5),
- v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12),
- v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18),
- v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24),
- v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30),
- v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36),
- v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42),
- v43_(v43), v44_(v44) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray44& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45>
-class ValueArray45 {
- public:
- ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4),
- v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11),
- v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17),
- v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23),
- v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29),
- v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35),
- v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41),
- v42_(v42), v43_(v43), v44_(v44), v45_(v45) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
- static_cast<T>(v45_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray45& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
- const T45 v45_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46>
-class ValueArray46 {
- public:
- ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3),
- v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
- v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
- v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
- v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
- static_cast<T>(v45_), static_cast<T>(v46_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray46& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
- const T45 v45_;
- const T46 v46_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47>
-class ValueArray47 {
- public:
- ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2),
- v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10),
- v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16),
- v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22),
- v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28),
- v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34),
- v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40),
- v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46),
- v47_(v47) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
- static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray47& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
- const T45 v45_;
- const T46 v46_;
- const T47 v47_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47, typename T48>
-class ValueArray48 {
- public:
- ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1),
- v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9),
- v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15),
- v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21),
- v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27),
- v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33),
- v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39),
- v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45),
- v46_(v46), v47_(v47), v48_(v48) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
- static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
- static_cast<T>(v48_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray48& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
- const T45 v45_;
- const T46 v46_;
- const T47 v47_;
- const T48 v48_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47, typename T48, typename T49>
-class ValueArray49 {
- public:
- ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48,
- T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
- v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
- v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
- v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
- v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
- static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
- static_cast<T>(v48_), static_cast<T>(v49_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray49& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
- const T45 v45_;
- const T46 v46_;
- const T47 v47_;
- const T48 v48_;
- const T49 v49_;
-};
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10,
- typename T11, typename T12, typename T13, typename T14, typename T15,
- typename T16, typename T17, typename T18, typename T19, typename T20,
- typename T21, typename T22, typename T23, typename T24, typename T25,
- typename T26, typename T27, typename T28, typename T29, typename T30,
- typename T31, typename T32, typename T33, typename T34, typename T35,
- typename T36, typename T37, typename T38, typename T39, typename T40,
- typename T41, typename T42, typename T43, typename T44, typename T45,
- typename T46, typename T47, typename T48, typename T49, typename T50>
-class ValueArray50 {
- public:
- ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9,
- T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17,
- T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25,
- T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33,
- T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41,
- T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49,
- T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7),
- v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14),
- v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20),
- v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26),
- v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32),
- v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38),
- v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44),
- v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {}
-
- template <typename T>
- operator ParamGenerator<T>() const {
- const T array[] = {static_cast<T>(v1_), static_cast<T>(v2_),
- static_cast<T>(v3_), static_cast<T>(v4_), static_cast<T>(v5_),
- static_cast<T>(v6_), static_cast<T>(v7_), static_cast<T>(v8_),
- static_cast<T>(v9_), static_cast<T>(v10_), static_cast<T>(v11_),
- static_cast<T>(v12_), static_cast<T>(v13_), static_cast<T>(v14_),
- static_cast<T>(v15_), static_cast<T>(v16_), static_cast<T>(v17_),
- static_cast<T>(v18_), static_cast<T>(v19_), static_cast<T>(v20_),
- static_cast<T>(v21_), static_cast<T>(v22_), static_cast<T>(v23_),
- static_cast<T>(v24_), static_cast<T>(v25_), static_cast<T>(v26_),
- static_cast<T>(v27_), static_cast<T>(v28_), static_cast<T>(v29_),
- static_cast<T>(v30_), static_cast<T>(v31_), static_cast<T>(v32_),
- static_cast<T>(v33_), static_cast<T>(v34_), static_cast<T>(v35_),
- static_cast<T>(v36_), static_cast<T>(v37_), static_cast<T>(v38_),
- static_cast<T>(v39_), static_cast<T>(v40_), static_cast<T>(v41_),
- static_cast<T>(v42_), static_cast<T>(v43_), static_cast<T>(v44_),
- static_cast<T>(v45_), static_cast<T>(v46_), static_cast<T>(v47_),
- static_cast<T>(v48_), static_cast<T>(v49_), static_cast<T>(v50_)};
- return ValuesIn(array);
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const ValueArray50& other) = delete;
-
- const T1 v1_;
- const T2 v2_;
- const T3 v3_;
- const T4 v4_;
- const T5 v5_;
- const T6 v6_;
- const T7 v7_;
- const T8 v8_;
- const T9 v9_;
- const T10 v10_;
- const T11 v11_;
- const T12 v12_;
- const T13 v13_;
- const T14 v14_;
- const T15 v15_;
- const T16 v16_;
- const T17 v17_;
- const T18 v18_;
- const T19 v19_;
- const T20 v20_;
- const T21 v21_;
- const T22 v22_;
- const T23 v23_;
- const T24 v24_;
- const T25 v25_;
- const T26 v26_;
- const T27 v27_;
- const T28 v28_;
- const T29 v29_;
- const T30 v30_;
- const T31 v31_;
- const T32 v32_;
- const T33 v33_;
- const T34 v34_;
- const T35 v35_;
- const T36 v36_;
- const T37 v37_;
- const T38 v38_;
- const T39 v39_;
- const T40 v40_;
- const T41 v41_;
- const T42 v42_;
- const T43 v43_;
- const T44 v44_;
- const T45 v45_;
- const T46 v46_;
- const T47 v47_;
- const T48 v48_;
- const T49 v49_;
- const T50 v50_;
-};
-
-# if GTEST_HAS_COMBINE
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Generates values from the Cartesian product of values produced
-// by the argument generators.
-//
-template <typename T1, typename T2>
-class CartesianProductGenerator2
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2> > {
- public:
- typedef ::testing::tuple<T1, T2> ParamType;
-
- CartesianProductGenerator2(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2)
- : g1_(g1), g2_(g2) {}
- virtual ~CartesianProductGenerator2() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current2_;
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- ParamType current_value_;
- }; // class CartesianProductGenerator2::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator2& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
-}; // class CartesianProductGenerator2
-
-
-template <typename T1, typename T2, typename T3>
-class CartesianProductGenerator3
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3> > {
- public:
- typedef ::testing::tuple<T1, T2, T3> ParamType;
-
- CartesianProductGenerator3(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3)
- : g1_(g1), g2_(g2), g3_(g3) {}
- virtual ~CartesianProductGenerator3() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current3_;
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- ParamType current_value_;
- }; // class CartesianProductGenerator3::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator3& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
-}; // class CartesianProductGenerator3
-
-
-template <typename T1, typename T2, typename T3, typename T4>
-class CartesianProductGenerator4
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4> ParamType;
-
- CartesianProductGenerator4(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
- virtual ~CartesianProductGenerator4() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current4_;
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- ParamType current_value_;
- }; // class CartesianProductGenerator4::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator4& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
-}; // class CartesianProductGenerator4
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5>
-class CartesianProductGenerator5
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4, T5> ParamType;
-
- CartesianProductGenerator5(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
- virtual ~CartesianProductGenerator5() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end(), g5_, g5_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4,
- const ParamGenerator<T5>& g5,
- const typename ParamGenerator<T5>::iterator& current5)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
- begin5_(g5.begin()), end5_(g5.end()), current5_(current5) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current5_;
- if (current5_ == end5_) {
- current5_ = begin5_;
- ++current4_;
- }
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_ &&
- current5_ == typed_other->current5_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_),
- begin5_(other.begin5_),
- end5_(other.end5_),
- current5_(other.current5_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_, *current5_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_ ||
- current5_ == end5_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- const typename ParamGenerator<T5>::iterator begin5_;
- const typename ParamGenerator<T5>::iterator end5_;
- typename ParamGenerator<T5>::iterator current5_;
- ParamType current_value_;
- }; // class CartesianProductGenerator5::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator5& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
- const ParamGenerator<T5> g5_;
-}; // class CartesianProductGenerator5
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
-class CartesianProductGenerator6
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5,
- T6> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4, T5, T6> ParamType;
-
- CartesianProductGenerator6(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
- const ParamGenerator<T6>& g6)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
- virtual ~CartesianProductGenerator6() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4,
- const ParamGenerator<T5>& g5,
- const typename ParamGenerator<T5>::iterator& current5,
- const ParamGenerator<T6>& g6,
- const typename ParamGenerator<T6>::iterator& current6)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
- begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
- begin6_(g6.begin()), end6_(g6.end()), current6_(current6) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current6_;
- if (current6_ == end6_) {
- current6_ = begin6_;
- ++current5_;
- }
- if (current5_ == end5_) {
- current5_ = begin5_;
- ++current4_;
- }
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_ &&
- current5_ == typed_other->current5_ &&
- current6_ == typed_other->current6_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_),
- begin5_(other.begin5_),
- end5_(other.end5_),
- current5_(other.current5_),
- begin6_(other.begin6_),
- end6_(other.end6_),
- current6_(other.current6_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_, *current5_, *current6_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_ ||
- current5_ == end5_ ||
- current6_ == end6_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- const typename ParamGenerator<T5>::iterator begin5_;
- const typename ParamGenerator<T5>::iterator end5_;
- typename ParamGenerator<T5>::iterator current5_;
- const typename ParamGenerator<T6>::iterator begin6_;
- const typename ParamGenerator<T6>::iterator end6_;
- typename ParamGenerator<T6>::iterator current6_;
- ParamType current_value_;
- }; // class CartesianProductGenerator6::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator6& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
- const ParamGenerator<T5> g5_;
- const ParamGenerator<T6> g6_;
-}; // class CartesianProductGenerator6
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
-class CartesianProductGenerator7
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
- T7> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType;
-
- CartesianProductGenerator7(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
- const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
- virtual ~CartesianProductGenerator7() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
- g7_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4,
- const ParamGenerator<T5>& g5,
- const typename ParamGenerator<T5>::iterator& current5,
- const ParamGenerator<T6>& g6,
- const typename ParamGenerator<T6>::iterator& current6,
- const ParamGenerator<T7>& g7,
- const typename ParamGenerator<T7>::iterator& current7)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
- begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
- begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
- begin7_(g7.begin()), end7_(g7.end()), current7_(current7) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current7_;
- if (current7_ == end7_) {
- current7_ = begin7_;
- ++current6_;
- }
- if (current6_ == end6_) {
- current6_ = begin6_;
- ++current5_;
- }
- if (current5_ == end5_) {
- current5_ = begin5_;
- ++current4_;
- }
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_ &&
- current5_ == typed_other->current5_ &&
- current6_ == typed_other->current6_ &&
- current7_ == typed_other->current7_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_),
- begin5_(other.begin5_),
- end5_(other.end5_),
- current5_(other.current5_),
- begin6_(other.begin6_),
- end6_(other.end6_),
- current6_(other.current6_),
- begin7_(other.begin7_),
- end7_(other.end7_),
- current7_(other.current7_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_, *current5_, *current6_, *current7_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_ ||
- current5_ == end5_ ||
- current6_ == end6_ ||
- current7_ == end7_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- const typename ParamGenerator<T5>::iterator begin5_;
- const typename ParamGenerator<T5>::iterator end5_;
- typename ParamGenerator<T5>::iterator current5_;
- const typename ParamGenerator<T6>::iterator begin6_;
- const typename ParamGenerator<T6>::iterator end6_;
- typename ParamGenerator<T6>::iterator current6_;
- const typename ParamGenerator<T7>::iterator begin7_;
- const typename ParamGenerator<T7>::iterator end7_;
- typename ParamGenerator<T7>::iterator current7_;
- ParamType current_value_;
- }; // class CartesianProductGenerator7::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator7& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
- const ParamGenerator<T5> g5_;
- const ParamGenerator<T6> g6_;
- const ParamGenerator<T7> g7_;
-}; // class CartesianProductGenerator7
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
-class CartesianProductGenerator8
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
- T7, T8> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType;
-
- CartesianProductGenerator8(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
- const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
- const ParamGenerator<T8>& g8)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
- g8_(g8) {}
- virtual ~CartesianProductGenerator8() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
- g7_.begin(), g8_, g8_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
- g8_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4,
- const ParamGenerator<T5>& g5,
- const typename ParamGenerator<T5>::iterator& current5,
- const ParamGenerator<T6>& g6,
- const typename ParamGenerator<T6>::iterator& current6,
- const ParamGenerator<T7>& g7,
- const typename ParamGenerator<T7>::iterator& current7,
- const ParamGenerator<T8>& g8,
- const typename ParamGenerator<T8>::iterator& current8)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
- begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
- begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
- begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
- begin8_(g8.begin()), end8_(g8.end()), current8_(current8) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current8_;
- if (current8_ == end8_) {
- current8_ = begin8_;
- ++current7_;
- }
- if (current7_ == end7_) {
- current7_ = begin7_;
- ++current6_;
- }
- if (current6_ == end6_) {
- current6_ = begin6_;
- ++current5_;
- }
- if (current5_ == end5_) {
- current5_ = begin5_;
- ++current4_;
- }
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_ &&
- current5_ == typed_other->current5_ &&
- current6_ == typed_other->current6_ &&
- current7_ == typed_other->current7_ &&
- current8_ == typed_other->current8_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_),
- begin5_(other.begin5_),
- end5_(other.end5_),
- current5_(other.current5_),
- begin6_(other.begin6_),
- end6_(other.end6_),
- current6_(other.current6_),
- begin7_(other.begin7_),
- end7_(other.end7_),
- current7_(other.current7_),
- begin8_(other.begin8_),
- end8_(other.end8_),
- current8_(other.current8_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_, *current5_, *current6_, *current7_, *current8_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_ ||
- current5_ == end5_ ||
- current6_ == end6_ ||
- current7_ == end7_ ||
- current8_ == end8_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- const typename ParamGenerator<T5>::iterator begin5_;
- const typename ParamGenerator<T5>::iterator end5_;
- typename ParamGenerator<T5>::iterator current5_;
- const typename ParamGenerator<T6>::iterator begin6_;
- const typename ParamGenerator<T6>::iterator end6_;
- typename ParamGenerator<T6>::iterator current6_;
- const typename ParamGenerator<T7>::iterator begin7_;
- const typename ParamGenerator<T7>::iterator end7_;
- typename ParamGenerator<T7>::iterator current7_;
- const typename ParamGenerator<T8>::iterator begin8_;
- const typename ParamGenerator<T8>::iterator end8_;
- typename ParamGenerator<T8>::iterator current8_;
- ParamType current_value_;
- }; // class CartesianProductGenerator8::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator8& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
- const ParamGenerator<T5> g5_;
- const ParamGenerator<T6> g6_;
- const ParamGenerator<T7> g7_;
- const ParamGenerator<T8> g8_;
-}; // class CartesianProductGenerator8
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
-class CartesianProductGenerator9
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
- T7, T8, T9> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType;
-
- CartesianProductGenerator9(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
- const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
- const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
- g9_(g9) {}
- virtual ~CartesianProductGenerator9() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
- g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
- g8_.end(), g9_, g9_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4,
- const ParamGenerator<T5>& g5,
- const typename ParamGenerator<T5>::iterator& current5,
- const ParamGenerator<T6>& g6,
- const typename ParamGenerator<T6>::iterator& current6,
- const ParamGenerator<T7>& g7,
- const typename ParamGenerator<T7>::iterator& current7,
- const ParamGenerator<T8>& g8,
- const typename ParamGenerator<T8>::iterator& current8,
- const ParamGenerator<T9>& g9,
- const typename ParamGenerator<T9>::iterator& current9)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
- begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
- begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
- begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
- begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
- begin9_(g9.begin()), end9_(g9.end()), current9_(current9) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current9_;
- if (current9_ == end9_) {
- current9_ = begin9_;
- ++current8_;
- }
- if (current8_ == end8_) {
- current8_ = begin8_;
- ++current7_;
- }
- if (current7_ == end7_) {
- current7_ = begin7_;
- ++current6_;
- }
- if (current6_ == end6_) {
- current6_ = begin6_;
- ++current5_;
- }
- if (current5_ == end5_) {
- current5_ = begin5_;
- ++current4_;
- }
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_ &&
- current5_ == typed_other->current5_ &&
- current6_ == typed_other->current6_ &&
- current7_ == typed_other->current7_ &&
- current8_ == typed_other->current8_ &&
- current9_ == typed_other->current9_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_),
- begin5_(other.begin5_),
- end5_(other.end5_),
- current5_(other.current5_),
- begin6_(other.begin6_),
- end6_(other.end6_),
- current6_(other.current6_),
- begin7_(other.begin7_),
- end7_(other.end7_),
- current7_(other.current7_),
- begin8_(other.begin8_),
- end8_(other.end8_),
- current8_(other.current8_),
- begin9_(other.begin9_),
- end9_(other.end9_),
- current9_(other.current9_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_, *current5_, *current6_, *current7_, *current8_,
- *current9_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_ ||
- current5_ == end5_ ||
- current6_ == end6_ ||
- current7_ == end7_ ||
- current8_ == end8_ ||
- current9_ == end9_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- const typename ParamGenerator<T5>::iterator begin5_;
- const typename ParamGenerator<T5>::iterator end5_;
- typename ParamGenerator<T5>::iterator current5_;
- const typename ParamGenerator<T6>::iterator begin6_;
- const typename ParamGenerator<T6>::iterator end6_;
- typename ParamGenerator<T6>::iterator current6_;
- const typename ParamGenerator<T7>::iterator begin7_;
- const typename ParamGenerator<T7>::iterator end7_;
- typename ParamGenerator<T7>::iterator current7_;
- const typename ParamGenerator<T8>::iterator begin8_;
- const typename ParamGenerator<T8>::iterator end8_;
- typename ParamGenerator<T8>::iterator current8_;
- const typename ParamGenerator<T9>::iterator begin9_;
- const typename ParamGenerator<T9>::iterator end9_;
- typename ParamGenerator<T9>::iterator current9_;
- ParamType current_value_;
- }; // class CartesianProductGenerator9::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator9& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
- const ParamGenerator<T5> g5_;
- const ParamGenerator<T6> g6_;
- const ParamGenerator<T7> g7_;
- const ParamGenerator<T8> g8_;
- const ParamGenerator<T9> g9_;
-}; // class CartesianProductGenerator9
-
-
-template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
-class CartesianProductGenerator10
- : public ParamGeneratorInterface< ::testing::tuple<T1, T2, T3, T4, T5, T6,
- T7, T8, T9, T10> > {
- public:
- typedef ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType;
-
- CartesianProductGenerator10(const ParamGenerator<T1>& g1,
- const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3,
- const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5,
- const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7,
- const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9,
- const ParamGenerator<T10>& g10)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
- g9_(g9), g10_(g10) {}
- virtual ~CartesianProductGenerator10() {}
-
- virtual ParamIteratorInterface<ParamType>* Begin() const {
- return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_,
- g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_,
- g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin());
- }
- virtual ParamIteratorInterface<ParamType>* End() const {
- return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(),
- g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_,
- g8_.end(), g9_, g9_.end(), g10_, g10_.end());
- }
-
- private:
- class Iterator : public ParamIteratorInterface<ParamType> {
- public:
- Iterator(const ParamGeneratorInterface<ParamType>* base,
- const ParamGenerator<T1>& g1,
- const typename ParamGenerator<T1>::iterator& current1,
- const ParamGenerator<T2>& g2,
- const typename ParamGenerator<T2>::iterator& current2,
- const ParamGenerator<T3>& g3,
- const typename ParamGenerator<T3>::iterator& current3,
- const ParamGenerator<T4>& g4,
- const typename ParamGenerator<T4>::iterator& current4,
- const ParamGenerator<T5>& g5,
- const typename ParamGenerator<T5>::iterator& current5,
- const ParamGenerator<T6>& g6,
- const typename ParamGenerator<T6>::iterator& current6,
- const ParamGenerator<T7>& g7,
- const typename ParamGenerator<T7>::iterator& current7,
- const ParamGenerator<T8>& g8,
- const typename ParamGenerator<T8>::iterator& current8,
- const ParamGenerator<T9>& g9,
- const typename ParamGenerator<T9>::iterator& current9,
- const ParamGenerator<T10>& g10,
- const typename ParamGenerator<T10>::iterator& current10)
- : base_(base),
- begin1_(g1.begin()), end1_(g1.end()), current1_(current1),
- begin2_(g2.begin()), end2_(g2.end()), current2_(current2),
- begin3_(g3.begin()), end3_(g3.end()), current3_(current3),
- begin4_(g4.begin()), end4_(g4.end()), current4_(current4),
- begin5_(g5.begin()), end5_(g5.end()), current5_(current5),
- begin6_(g6.begin()), end6_(g6.end()), current6_(current6),
- begin7_(g7.begin()), end7_(g7.end()), current7_(current7),
- begin8_(g8.begin()), end8_(g8.end()), current8_(current8),
- begin9_(g9.begin()), end9_(g9.end()), current9_(current9),
- begin10_(g10.begin()), end10_(g10.end()), current10_(current10) {
- ComputeCurrentValue();
- }
- virtual ~Iterator() {}
-
- virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const {
- return base_;
- }
- // Advance should not be called on beyond-of-range iterators
- // so no component iterators must be beyond end of range, either.
- virtual void Advance() {
- assert(!AtEnd());
- ++current10_;
- if (current10_ == end10_) {
- current10_ = begin10_;
- ++current9_;
- }
- if (current9_ == end9_) {
- current9_ = begin9_;
- ++current8_;
- }
- if (current8_ == end8_) {
- current8_ = begin8_;
- ++current7_;
- }
- if (current7_ == end7_) {
- current7_ = begin7_;
- ++current6_;
- }
- if (current6_ == end6_) {
- current6_ = begin6_;
- ++current5_;
- }
- if (current5_ == end5_) {
- current5_ = begin5_;
- ++current4_;
- }
- if (current4_ == end4_) {
- current4_ = begin4_;
- ++current3_;
- }
- if (current3_ == end3_) {
- current3_ = begin3_;
- ++current2_;
- }
- if (current2_ == end2_) {
- current2_ = begin2_;
- ++current1_;
- }
- ComputeCurrentValue();
- }
- virtual ParamIteratorInterface<ParamType>* Clone() const {
- return new Iterator(*this);
- }
- virtual const ParamType* Current() const { return ¤t_value_; }
- virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const {
- // Having the same base generator guarantees that the other
- // iterator is of the same type and we can downcast.
- GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
- << "The program attempted to compare iterators "
- << "from different generators." << std::endl;
- const Iterator* typed_other =
- CheckedDowncastToActualType<const Iterator>(&other);
- // We must report iterators equal if they both point beyond their
- // respective ranges. That can happen in a variety of fashions,
- // so we have to consult AtEnd().
- return (AtEnd() && typed_other->AtEnd()) ||
- (
- current1_ == typed_other->current1_ &&
- current2_ == typed_other->current2_ &&
- current3_ == typed_other->current3_ &&
- current4_ == typed_other->current4_ &&
- current5_ == typed_other->current5_ &&
- current6_ == typed_other->current6_ &&
- current7_ == typed_other->current7_ &&
- current8_ == typed_other->current8_ &&
- current9_ == typed_other->current9_ &&
- current10_ == typed_other->current10_);
- }
-
- private:
- Iterator(const Iterator& other)
- : base_(other.base_),
- begin1_(other.begin1_),
- end1_(other.end1_),
- current1_(other.current1_),
- begin2_(other.begin2_),
- end2_(other.end2_),
- current2_(other.current2_),
- begin3_(other.begin3_),
- end3_(other.end3_),
- current3_(other.current3_),
- begin4_(other.begin4_),
- end4_(other.end4_),
- current4_(other.current4_),
- begin5_(other.begin5_),
- end5_(other.end5_),
- current5_(other.current5_),
- begin6_(other.begin6_),
- end6_(other.end6_),
- current6_(other.current6_),
- begin7_(other.begin7_),
- end7_(other.end7_),
- current7_(other.current7_),
- begin8_(other.begin8_),
- end8_(other.end8_),
- current8_(other.current8_),
- begin9_(other.begin9_),
- end9_(other.end9_),
- current9_(other.current9_),
- begin10_(other.begin10_),
- end10_(other.end10_),
- current10_(other.current10_) {
- ComputeCurrentValue();
- }
-
- void ComputeCurrentValue() {
- if (!AtEnd())
- current_value_ = ParamType(*current1_, *current2_, *current3_,
- *current4_, *current5_, *current6_, *current7_, *current8_,
- *current9_, *current10_);
- }
- bool AtEnd() const {
- // We must report iterator past the end of the range when either of the
- // component iterators has reached the end of its range.
- return
- current1_ == end1_ ||
- current2_ == end2_ ||
- current3_ == end3_ ||
- current4_ == end4_ ||
- current5_ == end5_ ||
- current6_ == end6_ ||
- current7_ == end7_ ||
- current8_ == end8_ ||
- current9_ == end9_ ||
- current10_ == end10_;
- }
-
- // No implementation - assignment is unsupported.
- void operator=(const Iterator& other) = delete;
-
- const ParamGeneratorInterface<ParamType>* const base_;
- // begin[i]_ and end[i]_ define the i-th range that Iterator traverses.
- // current[i]_ is the actual traversing iterator.
- const typename ParamGenerator<T1>::iterator begin1_;
- const typename ParamGenerator<T1>::iterator end1_;
- typename ParamGenerator<T1>::iterator current1_;
- const typename ParamGenerator<T2>::iterator begin2_;
- const typename ParamGenerator<T2>::iterator end2_;
- typename ParamGenerator<T2>::iterator current2_;
- const typename ParamGenerator<T3>::iterator begin3_;
- const typename ParamGenerator<T3>::iterator end3_;
- typename ParamGenerator<T3>::iterator current3_;
- const typename ParamGenerator<T4>::iterator begin4_;
- const typename ParamGenerator<T4>::iterator end4_;
- typename ParamGenerator<T4>::iterator current4_;
- const typename ParamGenerator<T5>::iterator begin5_;
- const typename ParamGenerator<T5>::iterator end5_;
- typename ParamGenerator<T5>::iterator current5_;
- const typename ParamGenerator<T6>::iterator begin6_;
- const typename ParamGenerator<T6>::iterator end6_;
- typename ParamGenerator<T6>::iterator current6_;
- const typename ParamGenerator<T7>::iterator begin7_;
- const typename ParamGenerator<T7>::iterator end7_;
- typename ParamGenerator<T7>::iterator current7_;
- const typename ParamGenerator<T8>::iterator begin8_;
- const typename ParamGenerator<T8>::iterator end8_;
- typename ParamGenerator<T8>::iterator current8_;
- const typename ParamGenerator<T9>::iterator begin9_;
- const typename ParamGenerator<T9>::iterator end9_;
- typename ParamGenerator<T9>::iterator current9_;
- const typename ParamGenerator<T10>::iterator begin10_;
- const typename ParamGenerator<T10>::iterator end10_;
- typename ParamGenerator<T10>::iterator current10_;
- ParamType current_value_;
- }; // class CartesianProductGenerator10::Iterator
-
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductGenerator10& other) = delete;
-
- const ParamGenerator<T1> g1_;
- const ParamGenerator<T2> g2_;
- const ParamGenerator<T3> g3_;
- const ParamGenerator<T4> g4_;
- const ParamGenerator<T5> g5_;
- const ParamGenerator<T6> g6_;
- const ParamGenerator<T7> g7_;
- const ParamGenerator<T8> g8_;
- const ParamGenerator<T9> g9_;
- const ParamGenerator<T10> g10_;
-}; // class CartesianProductGenerator10
-
-
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Helper classes providing Combine() with polymorphic features. They allow
-// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is
-// convertible to U.
-//
-template <class Generator1, class Generator2>
-class CartesianProductHolder2 {
- public:
-CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
- : g1_(g1), g2_(g2) {}
- template <typename T1, typename T2>
- operator ParamGenerator< ::testing::tuple<T1, T2> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2> >(
- new CartesianProductGenerator2<T1, T2>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder2& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
-}; // class CartesianProductHolder2
-
-template <class Generator1, class Generator2, class Generator3>
-class CartesianProductHolder3 {
- public:
-CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
- const Generator3& g3)
- : g1_(g1), g2_(g2), g3_(g3) {}
- template <typename T1, typename T2, typename T3>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3> >(
- new CartesianProductGenerator3<T1, T2, T3>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder3& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
-}; // class CartesianProductHolder3
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4>
-class CartesianProductHolder4 {
- public:
-CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {}
- template <typename T1, typename T2, typename T3, typename T4>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4> >(
- new CartesianProductGenerator4<T1, T2, T3, T4>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder4& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
-}; // class CartesianProductHolder4
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4, class Generator5>
-class CartesianProductHolder5 {
- public:
-CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4, const Generator5& g5)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {}
- template <typename T1, typename T2, typename T3, typename T4, typename T5>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5> >(
- new CartesianProductGenerator5<T1, T2, T3, T4, T5>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_),
- static_cast<ParamGenerator<T5> >(g5_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder5& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
- const Generator5 g5_;
-}; // class CartesianProductHolder5
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4, class Generator5, class Generator6>
-class CartesianProductHolder6 {
- public:
-CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4, const Generator5& g5,
- const Generator6& g6)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {}
- template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6> >(
- new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_),
- static_cast<ParamGenerator<T5> >(g5_),
- static_cast<ParamGenerator<T6> >(g6_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder6& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
- const Generator5 g5_;
- const Generator6 g6_;
-}; // class CartesianProductHolder6
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4, class Generator5, class Generator6, class Generator7>
-class CartesianProductHolder7 {
- public:
-CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4, const Generator5& g5,
- const Generator6& g6, const Generator7& g7)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {}
- template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6,
- T7> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7> >(
- new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_),
- static_cast<ParamGenerator<T5> >(g5_),
- static_cast<ParamGenerator<T6> >(g6_),
- static_cast<ParamGenerator<T7> >(g7_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder7& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
- const Generator5 g5_;
- const Generator6 g6_;
- const Generator7 g7_;
-}; // class CartesianProductHolder7
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4, class Generator5, class Generator6, class Generator7,
- class Generator8>
-class CartesianProductHolder8 {
- public:
-CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4, const Generator5& g5,
- const Generator6& g6, const Generator7& g7, const Generator8& g8)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7),
- g8_(g8) {}
- template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7,
- T8> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >(
- new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_),
- static_cast<ParamGenerator<T5> >(g5_),
- static_cast<ParamGenerator<T6> >(g6_),
- static_cast<ParamGenerator<T7> >(g7_),
- static_cast<ParamGenerator<T8> >(g8_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder8& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
- const Generator5 g5_;
- const Generator6 g6_;
- const Generator7 g7_;
- const Generator8 g8_;
-}; // class CartesianProductHolder8
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4, class Generator5, class Generator6, class Generator7,
- class Generator8, class Generator9>
-class CartesianProductHolder9 {
- public:
-CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4, const Generator5& g5,
- const Generator6& g6, const Generator7& g7, const Generator8& g8,
- const Generator9& g9)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
- g9_(g9) {}
- template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
- T9> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8,
- T9> >(
- new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_),
- static_cast<ParamGenerator<T5> >(g5_),
- static_cast<ParamGenerator<T6> >(g6_),
- static_cast<ParamGenerator<T7> >(g7_),
- static_cast<ParamGenerator<T8> >(g8_),
- static_cast<ParamGenerator<T9> >(g9_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder9& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
- const Generator5 g5_;
- const Generator6 g6_;
- const Generator7 g7_;
- const Generator8 g8_;
- const Generator9 g9_;
-}; // class CartesianProductHolder9
-
-template <class Generator1, class Generator2, class Generator3,
- class Generator4, class Generator5, class Generator6, class Generator7,
- class Generator8, class Generator9, class Generator10>
-class CartesianProductHolder10 {
- public:
-CartesianProductHolder10(const Generator1& g1, const Generator2& g2,
- const Generator3& g3, const Generator4& g4, const Generator5& g5,
- const Generator6& g6, const Generator7& g7, const Generator8& g8,
- const Generator9& g9, const Generator10& g10)
- : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8),
- g9_(g9), g10_(g10) {}
- template <typename T1, typename T2, typename T3, typename T4, typename T5,
- typename T6, typename T7, typename T8, typename T9, typename T10>
- operator ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9,
- T10> >() const {
- return ParamGenerator< ::testing::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9,
- T10> >(
- new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9,
- T10>(
- static_cast<ParamGenerator<T1> >(g1_),
- static_cast<ParamGenerator<T2> >(g2_),
- static_cast<ParamGenerator<T3> >(g3_),
- static_cast<ParamGenerator<T4> >(g4_),
- static_cast<ParamGenerator<T5> >(g5_),
- static_cast<ParamGenerator<T6> >(g6_),
- static_cast<ParamGenerator<T7> >(g7_),
- static_cast<ParamGenerator<T8> >(g8_),
- static_cast<ParamGenerator<T9> >(g9_),
- static_cast<ParamGenerator<T10> >(g10_)));
- }
-
- private:
- // No implementation - assignment is unsupported.
- void operator=(const CartesianProductHolder10& other) = delete;
-
- const Generator1 g1_;
- const Generator2 g2_;
- const Generator3 g3_;
- const Generator4 g4_;
- const Generator5 g5_;
- const Generator6 g6_;
- const Generator7 g7_;
- const Generator8 g8_;
- const Generator9 g9_;
- const Generator10 g10_;
-}; // class CartesianProductHolder10
-
-# endif // GTEST_HAS_COMBINE
-
-} // namespace internal
-} // namespace testing
-
-#endif // GTEST_HAS_PARAM_TEST
-
-#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
index 82cab9b..9753399 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-param-util.h
@@ -26,33 +26,30 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Vlad Losev)
+
// Type and function utilities for implementing parameterized tests.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <ctype.h>
+#include <cassert>
#include <iterator>
+#include <memory>
#include <set>
+#include <tuple>
#include <utility>
#include <vector>
-// scripts/fuse_gtest.py depends on gtest's own header being #included
-// *unconditionally*. Therefore these #includes cannot be moved
-// inside #if GTEST_HAS_PARAM_TEST.
#include "gtest/internal/gtest-internal.h"
-#include "gtest/internal/gtest-linked_ptr.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h"
-#if GTEST_HAS_PARAM_TEST
-
namespace testing {
-
// Input to a parameterized test name generator, describing a test parameter.
// Consists of the parameter value and the integer parameter index.
template <class ParamType>
@@ -76,13 +73,14 @@
namespace internal {
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
+// Utility Functions
+
// Outputs a message explaining invalid registration of different
-// fixture class for the same test case. This may happen when
+// fixture class for the same test suite. This may happen when
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
-GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name,
- CodeLocation code_location);
+GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
+ CodeLocation code_location);
template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator;
@@ -157,7 +155,7 @@
private:
friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
- scoped_ptr<ParamIteratorInterface<T> > impl_;
+ std::unique_ptr<ParamIteratorInterface<T> > impl_;
};
// ParamGeneratorInterface<T> is the binary interface to access generators
@@ -196,7 +194,7 @@
iterator end() const { return iterator(impl_->End()); }
private:
- linked_ptr<const ParamGeneratorInterface<T> > impl_;
+ std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
};
// Generates values from a range of two comparable values. Can be used to
@@ -209,12 +207,12 @@
RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
- virtual ~RangeGenerator() {}
+ ~RangeGenerator() override {}
- virtual ParamIteratorInterface<T>* Begin() const {
+ ParamIteratorInterface<T>* Begin() const override {
return new Iterator(this, begin_, 0, step_);
}
- virtual ParamIteratorInterface<T>* End() const {
+ ParamIteratorInterface<T>* End() const override {
return new Iterator(this, end_, end_index_, step_);
}
@@ -224,20 +222,20 @@
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
IncrementT step)
: base_(base), value_(value), index_(index), step_(step) {}
- virtual ~Iterator() {}
+ ~Iterator() override {}
- virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+ const ParamGeneratorInterface<T>* BaseGenerator() const override {
return base_;
}
- virtual void Advance() {
+ void Advance() override {
value_ = static_cast<T>(value_ + step_);
index_++;
}
- virtual ParamIteratorInterface<T>* Clone() const {
+ ParamIteratorInterface<T>* Clone() const override {
return new Iterator(*this);
}
- virtual const T* Current() const { return &value_; }
- virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+ const T* Current() const override { return &value_; }
+ bool Equals(const ParamIteratorInterface<T>& other) const override {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
@@ -294,12 +292,12 @@
template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
: container_(begin, end) {}
- virtual ~ValuesInIteratorRangeGenerator() {}
+ ~ValuesInIteratorRangeGenerator() override {}
- virtual ParamIteratorInterface<T>* Begin() const {
+ ParamIteratorInterface<T>* Begin() const override {
return new Iterator(this, container_.begin());
}
- virtual ParamIteratorInterface<T>* End() const {
+ ParamIteratorInterface<T>* End() const override {
return new Iterator(this, container_.end());
}
@@ -311,16 +309,16 @@
Iterator(const ParamGeneratorInterface<T>* base,
typename ContainerType::const_iterator iterator)
: base_(base), iterator_(iterator) {}
- virtual ~Iterator() {}
+ ~Iterator() override {}
- virtual const ParamGeneratorInterface<T>* BaseGenerator() const {
+ const ParamGeneratorInterface<T>* BaseGenerator() const override {
return base_;
}
- virtual void Advance() {
+ void Advance() override {
++iterator_;
value_.reset();
}
- virtual ParamIteratorInterface<T>* Clone() const {
+ ParamIteratorInterface<T>* Clone() const override {
return new Iterator(*this);
}
// We need to use cached value referenced by iterator_ because *iterator_
@@ -330,12 +328,11 @@
// can advance iterator_ beyond the end of the range, and we cannot
// detect that fact. The client code, on the other hand, is
// responsible for not calling Current() on an out-of-range iterator.
- virtual const T* Current() const {
- if (value_.get() == NULL)
- value_.reset(new T(*iterator_));
+ const T* Current() const override {
+ if (value_.get() == nullptr) value_.reset(new T(*iterator_));
return value_.get();
}
- virtual bool Equals(const ParamIteratorInterface<T>& other) const {
+ bool Equals(const ParamIteratorInterface<T>& other) const override {
// Having the same base generator guarantees that the other
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
@@ -358,9 +355,9 @@
// A cached value of *iterator_. We keep it here to allow access by
// pointer in the wrapping iterator's operator->().
// value_ needs to be mutable to be accessed in Current().
- // Use of scoped_ptr helps manage cached value's lifetime,
+ // Use of std::unique_ptr helps manage cached value's lifetime,
// which is bound by the lifespan of the iterator itself.
- mutable scoped_ptr<const T> value_;
+ mutable std::unique_ptr<const T> value_;
}; // class ValuesInIteratorRangeGenerator::Iterator
// No implementation - assignment is unsupported.
@@ -380,25 +377,12 @@
return name_stream.GetString();
}
-// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
-//
-// Parameterized test name overload helpers, which help the
-// INSTANTIATE_TEST_CASE_P macro choose between the default parameterized
-// test name generator and user param name generator.
-template <class ParamType, class ParamNameGenFunctor>
-ParamNameGenFunctor GetParamNameGen(ParamNameGenFunctor func) {
- return func;
+template <typename T = int>
+void TestNotEmpty() {
+ static_assert(sizeof(T) == 0, "Empty arguments are not allowed.");
}
-
-template <class ParamType>
-struct ParamNameGenFunc {
- typedef std::string Type(const TestParamInfo<ParamType>&);
-};
-
-template <class ParamType>
-typename ParamNameGenFunc<ParamType>::Type *GetParamNameGen() {
- return DefaultParamName;
-}
+template <typename T = int>
+void TestNotEmpty(const T&) {}
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
@@ -410,7 +394,7 @@
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {}
- virtual Test* CreateTest() {
+ Test* CreateTest() override {
TestClass::SetParam(¶meter_);
return new TestClass();
}
@@ -438,19 +422,19 @@
// TestMetaFactory creates test factories for passing into
// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives
// ownership of test factory pointer, same factory object cannot be passed
-// into that method twice. But ParameterizedTestCaseInfo is going to call
+// into that method twice. But ParameterizedTestSuiteInfo is going to call
// it for each Test/Parameter value combination. Thus it needs meta factory
// creator class.
-template <class TestCase>
+template <class TestSuite>
class TestMetaFactory
- : public TestMetaFactoryBase<typename TestCase::ParamType> {
+ : public TestMetaFactoryBase<typename TestSuite::ParamType> {
public:
- typedef typename TestCase::ParamType ParamType;
+ using ParamType = typename TestSuite::ParamType;
TestMetaFactory() {}
- virtual TestFactoryBase* CreateTestFactory(ParamType parameter) {
- return new ParameterizedTestFactory<TestCase>(parameter);
+ TestFactoryBase* CreateTestFactory(ParamType parameter) override {
+ return new ParameterizedTestFactory<TestSuite>(parameter);
}
private:
@@ -459,107 +443,106 @@
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
-// ParameterizedTestCaseInfoBase is a generic interface
-// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase
+// ParameterizedTestSuiteInfoBase is a generic interface
+// to ParameterizedTestSuiteInfo classes. ParameterizedTestSuiteInfoBase
// accumulates test information provided by TEST_P macro invocations
-// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations
+// and generators provided by INSTANTIATE_TEST_SUITE_P macro invocations
// and uses that information to register all resulting test instances
-// in RegisterTests method. The ParameterizeTestCaseRegistry class holds
-// a collection of pointers to the ParameterizedTestCaseInfo objects
+// in RegisterTests method. The ParameterizeTestSuiteRegistry class holds
+// a collection of pointers to the ParameterizedTestSuiteInfo objects
// and calls RegisterTests() on each of them when asked.
-class ParameterizedTestCaseInfoBase {
+class ParameterizedTestSuiteInfoBase {
public:
- virtual ~ParameterizedTestCaseInfoBase() {}
+ virtual ~ParameterizedTestSuiteInfoBase() {}
- // Base part of test case name for display purposes.
- virtual const string& GetTestCaseName() const = 0;
+ // Base part of test suite name for display purposes.
+ virtual const std::string& GetTestSuiteName() const = 0;
// Test case id to verify identity.
- virtual TypeId GetTestCaseTypeId() const = 0;
+ virtual TypeId GetTestSuiteTypeId() const = 0;
// UnitTest class invokes this method to register tests in this
- // test case right before running them in RUN_ALL_TESTS macro.
- // This method should not be called more then once on any single
- // instance of a ParameterizedTestCaseInfoBase derived class.
+ // test suite right before running them in RUN_ALL_TESTS macro.
+ // This method should not be called more than once on any single
+ // instance of a ParameterizedTestSuiteInfoBase derived class.
virtual void RegisterTests() = 0;
protected:
- ParameterizedTestCaseInfoBase() {}
+ ParameterizedTestSuiteInfoBase() {}
private:
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase);
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
-// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P
-// macro invocations for a particular test case and generators
-// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that
-// test case. It registers tests with all values generated by all
+// ParameterizedTestSuiteInfo accumulates tests obtained from TEST_P
+// macro invocations for a particular test suite and generators
+// obtained from INSTANTIATE_TEST_SUITE_P macro invocations for that
+// test suite. It registers tests with all values generated by all
// generators when asked.
-template <class TestCase>
-class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
+template <class TestSuite>
+class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
public:
// ParamType and GeneratorCreationFunc are private types but are required
// for declarations of public methods AddTestPattern() and
- // AddTestCaseInstantiation().
- typedef typename TestCase::ParamType ParamType;
+ // AddTestSuiteInstantiation().
+ using ParamType = typename TestSuite::ParamType;
// A function that returns an instance of appropriate generator type.
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
- typedef typename ParamNameGenFunc<ParamType>::Type ParamNameGeneratorFunc;
+ using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
- explicit ParameterizedTestCaseInfo(
- const char* name, CodeLocation code_location)
- : test_case_name_(name), code_location_(code_location) {}
+ explicit ParameterizedTestSuiteInfo(const char* name,
+ CodeLocation code_location)
+ : test_suite_name_(name), code_location_(code_location) {}
// Test case base name for display purposes.
- virtual const string& GetTestCaseName() const { return test_case_name_; }
+ const std::string& GetTestSuiteName() const override {
+ return test_suite_name_;
+ }
// Test case id to verify identity.
- virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); }
+ TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
// TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure.
- // test_case_name is the base name of the test case (without invocation
+ // test_suite_name is the base name of the test suite (without invocation
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
- // test case base name and DoBar is test base name.
- void AddTestPattern(const char* test_case_name,
- const char* test_base_name,
+ // test suite base name and DoBar is test base name.
+ void AddTestPattern(const char* test_suite_name, const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) {
- tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name,
- test_base_name,
- meta_factory)));
+ tests_.push_back(std::shared_ptr<TestInfo>(
+ new TestInfo(test_suite_name, test_base_name, meta_factory)));
}
- // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information
+ // INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator.
- int AddTestCaseInstantiation(const string& instantiation_name,
- GeneratorCreationFunc* func,
- ParamNameGeneratorFunc* name_func,
- const char* file,
- int line) {
+ int AddTestSuiteInstantiation(const std::string& instantiation_name,
+ GeneratorCreationFunc* func,
+ ParamNameGeneratorFunc* name_func,
+ const char* file, int line) {
instantiations_.push_back(
InstantiationInfo(instantiation_name, func, name_func, file, line));
return 0; // Return value used only to run this method in namespace scope.
}
- // UnitTest class invokes this method to register tests in this test case
- // test cases right before running tests in RUN_ALL_TESTS macro.
- // This method should not be called more then once on any single
- // instance of a ParameterizedTestCaseInfoBase derived class.
- // UnitTest has a guard to prevent from calling this method more then once.
- virtual void RegisterTests() {
+ // UnitTest class invokes this method to register tests in this test suite
+ // test suites right before running tests in RUN_ALL_TESTS macro.
+ // This method should not be called more than once on any single
+ // instance of a ParameterizedTestSuiteInfoBase derived class.
+ // UnitTest has a guard to prevent from calling this method more than once.
+ void RegisterTests() override {
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
- linked_ptr<TestInfo> test_info = *test_it;
+ std::shared_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end();
++gen_it) {
- const string& instantiation_name = gen_it->name;
+ const std::string& instantiation_name = gen_it->name;
ParamGenerator<ParamType> generator((*gen_it->generator)());
ParamNameGeneratorFunc* name_func = gen_it->name_func;
const char* file = gen_it->file;
int line = gen_it->line;
- string test_case_name;
+ std::string test_suite_name;
if ( !instantiation_name.empty() )
- test_case_name = instantiation_name + "/";
- test_case_name += test_info->test_case_base_name;
+ test_suite_name = instantiation_name + "/";
+ test_suite_name += test_info->test_suite_base_name;
size_t i = 0;
std::set<std::string> test_param_names;
@@ -582,39 +565,39 @@
test_param_names.insert(param_name);
- test_name_stream << test_info->test_base_name << "/" << param_name;
+ if (!test_info->test_base_name.empty()) {
+ test_name_stream << test_info->test_base_name << "/";
+ }
+ test_name_stream << param_name;
MakeAndRegisterTestInfo(
- test_case_name.c_str(),
- test_name_stream.GetString().c_str(),
- NULL, // No type parameter.
- PrintToString(*param_it).c_str(),
- code_location_,
- GetTestCaseTypeId(),
- TestCase::SetUpTestCase,
- TestCase::TearDownTestCase,
+ test_suite_name.c_str(), test_name_stream.GetString().c_str(),
+ nullptr, // No type parameter.
+ PrintToString(*param_it).c_str(), code_location_,
+ GetTestSuiteTypeId(),
+ SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
+ SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
- } // RegisterTests
+ } // RegisterTests
private:
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
- TestInfo(const char* a_test_case_base_name,
- const char* a_test_base_name,
- TestMetaFactoryBase<ParamType>* a_test_meta_factory) :
- test_case_base_name(a_test_case_base_name),
- test_base_name(a_test_base_name),
- test_meta_factory(a_test_meta_factory) {}
+ TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
+ TestMetaFactoryBase<ParamType>* a_test_meta_factory)
+ : test_suite_base_name(a_test_suite_base_name),
+ test_base_name(a_test_base_name),
+ test_meta_factory(a_test_meta_factory) {}
- const string test_case_base_name;
- const string test_base_name;
- const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
+ const std::string test_suite_base_name;
+ const std::string test_base_name;
+ const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
};
- typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer;
- // Records data received from INSTANTIATE_TEST_CASE_P macros:
+ using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
+ // Records data received from INSTANTIATE_TEST_SUITE_P macros:
// <Instantiation name, Sequence generator creation function,
// Name generator function, Source file, Source line>
struct InstantiationInfo {
@@ -651,81 +634,250 @@
return true;
}
- const string test_case_name_;
+ const std::string test_suite_name_;
CodeLocation code_location_;
TestInfoContainer tests_;
InstantiationContainer instantiations_;
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo);
-}; // class ParameterizedTestCaseInfo
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
+}; // class ParameterizedTestSuiteInfo
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+template <class TestCase>
+using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
-// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase
-// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P
-// macros use it to locate their corresponding ParameterizedTestCaseInfo
-// descriptors.
-class ParameterizedTestCaseRegistry {
+// ParameterizedTestSuiteRegistry contains a map of
+// ParameterizedTestSuiteInfoBase classes accessed by test suite names. TEST_P
+// and INSTANTIATE_TEST_SUITE_P macros use it to locate their corresponding
+// ParameterizedTestSuiteInfo descriptors.
+class ParameterizedTestSuiteRegistry {
public:
- ParameterizedTestCaseRegistry() {}
- ~ParameterizedTestCaseRegistry() {
- for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
- it != test_case_infos_.end(); ++it) {
- delete *it;
+ ParameterizedTestSuiteRegistry() {}
+ ~ParameterizedTestSuiteRegistry() {
+ for (auto& test_suite_info : test_suite_infos_) {
+ delete test_suite_info;
}
}
// Looks up or creates and returns a structure containing information about
- // tests and instantiations of a particular test case.
- template <class TestCase>
- ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
- const char* test_case_name,
- CodeLocation code_location) {
- ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL;
- for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
- it != test_case_infos_.end(); ++it) {
- if ((*it)->GetTestCaseName() == test_case_name) {
- if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) {
+ // tests and instantiations of a particular test suite.
+ template <class TestSuite>
+ ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
+ const char* test_suite_name, CodeLocation code_location) {
+ ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
+ for (auto& test_suite_info : test_suite_infos_) {
+ if (test_suite_info->GetTestSuiteName() == test_suite_name) {
+ if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
- // test case setup and tear-down in this case.
- ReportInvalidTestCaseType(test_case_name, code_location);
+ // test suite setup and tear-down in this case.
+ ReportInvalidTestSuiteType(test_suite_name, code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
- ParameterizedTestCaseInfo<TestCase> >(*it);
+ ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
}
break;
}
}
- if (typed_test_info == NULL) {
- typed_test_info = new ParameterizedTestCaseInfo<TestCase>(
- test_case_name, code_location);
- test_case_infos_.push_back(typed_test_info);
+ if (typed_test_info == nullptr) {
+ typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
+ test_suite_name, code_location);
+ test_suite_infos_.push_back(typed_test_info);
}
return typed_test_info;
}
void RegisterTests() {
- for (TestCaseInfoContainer::iterator it = test_case_infos_.begin();
- it != test_case_infos_.end(); ++it) {
- (*it)->RegisterTests();
+ for (auto& test_suite_info : test_suite_infos_) {
+ test_suite_info->RegisterTests();
}
}
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ template <class TestCase>
+ ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
+ const char* test_case_name, CodeLocation code_location) {
+ return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
+ }
+
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+ private:
+ using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
+
+ TestSuiteInfoContainer test_suite_infos_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
+};
+
+} // namespace internal
+
+// Forward declarations of ValuesIn(), which is implemented in
+// include/gtest/gtest-param-test.h.
+template <class Container>
+internal::ParamGenerator<typename Container::value_type> ValuesIn(
+ const Container& container);
+
+namespace internal {
+// Used in the Values() function to provide polymorphic capabilities.
+
+template <typename... Ts>
+class ValueArray {
+ public:
+ ValueArray(Ts... v) : v_{std::move(v)...} {}
+
+ template <typename T>
+ operator ParamGenerator<T>() const { // NOLINT
+ return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
+ }
private:
- typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer;
+ template <typename T, size_t... I>
+ std::vector<T> MakeVector(IndexSequence<I...>) const {
+ return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
+ }
- TestCaseInfoContainer test_case_infos_;
+ FlatTuple<Ts...> v_;
+};
- GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry);
+template <typename... T>
+class CartesianProductGenerator
+ : public ParamGeneratorInterface<::std::tuple<T...>> {
+ public:
+ typedef ::std::tuple<T...> ParamType;
+
+ CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
+ : generators_(g) {}
+ ~CartesianProductGenerator() override {}
+
+ ParamIteratorInterface<ParamType>* Begin() const override {
+ return new Iterator(this, generators_, false);
+ }
+ ParamIteratorInterface<ParamType>* End() const override {
+ return new Iterator(this, generators_, true);
+ }
+
+ private:
+ template <class I>
+ class IteratorImpl;
+ template <size_t... I>
+ class IteratorImpl<IndexSequence<I...>>
+ : public ParamIteratorInterface<ParamType> {
+ public:
+ IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
+ const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
+ : base_(base),
+ begin_(std::get<I>(generators).begin()...),
+ end_(std::get<I>(generators).end()...),
+ current_(is_end ? end_ : begin_) {
+ ComputeCurrentValue();
+ }
+ ~IteratorImpl() override {}
+
+ const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
+ return base_;
+ }
+ // Advance should not be called on beyond-of-range iterators
+ // so no component iterators must be beyond end of range, either.
+ void Advance() override {
+ assert(!AtEnd());
+ // Advance the last iterator.
+ ++std::get<sizeof...(T) - 1>(current_);
+ // if that reaches end, propagate that up.
+ AdvanceIfEnd<sizeof...(T) - 1>();
+ ComputeCurrentValue();
+ }
+ ParamIteratorInterface<ParamType>* Clone() const override {
+ return new IteratorImpl(*this);
+ }
+
+ const ParamType* Current() const override { return current_value_.get(); }
+
+ bool Equals(const ParamIteratorInterface<ParamType>& other) const override {
+ // Having the same base generator guarantees that the other
+ // iterator is of the same type and we can downcast.
+ GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
+ << "The program attempted to compare iterators "
+ << "from different generators." << std::endl;
+ const IteratorImpl* typed_other =
+ CheckedDowncastToActualType<const IteratorImpl>(&other);
+
+ // We must report iterators equal if they both point beyond their
+ // respective ranges. That can happen in a variety of fashions,
+ // so we have to consult AtEnd().
+ if (AtEnd() && typed_other->AtEnd()) return true;
+
+ bool same = true;
+ bool dummy[] = {
+ (same = same && std::get<I>(current_) ==
+ std::get<I>(typed_other->current_))...};
+ (void)dummy;
+ return same;
+ }
+
+ private:
+ template <size_t ThisI>
+ void AdvanceIfEnd() {
+ if (std::get<ThisI>(current_) != std::get<ThisI>(end_)) return;
+
+ bool last = ThisI == 0;
+ if (last) {
+ // We are done. Nothing else to propagate.
+ return;
+ }
+
+ constexpr size_t NextI = ThisI - (ThisI != 0);
+ std::get<ThisI>(current_) = std::get<ThisI>(begin_);
+ ++std::get<NextI>(current_);
+ AdvanceIfEnd<NextI>();
+ }
+
+ void ComputeCurrentValue() {
+ if (!AtEnd())
+ current_value_ = std::make_shared<ParamType>(*std::get<I>(current_)...);
+ }
+ bool AtEnd() const {
+ bool at_end = false;
+ bool dummy[] = {
+ (at_end = at_end || std::get<I>(current_) == std::get<I>(end_))...};
+ (void)dummy;
+ return at_end;
+ }
+
+ const ParamGeneratorInterface<ParamType>* const base_;
+ std::tuple<typename ParamGenerator<T>::iterator...> begin_;
+ std::tuple<typename ParamGenerator<T>::iterator...> end_;
+ std::tuple<typename ParamGenerator<T>::iterator...> current_;
+ std::shared_ptr<ParamType> current_value_;
+ };
+
+ using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
+
+ std::tuple<ParamGenerator<T>...> generators_;
+};
+
+template <class... Gen>
+class CartesianProductHolder {
+ public:
+ CartesianProductHolder(const Gen&... g) : generators_(g...) {}
+ template <typename... T>
+ operator ParamGenerator<::std::tuple<T...>>() const {
+ return ParamGenerator<::std::tuple<T...>>(
+ new CartesianProductGenerator<T...>(generators_));
+ }
+
+ private:
+ std::tuple<Gen...> generators_;
};
} // namespace internal
} // namespace testing
-#endif // GTEST_HAS_PARAM_TEST
-
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h
index f1319c7..cece93d 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port-arch.h
@@ -27,7 +27,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the GTEST_OS_* macro.
// It is separate from gtest-port.h so that custom/gtest-port.h can include it.
@@ -38,14 +38,13 @@
// Determines the platform on which Google Test is compiled.
#ifdef __CYGWIN__
# define GTEST_OS_CYGWIN 1
-#elif defined __SYMBIAN32__
-# define GTEST_OS_SYMBIAN 1
+# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
+# define GTEST_OS_WINDOWS_MINGW 1
+# define GTEST_OS_WINDOWS 1
#elif defined _WIN32
# define GTEST_OS_WINDOWS 1
# ifdef _WIN32_WCE
# define GTEST_OS_WINDOWS_MOBILE 1
-# elif defined(__MINGW__) || defined(__MINGW32__)
-# define GTEST_OS_WINDOWS_MINGW 1
# elif defined(WINAPI_FAMILY)
# include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
@@ -54,6 +53,9 @@
# define GTEST_OS_WINDOWS_PHONE 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
# define GTEST_OS_WINDOWS_RT 1
+# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
+# define GTEST_OS_WINDOWS_PHONE 1
+# define GTEST_OS_WINDOWS_TV_TITLE 1
# else
// WINAPI_FAMILY defined but no known partition matched.
// Default to desktop.
@@ -62,13 +64,21 @@
# else
# define GTEST_OS_WINDOWS_DESKTOP 1
# endif // _WIN32_WCE
+#elif defined __OS2__
+# define GTEST_OS_OS2 1
#elif defined __APPLE__
# define GTEST_OS_MAC 1
# if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1
# endif
+#elif defined __DragonFly__
+# define GTEST_OS_DRAGONFLY 1
#elif defined __FreeBSD__
# define GTEST_OS_FREEBSD 1
+#elif defined __Fuchsia__
+# define GTEST_OS_FUCHSIA 1
+#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
+# define GTEST_OS_GNU_KFREEBSD 1
#elif defined __linux__
# define GTEST_OS_LINUX 1
# if defined __ANDROID__
@@ -91,9 +101,7 @@
#elif defined __QNX__
# define GTEST_OS_QNX 1
#elif defined(__HAIKU__)
-# define GTEST_OS_HAIKU 1
-#elif defined(_MINIX)
-# define GTEST_OS_MINIX 1
+#define GTEST_OS_HAIKU 1
#endif // __CYGWIN__
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h
index 17410d3..063fcb1 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-port.h
@@ -27,8 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Authors: [email protected] (Zhanyong Wan)
-//
// Low-level types and utilities for porting Google Test to various
// platforms. All macros ending with _ and symbols defined in an
// internal namespace are subject to change without notice. Code
@@ -40,6 +38,8 @@
// files are expected to #include this. Therefore, it cannot #include
// any other Google Test header.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
@@ -72,12 +72,6 @@
// is/isn't available.
// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions
// are enabled.
-// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string
-// is/isn't available (some systems define
-// ::string, which is different to std::string).
-// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string
-// is/isn't available (some systems define
-// ::wstring, which is different to std::wstring).
// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular
// expressions are/aren't available.
// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h>
@@ -87,8 +81,6 @@
// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that
// std::wstring does/doesn't work (Google Test can
// be used where std::wstring is unavailable).
-// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple
-// is/isn't available.
// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the
// compiler supports Microsoft's "Structured
// Exception Handling".
@@ -96,12 +88,6 @@
// - Define it to 1/0 to indicate whether the
// platform supports I/O stream redirection using
// dup() and dup2().
-// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google
-// Test's own tr1 tuple implementation should be
-// used. Unused when the user sets
-// GTEST_HAS_TR1_TUPLE to 0.
-// GTEST_LANG_CXX11 - Define it to 1/0 to indicate that Google Test
-// is building in C++11/C++98 mode.
// GTEST_LINKED_AS_SHARED_LIBRARY
// - Define to 1 when compiling tests that use
// Google Test as a shared library (known as
@@ -109,6 +95,12 @@
// GTEST_CREATE_SHARED_LIBRARY
// - Define to 1 when compiling Google Test itself
// as a shared library.
+// GTEST_DEFAULT_DEATH_TEST_STYLE
+// - The default value of --gtest_death_test_style.
+// The legacy default has been "fast" in the open
+// source version since 2008. The recommended value
+// is "threadsafe", and can be set in
+// custom/gtest-port.h.
// Platform-indicating macros
// --------------------------
@@ -121,19 +113,22 @@
//
// GTEST_OS_AIX - IBM AIX
// GTEST_OS_CYGWIN - Cygwin
+// GTEST_OS_DRAGONFLY - DragonFlyBSD
// GTEST_OS_FREEBSD - FreeBSD
+// GTEST_OS_FUCHSIA - Fuchsia
+// GTEST_OS_GNU_KFREEBSD - GNU/kFreeBSD
// GTEST_OS_HAIKU - Haiku
// GTEST_OS_HPUX - HP-UX
// GTEST_OS_LINUX - Linux
// GTEST_OS_LINUX_ANDROID - Google Android
// GTEST_OS_MAC - Mac OS X
// GTEST_OS_IOS - iOS
-// GTEST_OS_MINIX - Minix
// GTEST_OS_NACL - Google Native Client (NaCl)
+// GTEST_OS_NETBSD - NetBSD
// GTEST_OS_OPENBSD - OpenBSD
+// GTEST_OS_OS2 - OS/2
// GTEST_OS_QNX - QNX
// GTEST_OS_SOLARIS - Sun Solaris
-// GTEST_OS_SYMBIAN - Symbian
// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile)
// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop
// GTEST_OS_WINDOWS_MINGW - MinGW
@@ -142,7 +137,7 @@
// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT
// GTEST_OS_ZOS - z/OS
//
-// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the
+// Among the platforms, Cygwin, Linux, Mac OS X, and Windows have the
// most stable support. Since core members of the Google Test project
// don't have access to other platforms, support for them may be less
// stable. If you notice any problems on your platform, please notify
@@ -168,19 +163,16 @@
// EXPECT_DEATH(DoSomethingDeadly());
// #endif
//
-// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized
-// tests)
// GTEST_HAS_DEATH_TEST - death tests
-// GTEST_HAS_PARAM_TEST - value-parameterized tests
// GTEST_HAS_TYPED_TEST - typed tests
// GTEST_HAS_TYPED_TEST_P - type-parameterized tests
// GTEST_IS_THREADSAFE - Google Test is thread-safe.
+// GOOGLETEST_CM0007 DO NOT DELETE
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
// GTEST_HAS_POSIX_RE (see above) which users can
// define themselves.
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
-// the above two are mutually exclusive.
-// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ().
+// the above RE\b(s) are mutually exclusive.
// Misc public macros
// ------------------
@@ -206,28 +198,16 @@
// GTEST_INTENTIONAL_CONST_COND_POP_ - finish code section where MSVC C4127
// is suppressed.
//
-// C++11 feature wrappers:
-//
-// testing::internal::move - portability wrapper for std::move.
-//
// Synchronization:
// Mutex, MutexLock, ThreadLocal, GetThreadCount()
// - synchronization primitives.
//
-// Template meta programming:
-// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only.
-// IteratorTraits - partial implementation of std::iterator_traits, which
-// is not available in libCstd when compiled with Sun C++.
-//
-// Smart pointers:
-// scoped_ptr - as in TR2.
-//
// Regular expressions:
// RE - a simple regular expression class using the POSIX
-// Extended Regular Expression syntax on UNIX-like
-// platforms, or a reduced regular exception syntax on
-// other platforms, including Windows.
-//
+// Extended Regular Expression syntax on UNIX-like platforms
+// GOOGLETEST_CM0008 DO NOT DELETE
+// or a reduced regular exception syntax on other
+// platforms, including Windows.
// Logging:
// GTEST_LOG_() - logs messages at the specified severity level.
// LogToStderr() - directs all log messages to stderr.
@@ -257,12 +237,20 @@
// BoolFromGTestEnv() - parses a bool environment variable.
// Int32FromGTestEnv() - parses an Int32 environment variable.
// StringFromGTestEnv() - parses a string environment variable.
+//
+// Deprecation warnings:
+// GTEST_INTERNAL_DEPRECATED(message) - attribute marking a function as
+// deprecated; calling a marked function
+// should generate a compiler warning
#include <ctype.h> // for isspace, etc
#include <stddef.h> // for ptrdiff_t
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <memory>
+#include <type_traits>
+
#ifndef _WIN32_WCE
# include <sys/types.h>
# include <sys/stat.h>
@@ -274,9 +262,10 @@
#endif
#include <algorithm> // NOLINT
-#include <iostream> // NOLINT
-#include <sstream> // NOLINT
-#include <string> // NOLINT
+#include <iostream> // NOLINT
+#include <sstream> // NOLINT
+#include <string> // NOLINT
+#include <tuple>
#include <utility>
#include <vector> // NOLINT
@@ -308,85 +297,32 @@
// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
// /* code that triggers warnings C4800 and C4385 */
// GTEST_DISABLE_MSC_WARNINGS_POP_()
-#if _MSC_VER >= 1500
+#if defined(_MSC_VER)
# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \
__pragma(warning(push)) \
__pragma(warning(disable: warnings))
# define GTEST_DISABLE_MSC_WARNINGS_POP_() \
__pragma(warning(pop))
#else
-// Older versions of MSVC don't have __pragma.
+// Not all compilers are MSVC
# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings)
# define GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
-#ifndef GTEST_LANG_CXX11
-// gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when
-// -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a
-// value for __cplusplus, and recent versions of clang, gcc, and
-// probably other compilers set that too in C++11 mode.
-# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L
-// Compiling in at least C++11 mode.
-# define GTEST_LANG_CXX11 1
-# else
-# define GTEST_LANG_CXX11 0
-# endif
-#endif
-
-// Distinct from C++11 language support, some environments don't provide
-// proper C++11 library support. Notably, it's possible to build in
-// C++11 mode when targeting Mac OS X 10.6, which has an old libstdc++
-// with no C++11 support.
-//
-// libstdc++ has sufficient C++11 support as of GCC 4.6.0, __GLIBCXX__
-// 20110325, but maintenance releases in the 4.4 and 4.5 series followed
-// this date, so check for those versions by their date stamps.
-// https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning
-#if GTEST_LANG_CXX11 && \
- (!defined(__GLIBCXX__) || ( \
- __GLIBCXX__ >= 20110325ul && /* GCC >= 4.6.0 */ \
- /* Exclude patch releases of older branches: */ \
- __GLIBCXX__ != 20110416ul && /* GCC 4.4.6 */ \
- __GLIBCXX__ != 20120313ul && /* GCC 4.4.7 */ \
- __GLIBCXX__ != 20110428ul && /* GCC 4.5.3 */ \
- __GLIBCXX__ != 20120702ul)) /* GCC 4.5.4 */
-# define GTEST_STDLIB_CXX11 1
-#endif
-
-// Only use C++11 library features if the library provides them.
-#if GTEST_STDLIB_CXX11
-# define GTEST_HAS_STD_BEGIN_AND_END_ 1
-# define GTEST_HAS_STD_FORWARD_LIST_ 1
-# define GTEST_HAS_STD_FUNCTION_ 1
-# define GTEST_HAS_STD_INITIALIZER_LIST_ 1
-# define GTEST_HAS_STD_MOVE_ 1
-# define GTEST_HAS_STD_SHARED_PTR_ 1
-# define GTEST_HAS_STD_TYPE_TRAITS_ 1
-# define GTEST_HAS_STD_UNIQUE_PTR_ 1
-#endif
-
-// C++11 specifies that <tuple> provides std::tuple.
-// Some platforms still might not have it, however.
-#if GTEST_LANG_CXX11
-# define GTEST_HAS_STD_TUPLE_ 1
-# if defined(__clang__)
-// Inspired by http://clang.llvm.org/docs/LanguageExtensions.html#__has_include
-# if defined(__has_include) && !__has_include(<tuple>)
-# undef GTEST_HAS_STD_TUPLE_
-# endif
-# elif defined(_MSC_VER)
-// Inspired by boost/config/stdlib/dinkumware.hpp
-# if defined(_CPPLIB_VER) && _CPPLIB_VER < 520
-# undef GTEST_HAS_STD_TUPLE_
-# endif
-# elif defined(__GLIBCXX__)
-// Inspired by boost/config/stdlib/libstdcpp3.hpp,
-// http://gcc.gnu.org/gcc-4.2/changes.html and
-// http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01.html#manual.intro.status.standard.200x
-# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2)
-# undef GTEST_HAS_STD_TUPLE_
-# endif
-# endif
+// Clang on Windows does not understand MSVC's pragma warning.
+// We need clang-specific way to disable function deprecation warning.
+#ifdef __clang__
+# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \
+ _Pragma("clang diagnostic ignored \"-Wdeprecated-implementations\"")
+#define GTEST_DISABLE_MSC_DEPRECATED_POP_() \
+ _Pragma("clang diagnostic pop")
+#else
+# define GTEST_DISABLE_MSC_DEPRECATED_PUSH_() \
+ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
+# define GTEST_DISABLE_MSC_DEPRECATED_POP_() \
+ GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
// Brings in definitions for functions used in the testing::internal::posix
@@ -398,10 +334,16 @@
# include <io.h>
# endif
// In order to avoid having to include <windows.h>, use forward declaration
-// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.
+#if GTEST_OS_WINDOWS_MINGW && !defined(__MINGW64_VERSION_MAJOR)
+// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two
+// separate (equivalent) structs, instead of using typedef
+typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;
+#else
+// Assume CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.
// This assumption is verified by
// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.
-struct _RTL_CRITICAL_SECTION;
+typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
+#endif
#else
// This assumes that non-Windows OSes provide unistd.h. For OSes where this
// is not the case, we need to include headers that provide the functions
@@ -415,7 +357,8 @@
# include <android/api-level.h> // NOLINT
#endif
-// Defines this to true iff Google Test can use POSIX regular expressions.
+// Defines this to true if and only if Google Test can use POSIX regular
+// expressions.
#ifndef GTEST_HAS_POSIX_RE
# if GTEST_OS_LINUX_ANDROID
// On Android, <regex.h> is only available starting with Gingerbread.
@@ -455,8 +398,11 @@
#ifndef GTEST_HAS_EXCEPTIONS
// The user didn't tell us whether exceptions are enabled, so we need
// to figure it out.
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS
+# if defined(_MSC_VER) && defined(_CPPUNWIND)
+// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled.
+# define GTEST_HAS_EXCEPTIONS 1
+# elif defined(__BORLANDC__)
+// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS
// macro to enable exceptions, so we'll do the same.
// Assumes that exceptions are enabled by default.
# ifndef _HAS_EXCEPTIONS
@@ -464,16 +410,17 @@
# endif // _HAS_EXCEPTIONS
# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
# elif defined(__clang__)
-// clang defines __EXCEPTIONS iff exceptions are enabled before clang 220714,
-// but iff cleanups are enabled after that. In Obj-C++ files, there can be
-// cleanups for ObjC exceptions which also need cleanups, even if C++ exceptions
-// are disabled. clang has __has_feature(cxx_exceptions) which checks for C++
-// exceptions starting at clang r206352, but which checked for cleanups prior to
-// that. To reliably check for C++ exception availability with clang, check for
+// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang
+// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files,
+// there can be cleanups for ObjC exceptions which also need cleanups, even if
+// C++ exceptions are disabled. clang has __has_feature(cxx_exceptions) which
+// checks for C++ exceptions starting at clang r206352, but which checked for
+// cleanups prior to that. To reliably check for C++ exception availability with
+// clang, check for
// __EXCEPTIONS && __has_feature(cxx_exceptions).
# define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions))
# elif defined(__GNUC__) && __EXCEPTIONS
-// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled.
+// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__SUNPRO_CC)
// Sun Pro CC supports exceptions. However, there is no compile-time way of
@@ -481,7 +428,7 @@
// they are enabled unless the user tells us otherwise.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__IBMCPP__) && __EXCEPTIONS
-// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled.
+// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
# define GTEST_HAS_EXCEPTIONS 1
# elif defined(__HP_aCC)
// Exception handling is in effect by default in HP aCC compiler. It has to
@@ -500,39 +447,21 @@
# define GTEST_HAS_STD_STRING 1
#elif !GTEST_HAS_STD_STRING
// The user told us that ::std::string isn't available.
-# error "Google Test cannot be used where ::std::string isn't available."
+# error "::std::string isn't available."
#endif // !defined(GTEST_HAS_STD_STRING)
-#ifndef GTEST_HAS_GLOBAL_STRING
-// The user didn't tell us whether ::string is available, so we need
-// to figure it out.
-
-# define GTEST_HAS_GLOBAL_STRING 0
-
-#endif // GTEST_HAS_GLOBAL_STRING
-
#ifndef GTEST_HAS_STD_WSTRING
// The user didn't tell us whether ::std::wstring is available, so we need
// to figure it out.
-// TODO([email protected]): uses autoconf to detect whether ::std::wstring
-// is available.
-
// Cygwin 1.7 and below doesn't support ::std::wstring.
// Solaris' libc++ doesn't support it either. Android has
// no support for it at least as recent as Froyo (2.2).
-// Minix currently doesn't support it either.
-# define GTEST_HAS_STD_WSTRING \
- (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || GTEST_OS_HAIKU || GTEST_OS_MINIX))
+#define GTEST_HAS_STD_WSTRING \
+ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+ GTEST_OS_HAIKU))
#endif // GTEST_HAS_STD_WSTRING
-#ifndef GTEST_HAS_GLOBAL_WSTRING
-// The user didn't tell us whether ::wstring is available, so we need
-// to figure it out.
-# define GTEST_HAS_GLOBAL_WSTRING \
- (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING)
-#endif // GTEST_HAS_GLOBAL_WSTRING
-
// Determines whether RTTI is available.
#ifndef GTEST_HAS_RTTI
// The user didn't tell us whether RTTI is enabled, so we need to
@@ -540,14 +469,15 @@
# ifdef _MSC_VER
-# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled.
+#ifdef _CPPRTTI // MSVC defines this macro if and only if RTTI is enabled.
# define GTEST_HAS_RTTI 1
# else
# define GTEST_HAS_RTTI 0
# endif
-// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled.
-# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302)
+// Starting with version 4.3.2, gcc defines __GXX_RTTI if and only if RTTI is
+// enabled.
+# elif defined(__GNUC__)
# ifdef __GXX_RTTI
// When building against STLport with the Android NDK and with
@@ -603,8 +533,11 @@
//
// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0
// to your compiler flags.
-# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \
- || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NACL)
+#define GTEST_HAS_PTHREAD \
+ (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX || \
+ GTEST_OS_FREEBSD || GTEST_OS_NACL || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
+ GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_OPENBSD || \
+ GTEST_OS_HAIKU)
#endif // GTEST_HAS_PTHREAD
#if GTEST_HAS_PTHREAD
@@ -616,138 +549,6 @@
# include <time.h> // NOLINT
#endif
-// Determines if hash_map/hash_set are available.
-// Only used for testing against those containers.
-#if !defined(GTEST_HAS_HASH_MAP_)
-# if _MSC_VER
-# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available.
-# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available.
-# endif // _MSC_VER
-#endif // !defined(GTEST_HAS_HASH_MAP_)
-
-// Determines whether Google Test can use tr1/tuple. You can define
-// this macro to 0 to prevent Google Test from using tuple (any
-// feature depending on tuple with be disabled in this mode).
-#ifndef GTEST_HAS_TR1_TUPLE
-# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR)
-// STLport, provided with the Android NDK, has neither <tr1/tuple> or <tuple>.
-# define GTEST_HAS_TR1_TUPLE 0
-# else
-// The user didn't tell us not to do it, so we assume it's OK.
-# define GTEST_HAS_TR1_TUPLE 1
-# endif
-#endif // GTEST_HAS_TR1_TUPLE
-
-// Determines whether Google Test's own tr1 tuple implementation
-// should be used.
-#ifndef GTEST_USE_OWN_TR1_TUPLE
-// The user didn't tell us, so we need to figure it out.
-
-// We use our own TR1 tuple if we aren't sure the user has an
-// implementation of it already. At this time, libstdc++ 4.0.0+ and
-// MSVC 2010 are the only mainstream standard libraries that come
-// with a TR1 tuple implementation. NVIDIA's CUDA NVCC compiler
-// pretends to be GCC by defining __GNUC__ and friends, but cannot
-// compile GCC's tuple implementation. MSVC 2008 (9.0) provides TR1
-// tuple in a 323 MB Feature Pack download, which we cannot assume the
-// user has. QNX's QCC compiler is a modified GCC but it doesn't
-// support TR1 tuple. libc++ only provides std::tuple, in C++11 mode,
-// and it can be used with some compilers that define __GNUC__.
-# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \
- && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600
-# define GTEST_ENV_HAS_TR1_TUPLE_ 1
-# endif
-
-// C++11 specifies that <tuple> provides std::tuple. Use that if gtest is used
-// in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6
-// can build with clang but need to use gcc4.2's libstdc++).
-# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325)
-# define GTEST_ENV_HAS_STD_TUPLE_ 1
-# endif
-
-# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_
-# define GTEST_USE_OWN_TR1_TUPLE 0
-# else
-# define GTEST_USE_OWN_TR1_TUPLE 1
-# endif
-
-#endif // GTEST_USE_OWN_TR1_TUPLE
-
-// To avoid conditional compilation everywhere, we make it
-// gtest-port.h's responsibility to #include the header implementing
-// tuple.
-#if GTEST_HAS_STD_TUPLE_
-# include <tuple> // IWYU pragma: export
-# define GTEST_TUPLE_NAMESPACE_ ::std
-#endif // GTEST_HAS_STD_TUPLE_
-
-// We include tr1::tuple even if std::tuple is available to define printers for
-// them.
-#if GTEST_HAS_TR1_TUPLE
-# ifndef GTEST_TUPLE_NAMESPACE_
-# define GTEST_TUPLE_NAMESPACE_ ::std::tr1
-# endif // GTEST_TUPLE_NAMESPACE_
-
-# if GTEST_USE_OWN_TR1_TUPLE
-# include "gtest/internal/gtest-tuple.h" // IWYU pragma: export // NOLINT
-# elif GTEST_ENV_HAS_STD_TUPLE_
-# include <tuple>
-// C++11 puts its tuple into the ::std namespace rather than
-// ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there.
-// This causes undefined behavior, but supported compilers react in
-// the way we intend.
-namespace std {
-namespace tr1 {
-using ::std::get;
-using ::std::make_tuple;
-using ::std::tuple;
-using ::std::tuple_element;
-using ::std::tuple_size;
-}
-}
-
-# elif GTEST_OS_SYMBIAN
-
-// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to
-// use STLport's tuple implementation, which unfortunately doesn't
-// work as the copy of STLport distributed with Symbian is incomplete.
-// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to
-// use its own tuple implementation.
-# ifdef BOOST_HAS_TR1_TUPLE
-# undef BOOST_HAS_TR1_TUPLE
-# endif // BOOST_HAS_TR1_TUPLE
-
-// This prevents <boost/tr1/detail/config.hpp>, which defines
-// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>.
-# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED
-# include <tuple> // IWYU pragma: export // NOLINT
-
-# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000)
-// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does
-// not conform to the TR1 spec, which requires the header to be <tuple>.
-
-# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
-// Until version 4.3.2, gcc has a bug that causes <tr1/functional>,
-// which is #included by <tr1/tuple>, to not compile when RTTI is
-// disabled. _TR1_FUNCTIONAL is the header guard for
-// <tr1/functional>. Hence the following #define is a hack to prevent
-// <tr1/functional> from being included.
-# define _TR1_FUNCTIONAL 1
-# include <tr1/tuple>
-# undef _TR1_FUNCTIONAL // Allows the user to #include
- // <tr1/functional> if he chooses to.
-# else
-# include <tr1/tuple> // NOLINT
-# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302
-
-# else
-// If the compiler is not GCC 4.0+, we assume the user is using a
-// spec-conforming TR1 implementation.
-# include <tuple> // IWYU pragma: export // NOLINT
-# endif // GTEST_USE_OWN_TR1_TUPLE
-
-#endif // GTEST_HAS_TR1_TUPLE
-
// Determines whether clone(2) is supported.
// Usually it will only be available on Linux, excluding
// Linux on the Itanium architecture.
@@ -757,8 +558,12 @@
# if GTEST_OS_LINUX && !defined(__ia64__)
# if GTEST_OS_LINUX_ANDROID
-// On Android, clone() is only available on ARM starting with Gingerbread.
-# if defined(__arm__) && __ANDROID_API__ >= 9
+// On Android, clone() became available at different API levels for each 32-bit
+// architecture.
+# if defined(__LP64__) || \
+ (defined(__arm__) && __ANDROID_API__ >= 9) || \
+ (defined(__mips__) && __ANDROID_API__ >= 12) || \
+ (defined(__i386__) && __ANDROID_API__ >= 17)
# define GTEST_HAS_CLONE 1
# else
# define GTEST_HAS_CLONE 0
@@ -777,55 +582,41 @@
#ifndef GTEST_HAS_STREAM_REDIRECTION
// By default, we assume that stream redirection is supported on all
// platforms except known mobile ones.
-# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \
- GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
+# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
# define GTEST_HAS_STREAM_REDIRECTION 0
# else
# define GTEST_HAS_STREAM_REDIRECTION 1
-# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN
+# endif // !GTEST_OS_WINDOWS_MOBILE
#endif // GTEST_HAS_STREAM_REDIRECTION
// Determines whether to support death tests.
-// Google Test does not support death tests for VC 7.1 and earlier as
-// abort() in a VC 7.1 application compiled as GUI in debug config
// pops up a dialog window that cannot be suppressed programmatically.
-#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
- (GTEST_OS_MAC && !GTEST_OS_IOS) || \
- (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \
- GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \
- GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NETBSD)
+#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \
+ (GTEST_OS_MAC && !GTEST_OS_IOS) || \
+ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER) || GTEST_OS_WINDOWS_MINGW || \
+ GTEST_OS_AIX || GTEST_OS_HPUX || GTEST_OS_OPENBSD || GTEST_OS_QNX || \
+ GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \
+ GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU)
# define GTEST_HAS_DEATH_TEST 1
#endif
-// We don't support MSVC 7.1 with exceptions disabled now. Therefore
-// all the compilers we care about are adequate for supporting
-// value-parameterized tests.
-#define GTEST_HAS_PARAM_TEST 1
-
// Determines whether to support type-driven tests.
// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
// Sun Pro CC, IBM Visual Age, and HP aCC support.
-#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \
+#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \
defined(__IBMCPP__) || defined(__HP_aCC)
# define GTEST_HAS_TYPED_TEST 1
# define GTEST_HAS_TYPED_TEST_P 1
#endif
-// Determines whether to support Combine(). This only makes sense when
-// value-parameterized tests are enabled. The implementation doesn't
-// work on Sun Studio since it doesn't understand templated conversion
-// operators.
-#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC)
-# define GTEST_HAS_COMBINE 1
-#endif
-
// Determines whether the system compiler uses UTF-16 for encoding wide strings.
#define GTEST_WIDE_STRING_USES_UTF16_ \
- (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX)
+ (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_AIX || GTEST_OS_OS2)
// Determines whether test results can be streamed to a socket.
-#if GTEST_OS_LINUX
+#if GTEST_OS_LINUX || GTEST_OS_GNU_KFREEBSD || GTEST_OS_DRAGONFLY || \
+ GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_OPENBSD
# define GTEST_CAN_STREAM_RESULTS_ 1
#endif
@@ -867,15 +658,33 @@
# define GTEST_ATTRIBUTE_UNUSED_
#endif
+// Use this annotation before a function that takes a printf format string.
+#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC)
+# if defined(__MINGW_PRINTF_FORMAT)
+// MinGW has two different printf implementations. Ensure the format macro
+// matches the selected implementation. See
+// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/.
+# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
+ __attribute__((__format__(__MINGW_PRINTF_FORMAT, string_index, \
+ first_to_check)))
+# else
+# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \
+ __attribute__((__format__(__printf__, string_index, first_to_check)))
+# endif
+#else
+# define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check)
+#endif
+
+
// A macro to disallow operator=
// This should be used in the private: declarations for a class.
-#define GTEST_DISALLOW_ASSIGN_(type)\
+#define GTEST_DISALLOW_ASSIGN_(type) \
void operator=(type const &) = delete
// A macro to disallow copy constructor and operator=
// This should be used in the private: declarations for a class.
-#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\
- type(type const &) = delete;\
+#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \
+ type(type const &) = delete; \
GTEST_DISALLOW_ASSIGN_(type)
// Tell the compiler to warn about unused return values for functions declared
@@ -883,11 +692,11 @@
// following the argument list:
//
// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_;
-#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC)
+#if defined(__GNUC__) && !defined(COMPILER_ICC)
# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result))
#else
# define GTEST_MUST_USE_RESULT_
-#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC
+#endif // __GNUC__ && !COMPILER_ICC
// MS C++ compiler emits warning when a conditional expression is compile time
// constant. In some contexts this warning is false positive and needs to be
@@ -918,10 +727,19 @@
#endif // GTEST_HAS_SEH
-#define GTEST_IS_THREADSAFE \
- (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ \
- || (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \
- || GTEST_HAS_PTHREAD)
+#ifndef GTEST_IS_THREADSAFE
+
+#define GTEST_IS_THREADSAFE \
+ (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ || \
+ (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) || \
+ GTEST_HAS_PTHREAD)
+
+#endif // GTEST_IS_THREADSAFE
+
+// GTEST_API_ qualifies all symbols that must be exported. The definitions below
+// are guarded by #ifndef to give embedders a chance to define GTEST_API_ in
+// gtest/internal/custom/gtest-port.h
+#ifndef GTEST_API_
#ifdef _MSC_VER
# if GTEST_LINKED_AS_SHARED_LIBRARY
@@ -931,11 +749,17 @@
# endif
#elif __GNUC__ >= 4 || defined(__clang__)
# define GTEST_API_ __attribute__((visibility ("default")))
-#endif // _MSC_VER
+#endif // _MSC_VER
+
+#endif // GTEST_API_
#ifndef GTEST_API_
# define GTEST_API_
-#endif
+#endif // GTEST_API_
+
+#ifndef GTEST_DEFAULT_DEATH_TEST_STYLE
+# define GTEST_DEFAULT_DEATH_TEST_STYLE "fast"
+#endif // GTEST_DEFAULT_DEATH_TEST_STYLE
#ifdef __GNUC__
// Ask the compiler to never inline a given function.
@@ -945,16 +769,12 @@
#endif
// _LIBCPP_VERSION is defined by the libc++ library from the LLVM project.
-#if defined(__has_include)
-# if __has_include(<cxxabi.h>)
+#if !defined(GTEST_HAS_CXXABI_H_)
+# if defined(__GLIBCXX__) || (defined(_LIBCPP_VERSION) && !defined(_MSC_VER))
# define GTEST_HAS_CXXABI_H_ 1
# else
# define GTEST_HAS_CXXABI_H_ 0
# endif
-#elif defined(__GLIBCXX__) || defined(_LIBCPP_VERSION)
-# define GTEST_HAS_CXXABI_H_ 1
-#else
-# define GTEST_HAS_CXXABI_H_ 0
#endif
// A function level attribute to disable checking for use of uninitialized
@@ -982,6 +802,18 @@
# define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
#endif // __clang__
+// A function level attribute to disable HWAddressSanitizer instrumentation.
+#if defined(__clang__)
+# if __has_feature(hwaddress_sanitizer)
+# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \
+ __attribute__((no_sanitize("hwaddress")))
+# else
+# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
+# endif // __has_feature(hwaddress_sanitizer)
+#else
+# define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
+#endif // __clang__
+
// A function level attribute to disable ThreadSanitizer instrumentation.
#if defined(__clang__)
# if __has_feature(thread_sanitizer)
@@ -998,16 +830,13 @@
class Message;
-#if defined(GTEST_TUPLE_NAMESPACE_)
-// Import tuple and friends into the ::testing namespace.
-// It is part of our interface, having them in ::testing allows us to change
-// their types as needed.
-using GTEST_TUPLE_NAMESPACE_::get;
-using GTEST_TUPLE_NAMESPACE_::make_tuple;
-using GTEST_TUPLE_NAMESPACE_::tuple;
-using GTEST_TUPLE_NAMESPACE_::tuple_size;
-using GTEST_TUPLE_NAMESPACE_::tuple_element;
-#endif // defined(GTEST_TUPLE_NAMESPACE_)
+// Legacy imports for backwards compatibility.
+// New code should use std:: names directly.
+using std::get;
+using std::make_tuple;
+using std::tuple;
+using std::tuple_element;
+using std::tuple_size;
namespace internal {
@@ -1016,150 +845,30 @@
// Secret object, which is what we want.
class Secret;
-// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time
-// expression is true. For example, you could use it to verify the
-// size of a static array:
+// The GTEST_COMPILE_ASSERT_ is a legacy macro used to verify that a compile
+// time expression is true (in new code, use static_assert instead). For
+// example, you could use it to verify the size of a static array:
//
// GTEST_COMPILE_ASSERT_(GTEST_ARRAY_SIZE_(names) == NUM_NAMES,
// names_incorrect_size);
//
-// or to make sure a struct is smaller than a certain size:
-//
-// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large);
-//
-// The second argument to the macro is the name of the variable. If
-// the expression is false, most compilers will issue a warning/error
-// containing the name of the variable.
-
-#if GTEST_LANG_CXX11
-# define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
-#else // !GTEST_LANG_CXX11
-template <bool>
- struct CompileAssert {
-};
-
-# define GTEST_COMPILE_ASSERT_(expr, msg) \
- typedef ::testing::internal::CompileAssert<(static_cast<bool>(expr))> \
- msg[static_cast<bool>(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_
-#endif // !GTEST_LANG_CXX11
-
-// Implementation details of GTEST_COMPILE_ASSERT_:
-//
-// (In C++11, we simply use static_assert instead of the following)
-//
-// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1
-// elements (and thus is invalid) when the expression is false.
-//
-// - The simpler definition
-//
-// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1]
-//
-// does not work, as gcc supports variable-length arrays whose sizes
-// are determined at run-time (this is gcc's extension and not part
-// of the C++ standard). As a result, gcc fails to reject the
-// following code with the simple definition:
-//
-// int foo;
-// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is
-// // not a compile-time constant.
-//
-// - By using the type CompileAssert<(bool(expr))>, we ensures that
-// expr is a compile-time constant. (Template arguments must be
-// determined at compile-time.)
-//
-// - The outter parentheses in CompileAssert<(bool(expr))> are necessary
-// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written
-//
-// CompileAssert<bool(expr)>
-//
-// instead, these compilers will refuse to compile
-//
-// GTEST_COMPILE_ASSERT_(5 > 0, some_message);
-//
-// (They seem to think the ">" in "5 > 0" marks the end of the
-// template argument list.)
-//
-// - The array size is (bool(expr) ? 1 : -1), instead of simply
-//
-// ((expr) ? 1 : -1).
-//
-// This is to avoid running into a bug in MS VC 7.1, which
-// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1.
-
-// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h.
-//
-// This template is declared, but intentionally undefined.
-template <typename T1, typename T2>
-struct StaticAssertTypeEqHelper;
-
-template <typename T>
-struct StaticAssertTypeEqHelper<T, T> {
- enum { value = true };
-};
+// The second argument to the macro must be a valid C++ identifier. If the
+// expression is false, compiler will issue an error containing this identifier.
+#define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg)
// Evaluates to the number of elements in 'array'.
#define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0]))
-#if GTEST_HAS_GLOBAL_STRING
-typedef ::string string;
-#else
-typedef ::std::string string;
-#endif // GTEST_HAS_GLOBAL_STRING
-
-#if GTEST_HAS_GLOBAL_WSTRING
-typedef ::wstring wstring;
-#elif GTEST_HAS_STD_WSTRING
-typedef ::std::wstring wstring;
-#endif // GTEST_HAS_GLOBAL_WSTRING
-
// A helper for suppressing warnings on constant condition. It just
// returns 'condition'.
GTEST_API_ bool IsTrue(bool condition);
-// Defines scoped_ptr.
-
-// This implementation of scoped_ptr is PARTIAL - it only contains
-// enough stuff to satisfy Google Test's need.
-template <typename T>
-class scoped_ptr {
- public:
- typedef T element_type;
-
- explicit scoped_ptr(T* p = NULL) : ptr_(p) {}
- ~scoped_ptr() { reset(); }
-
- T& operator*() const { return *ptr_; }
- T* operator->() const { return ptr_; }
- T* get() const { return ptr_; }
-
- T* release() {
- T* const ptr = ptr_;
- ptr_ = NULL;
- return ptr;
- }
-
- void reset(T* p = NULL) {
- if (p != ptr_) {
- if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type.
- delete ptr_;
- }
- ptr_ = p;
- }
- }
-
- friend void swap(scoped_ptr& a, scoped_ptr& b) {
- using std::swap;
- swap(a.ptr_, b.ptr_);
- }
-
- private:
- T* ptr_;
-
- GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
-};
-
// Defines RE.
+#if GTEST_USES_PCRE
+// if used, PCRE is injected by custom/gtest-port.h
+#elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE
+
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
// Regular Expression syntax.
class GTEST_API_ RE {
@@ -1171,25 +880,16 @@
// Constructs an RE from a string.
RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT
-#if GTEST_HAS_GLOBAL_STRING
-
- RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT
-
-#endif // GTEST_HAS_GLOBAL_STRING
-
RE(const char* regex) { Init(regex); } // NOLINT
~RE();
// Returns the string representation of the regex.
const char* pattern() const { return pattern_; }
- // FullMatch(str, re) returns true iff regular expression re matches
- // the entire str.
- // PartialMatch(str, re) returns true iff regular expression re
+ // FullMatch(str, re) returns true if and only if regular expression re
+ // matches the entire str.
+ // PartialMatch(str, re) returns true if and only if regular expression re
// matches a substring of str (including str itself).
- //
- // TODO([email protected]): make FullMatch() and PartialMatch() work
- // when str contains NUL characters.
static bool FullMatch(const ::std::string& str, const RE& re) {
return FullMatch(str.c_str(), re);
}
@@ -1197,43 +897,30 @@
return PartialMatch(str.c_str(), re);
}
-#if GTEST_HAS_GLOBAL_STRING
-
- static bool FullMatch(const ::string& str, const RE& re) {
- return FullMatch(str.c_str(), re);
- }
- static bool PartialMatch(const ::string& str, const RE& re) {
- return PartialMatch(str.c_str(), re);
- }
-
-#endif // GTEST_HAS_GLOBAL_STRING
-
static bool FullMatch(const char* str, const RE& re);
static bool PartialMatch(const char* str, const RE& re);
private:
void Init(const char* regex);
-
- // We use a const char* instead of an std::string, as Google Test used to be
- // used where std::string is not available. TODO([email protected]): change to
- // std::string.
const char* pattern_;
bool is_valid_;
-#if GTEST_USES_POSIX_RE
+# if GTEST_USES_POSIX_RE
regex_t full_regex_; // For FullMatch().
regex_t partial_regex_; // For PartialMatch().
-#else // GTEST_USES_SIMPLE_RE
+# else // GTEST_USES_SIMPLE_RE
const char* full_pattern_; // For FullMatch();
-#endif
+# endif
GTEST_DISALLOW_ASSIGN_(RE);
};
+#endif // GTEST_USES_PCRE
+
// Formats a source file path and a line number as they would appear
// in an error message from the compiler used to compile this code.
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line);
@@ -1282,7 +969,7 @@
__FILE__, __LINE__).GetStream()
inline void LogToStderr() {}
-inline void FlushInfoLog() { fflush(NULL); }
+inline void FlushInfoLog() { fflush(nullptr); }
#endif // !defined(GTEST_LOG_)
@@ -1319,14 +1006,25 @@
GTEST_LOG_(FATAL) << #posix_call << "failed with error " \
<< gtest_error
-#if GTEST_HAS_STD_MOVE_
-using std::move;
-#else // GTEST_HAS_STD_MOVE_
+// Transforms "T" into "const T&" according to standard reference collapsing
+// rules (this is only needed as a backport for C++98 compilers that do not
+// support reference collapsing). Specifically, it transforms:
+//
+// char ==> const char&
+// const char ==> const char&
+// char& ==> char&
+// const char& ==> const char&
+//
+// Note that the non-const reference will not have "const" added. This is
+// standard, and necessary so that "T" can always bind to "const T&".
template <typename T>
-const T& move(const T& t) {
- return t;
-}
-#endif // GTEST_HAS_STD_MOVE_
+struct ConstRef { typedef const T& type; };
+template <typename T>
+struct ConstRef<T&> { typedef T& type; };
+
+// The argument T must depend on some template parameters.
+#define GTEST_REFERENCE_TO_CONST_(T) \
+ typename ::testing::internal::ConstRef<T>::type
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
@@ -1381,13 +1079,13 @@
GTEST_INTENTIONAL_CONST_COND_PUSH_()
if (false) {
GTEST_INTENTIONAL_CONST_COND_POP_()
- const To to = NULL;
- ::testing::internal::ImplicitCast_<From*>(to);
+ const To to = nullptr;
+ ::testing::internal::ImplicitCast_<From*>(to);
}
#if GTEST_HAS_RTTI
// RTTI: debug mode only!
- GTEST_CHECK_(f == NULL || dynamic_cast<To>(f) != NULL);
+ GTEST_CHECK_(f == nullptr || dynamic_cast<To>(f) != nullptr);
#endif
return static_cast<To>(f);
}
@@ -1426,10 +1124,6 @@
GTEST_API_ std::string GetCapturedStderr();
#endif // GTEST_HAS_STREAM_REDIRECTION
-
-// Returns a path to temporary directory.
-GTEST_API_ std::string TempDir();
-
// Returns the size (in bytes) of a file.
GTEST_API_ size_t GetFileSize(FILE* file);
@@ -1437,14 +1131,15 @@
GTEST_API_ std::string ReadEntireFile(FILE* file);
// All command line arguments.
-GTEST_API_ const ::std::vector<testing::internal::string>& GetArgvs();
+GTEST_API_ std::vector<std::string> GetArgvs();
#if GTEST_HAS_DEATH_TEST
-const ::std::vector<testing::internal::string>& GetInjectableArgvs();
-void SetInjectableArgvs(const ::std::vector<testing::internal::string>*
- new_argvs);
-
+std::vector<std::string> GetInjectableArgvs();
+// Deprecated: pass the args vector by value instead.
+void SetInjectableArgvs(const std::vector<std::string>* new_argvs);
+void SetInjectableArgvs(const std::vector<std::string>& new_argvs);
+void ClearInjectableArgvs();
#endif // GTEST_HAS_DEATH_TEST
@@ -1459,7 +1154,7 @@
0, // 0 seconds.
n * 1000L * 1000L, // And n ms.
};
- nanosleep(&time, NULL);
+ nanosleep(&time, nullptr);
}
# endif // GTEST_HAS_PTHREAD
@@ -1477,7 +1172,7 @@
class Notification {
public:
Notification() : notified_(false) {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
}
~Notification() {
pthread_mutex_destroy(&mutex_);
@@ -1535,7 +1230,8 @@
void Reset(Handle handle);
private:
- // Returns true iff the handle is a valid handle object that can be closed.
+ // Returns true if and only if the handle is a valid handle object that can be
+ // closed.
bool IsCloseable() const;
Handle handle_;
@@ -1586,7 +1282,7 @@
// pass into pthread_create().
extern "C" inline void* ThreadFuncWithCLinkage(void* thread) {
static_cast<ThreadWithParamBase*>(thread)->Run();
- return NULL;
+ return nullptr;
}
// Helper class for testing Google Test's multi-threading constructs.
@@ -1615,20 +1311,19 @@
// The thread can be created only after all fields except thread_
// have been initialized.
GTEST_CHECK_POSIX_SUCCESS_(
- pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base));
+ pthread_create(&thread_, nullptr, &ThreadFuncWithCLinkage, base));
}
- ~ThreadWithParam() { Join(); }
+ ~ThreadWithParam() override { Join(); }
void Join() {
if (!finished_) {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0));
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, nullptr));
finished_ = true;
}
}
- virtual void Run() {
- if (thread_can_start_ != NULL)
- thread_can_start_->WaitForNotification();
+ void Run() override {
+ if (thread_can_start_ != nullptr) thread_can_start_->WaitForNotification();
func_(param_);
}
@@ -1638,7 +1333,8 @@
// When non-NULL, used to block execution until the controller thread
// notifies.
Notification* const thread_can_start_;
- bool finished_; // true iff we know that the thread function has finished.
+ bool finished_; // true if and only if we know that the thread function has
+ // finished.
pthread_t thread_; // The native thread object.
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam);
@@ -1694,7 +1390,7 @@
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
void ThreadSafeLazyInit();
- // Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx,
+ // Per https://blogs.msdn.microsoft.com/oldnewthing/20040223-00/?p=40503,
// we assume that 0 is an invalid value for thread IDs.
unsigned int owner_thread_id_;
@@ -1702,7 +1398,7 @@
// by the linker.
MutexType type_;
long critical_section_init_phase_; // NOLINT
- _RTL_CRITICAL_SECTION* critical_section_;
+ GTEST_CRITICAL_SECTION* critical_section_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex);
};
@@ -1922,7 +1618,7 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory);
};
- scoped_ptr<ValueHolderFactory> default_factory_;
+ std::unique_ptr<ValueHolderFactory> default_factory_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
};
@@ -1978,15 +1674,20 @@
extern ::testing::internal::MutexBase mutex
// Defines and statically (i.e. at link time) initializes a static mutex.
-# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
- ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false, pthread_t() }
+// The initialization list here does not explicitly initialize each field,
+// instead relying on default initialization for the unspecified fields. In
+// particular, the owner_ field (a pthread_t) is not explicitly initialized.
+// This allows initialization to work whether pthread_t is a scalar or struct.
+// The flag -Wmissing-field-initializers must not be specified for this to work.
+#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
+ ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}
// The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise.
class Mutex : public MutexBase {
public:
Mutex() {
- GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL));
+ GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
has_owner_ = false;
}
~Mutex() {
@@ -2036,7 +1737,7 @@
// Implements thread-local storage on pthreads-based systems.
template <typename T>
-class ThreadLocal {
+class GTEST_API_ ThreadLocal {
public:
ThreadLocal()
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
@@ -2084,7 +1785,7 @@
T* GetOrCreateValue() const {
ThreadLocalValueHolderBase* const holder =
static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_));
- if (holder != NULL) {
+ if (holder != nullptr) {
return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
}
@@ -2128,7 +1829,7 @@
// A key pthreads uses for looking up per-thread values.
const pthread_key_t key_;
- scoped_ptr<ValueHolderFactory> default_factory_;
+ std::unique_ptr<ValueHolderFactory> default_factory_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
};
@@ -2168,7 +1869,7 @@
typedef GTestMutexLock MutexLock;
template <typename T>
-class ThreadLocal {
+class GTEST_API_ ThreadLocal {
public:
ThreadLocal() : value_() {}
explicit ThreadLocal(const T& value) : value_(value) {}
@@ -2186,58 +1887,8 @@
// we cannot detect it.
GTEST_API_ size_t GetThreadCount();
-// Passing non-POD classes through ellipsis (...) crashes the ARM
-// compiler and generates a warning in Sun Studio. The Nokia Symbian
-// and the IBM XL C/C++ compiler try to instantiate a copy constructor
-// for objects passed through ellipsis (...), failing for uncopyable
-// objects. We define this to ensure that only POD is passed through
-// ellipsis on these systems.
-#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC)
-// We lose support for NULL detection where the compiler doesn't like
-// passing non-POD classes through ellipsis (...).
-# define GTEST_ELLIPSIS_NEEDS_POD_ 1
-#else
-# define GTEST_CAN_COMPARE_NULL 1
-#endif
-
-// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between
-// const T& and const T* in a function template. These compilers
-// _can_ decide between class template specializations for T and T*,
-// so a tr1::type_traits-like is_pointer works.
-#if defined(__SYMBIAN32__) || defined(__IBMCPP__)
-# define GTEST_NEEDS_IS_POINTER_ 1
-#endif
-
-template <bool bool_value>
-struct bool_constant {
- typedef bool_constant<bool_value> type;
- static const bool value = bool_value;
-};
-template <bool bool_value> const bool bool_constant<bool_value>::value;
-
-typedef bool_constant<false> false_type;
-typedef bool_constant<true> true_type;
-
-template <typename T>
-struct is_pointer : public false_type {};
-
-template <typename T>
-struct is_pointer<T*> : public true_type {};
-
-template <typename Iterator>
-struct IteratorTraits {
- typedef typename Iterator::value_type value_type;
-};
-
-template <typename T>
-struct IteratorTraits<T*> {
- typedef T value_type;
-};
-
-template <typename T>
-struct IteratorTraits<const T*> {
- typedef T value_type;
-};
+template <bool B>
+using bool_constant = std::integral_constant<bool, B>;
#if GTEST_OS_WINDOWS
# define GTEST_PATH_SEP_ "\\"
@@ -2360,7 +2011,7 @@
// Functions deprecated by MSVC 8.0.
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */)
+GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
inline const char* StrNCpy(char* dest, const char* src, size_t n) {
return strncpy(dest, src, n);
@@ -2394,29 +2045,29 @@
inline const char* StrError(int errnum) { return strerror(errnum); }
#endif
inline const char* GetEnv(const char* name) {
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
// We are on Windows CE, which has no environment variables.
static_cast<void>(name); // To prevent 'unused argument' warning.
- return NULL;
+ return nullptr;
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// Environment variables which we programmatically clear will be set to the
// empty string rather than unset (NULL). Handle that case.
const char* const env = getenv(name);
- return (env != NULL && env[0] != '\0') ? env : NULL;
+ return (env != nullptr && env[0] != '\0') ? env : nullptr;
#else
return getenv(name);
#endif
}
-GTEST_DISABLE_MSC_WARNINGS_POP_()
+GTEST_DISABLE_MSC_DEPRECATED_POP_()
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE has no C library. The abort() function is used in
// several places in Google Test. This implementation provides a reasonable
// imitation of standard behaviour.
-void Abort();
+[[noreturn]] void Abort();
#else
-inline void Abort() { abort(); }
+[[noreturn]] inline void Abort() { abort(); }
#endif // GTEST_OS_WINDOWS_MOBILE
} // namespace posix
@@ -2426,13 +2077,12 @@
// MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate
// function in order to achieve that. We use macro definition here because
// snprintf is a variadic function.
-#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE
// MSVC 2005 and above support variadic macros.
# define GTEST_SNPRINTF_(buffer, size, format, ...) \
_snprintf_s(buffer, size, size, format, __VA_ARGS__)
#elif defined(_MSC_VER)
-// Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't
-// complain about _snprintf.
+// Windows CE does not define _snprintf_s
# define GTEST_SNPRINTF_ _snprintf
#else
# define GTEST_SNPRINTF_ snprintf
@@ -2524,15 +2174,15 @@
# define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name)
# define GTEST_DECLARE_int32_(name) \
GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name)
-#define GTEST_DECLARE_string_(name) \
+# define GTEST_DECLARE_string_(name) \
GTEST_API_ extern ::std::string GTEST_FLAG(name)
// Macros for defining flags.
-#define GTEST_DEFINE_bool_(name, default_val, doc) \
+# define GTEST_DEFINE_bool_(name, default_val, doc) \
GTEST_API_ bool GTEST_FLAG(name) = (default_val)
-#define GTEST_DEFINE_int32_(name, default_val, doc) \
+# define GTEST_DEFINE_int32_(name, default_val, doc) \
GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val)
-#define GTEST_DEFINE_string_(name, default_val, doc) \
+# define GTEST_DEFINE_string_(name, default_val, doc) \
GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val)
#endif // !defined(GTEST_DECLARE_bool_)
@@ -2546,18 +2196,36 @@
// Parses 'str' for a 32-bit signed integer. If successful, writes the result
// to *value and returns true; otherwise leaves *value unchanged and returns
// false.
-// TODO(chandlerc): Find a better way to refactor flag and environment parsing
-// out of both gtest-port.cc and gtest.cc to avoid exporting this utility
-// function.
bool ParseInt32(const Message& src_text, const char* str, Int32* value);
// Parses a bool/Int32/string from the environment variable
// corresponding to the given Google Test flag.
bool BoolFromGTestEnv(const char* flag, bool default_val);
GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val);
-std::string StringFromGTestEnv(const char* flag, const char* default_val);
+std::string OutputFlagAlsoCheckEnvVar();
+const char* StringFromGTestEnv(const char* flag, const char* default_val);
} // namespace internal
} // namespace testing
+#if !defined(GTEST_INTERNAL_DEPRECATED)
+
+// Internal Macro to mark an API deprecated, for googletest usage only
+// Usage: class GTEST_INTERNAL_DEPRECATED(message) MyClass or
+// GTEST_INTERNAL_DEPRECATED(message) <return_type> myFunction(); Every usage of
+// a deprecated entity will trigger a warning when compiled with
+// `-Wdeprecated-declarations` option (clang, gcc, any __GNUC__ compiler).
+// For msvc /W3 option will need to be used
+// Note that for 'other' compilers this macro evaluates to nothing to prevent
+// compilations errors.
+#if defined(_MSC_VER)
+#define GTEST_INTERNAL_DEPRECATED(message) __declspec(deprecated(message))
+#elif defined(__GNUC__)
+#define GTEST_INTERNAL_DEPRECATED(message) __attribute__((deprecated(message)))
+#else
+#define GTEST_INTERNAL_DEPRECATED(message)
+#endif
+
+#endif // !defined(GTEST_INTERNAL_DEPRECATED)
+
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h
index 97f1a7f..82aaa63 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-string.h
@@ -27,17 +27,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-// Authors: [email protected] (Zhanyong Wan), [email protected] (Sean Mcafee)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file declares the String class and functions used internally by
// Google Test. They are subject to change without notice. They should not used
// by code external to Google Test.
//
-// This header file is #included by <gtest/internal/gtest-internal.h>.
+// This header file is #included by gtest-internal.h.
// It should not be #included by other files.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
@@ -94,7 +94,8 @@
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#endif
- // Compares two C strings. Returns true iff they have the same content.
+ // Compares two C strings. Returns true if and only if they have the same
+ // content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
@@ -107,16 +108,16 @@
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
- // Compares two wide C strings. Returns true iff they have the same
- // content.
+ // Compares two wide C strings. Returns true if and only if they have the
+ // same content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
- // Compares two C strings, ignoring case. Returns true iff they
- // have the same content.
+ // Compares two C strings, ignoring case. Returns true if and only if
+ // they have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
@@ -124,8 +125,8 @@
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
- // Compares two wide C strings, ignoring case. Returns true iff they
- // have the same content.
+ // Compares two wide C strings, ignoring case. Returns true if and only if
+ // they have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
@@ -139,8 +140,8 @@
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
- // Returns true iff the given string ends with the given suffix, ignoring
- // case. Any string is considered to end with an empty suffix.
+ // Returns true if and only if the given string ends with the given suffix,
+ // ignoring case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
@@ -150,6 +151,9 @@
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
+ // Formats an int value as "%X".
+ static std::string FormatHexUInt32(UInt32 value);
+
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
deleted file mode 100644
index e9b4053..0000000
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-tuple.h
+++ /dev/null
@@ -1,1020 +0,0 @@
-// This file was GENERATED by command:
-// pump.py gtest-tuple.h.pump
-// DO NOT EDIT BY HAND!!!
-
-// Copyright 2009 Google Inc.
-// All Rights Reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
-
-// Implements a subset of TR1 tuple needed by Google Test and Google Mock.
-
-#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
-#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
-
-#include <utility> // For ::std::pair.
-
-// The compiler used in Symbian has a bug that prevents us from declaring the
-// tuple template as a friend (it complains that tuple is redefined). This
-// hack bypasses the bug by declaring the members that should otherwise be
-// private as public.
-// Sun Studio versions < 12 also have the above bug.
-#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590)
-# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public:
-#else
-# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \
- template <GTEST_10_TYPENAMES_(U)> friend class tuple; \
- private:
-#endif
-
-// Visual Studio 2010, 2012, and 2013 define symbols in std::tr1 that conflict
-// with our own definitions. Therefore using our own tuple does not work on
-// those compilers.
-#if defined(_MSC_VER) && _MSC_VER >= 1600 /* 1600 is Visual Studio 2010 */
-# error "gtest's tuple doesn't compile on Visual Studio 2010 or later. \
-GTEST_USE_OWN_TR1_TUPLE must be set to 0 on those compilers."
-#endif
-
-// GTEST_n_TUPLE_(T) is the type of an n-tuple.
-#define GTEST_0_TUPLE_(T) tuple<>
-#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \
- void, void, void>
-#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \
- void, void, void>
-#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \
- void, void, void>
-#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \
- void, void, void>
-#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \
- void, void, void>
-#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \
- void, void, void>
-#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
- void, void, void>
-#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
- T##7, void, void>
-#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
- T##7, T##8, void>
-#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \
- T##7, T##8, T##9>
-
-// GTEST_n_TYPENAMES_(T) declares a list of n typenames.
-#define GTEST_0_TYPENAMES_(T)
-#define GTEST_1_TYPENAMES_(T) typename T##0
-#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1
-#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2
-#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3
-#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3, typename T##4
-#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3, typename T##4, typename T##5
-#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3, typename T##4, typename T##5, typename T##6
-#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3, typename T##4, typename T##5, typename T##6, typename T##7
-#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3, typename T##4, typename T##5, typename T##6, \
- typename T##7, typename T##8
-#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \
- typename T##3, typename T##4, typename T##5, typename T##6, \
- typename T##7, typename T##8, typename T##9
-
-// In theory, defining stuff in the ::std namespace is undefined
-// behavior. We can do this as we are playing the role of a standard
-// library vendor.
-namespace std {
-namespace tr1 {
-
-template <typename T0 = void, typename T1 = void, typename T2 = void,
- typename T3 = void, typename T4 = void, typename T5 = void,
- typename T6 = void, typename T7 = void, typename T8 = void,
- typename T9 = void>
-class tuple;
-
-// Anything in namespace gtest_internal is Google Test's INTERNAL
-// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code.
-namespace gtest_internal {
-
-// ByRef<T>::type is T if T is a reference; otherwise it's const T&.
-template <typename T>
-struct ByRef { typedef const T& type; }; // NOLINT
-template <typename T>
-struct ByRef<T&> { typedef T& type; }; // NOLINT
-
-// A handy wrapper for ByRef.
-#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type
-
-// AddRef<T>::type is T if T is a reference; otherwise it's T&. This
-// is the same as tr1::add_reference<T>::type.
-template <typename T>
-struct AddRef { typedef T& type; }; // NOLINT
-template <typename T>
-struct AddRef<T&> { typedef T& type; }; // NOLINT
-
-// A handy wrapper for AddRef.
-#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type
-
-// A helper for implementing get<k>().
-template <int k> class Get;
-
-// A helper for implementing tuple_element<k, T>. kIndexValid is true
-// iff k < the number of fields in tuple type T.
-template <bool kIndexValid, int kIndex, class Tuple>
-struct TupleElement;
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 0, GTEST_10_TUPLE_(T) > {
- typedef T0 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 1, GTEST_10_TUPLE_(T) > {
- typedef T1 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 2, GTEST_10_TUPLE_(T) > {
- typedef T2 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 3, GTEST_10_TUPLE_(T) > {
- typedef T3 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 4, GTEST_10_TUPLE_(T) > {
- typedef T4 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 5, GTEST_10_TUPLE_(T) > {
- typedef T5 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 6, GTEST_10_TUPLE_(T) > {
- typedef T6 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 7, GTEST_10_TUPLE_(T) > {
- typedef T7 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 8, GTEST_10_TUPLE_(T) > {
- typedef T8 type;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct TupleElement<true, 9, GTEST_10_TUPLE_(T) > {
- typedef T9 type;
-};
-
-} // namespace gtest_internal
-
-template <>
-class tuple<> {
- public:
- tuple() {}
- tuple(const tuple& /* t */) {}
- tuple& operator=(const tuple& /* t */) { return *this; }
-};
-
-template <GTEST_1_TYPENAMES_(T)>
-class GTEST_1_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {}
-
- tuple(const tuple& t) : f0_(t.f0_) {}
-
- template <GTEST_1_TYPENAMES_(U)>
- tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_1_TYPENAMES_(U)>
- tuple& operator=(const GTEST_1_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_1_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) {
- f0_ = t.f0_;
- return *this;
- }
-
- T0 f0_;
-};
-
-template <GTEST_2_TYPENAMES_(T)>
-class GTEST_2_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0),
- f1_(f1) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {}
-
- template <GTEST_2_TYPENAMES_(U)>
- tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {}
- template <typename U0, typename U1>
- tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_2_TYPENAMES_(U)>
- tuple& operator=(const GTEST_2_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
- template <typename U0, typename U1>
- tuple& operator=(const ::std::pair<U0, U1>& p) {
- f0_ = p.first;
- f1_ = p.second;
- return *this;
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_2_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
-};
-
-template <GTEST_3_TYPENAMES_(T)>
-class GTEST_3_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
-
- template <GTEST_3_TYPENAMES_(U)>
- tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_3_TYPENAMES_(U)>
- tuple& operator=(const GTEST_3_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_3_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
-};
-
-template <GTEST_4_TYPENAMES_(T)>
-class GTEST_4_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2),
- f3_(f3) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {}
-
- template <GTEST_4_TYPENAMES_(U)>
- tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_4_TYPENAMES_(U)>
- tuple& operator=(const GTEST_4_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_4_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
-};
-
-template <GTEST_5_TYPENAMES_(T)>
-class GTEST_5_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3,
- GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
- f4_(t.f4_) {}
-
- template <GTEST_5_TYPENAMES_(U)>
- tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_), f4_(t.f4_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_5_TYPENAMES_(U)>
- tuple& operator=(const GTEST_5_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_5_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- f4_ = t.f4_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
- T4 f4_;
-};
-
-template <GTEST_6_TYPENAMES_(T)>
-class GTEST_6_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
- GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
- f5_(f5) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
- f4_(t.f4_), f5_(t.f5_) {}
-
- template <GTEST_6_TYPENAMES_(U)>
- tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_6_TYPENAMES_(U)>
- tuple& operator=(const GTEST_6_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_6_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- f4_ = t.f4_;
- f5_ = t.f5_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
- T4 f4_;
- T5 f5_;
-};
-
-template <GTEST_7_TYPENAMES_(T)>
-class GTEST_7_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
- GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2),
- f3_(f3), f4_(f4), f5_(f5), f6_(f6) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
- f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
-
- template <GTEST_7_TYPENAMES_(U)>
- tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_7_TYPENAMES_(U)>
- tuple& operator=(const GTEST_7_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_7_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- f4_ = t.f4_;
- f5_ = t.f5_;
- f6_ = t.f6_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
- T4 f4_;
- T5 f5_;
- T6 f6_;
-};
-
-template <GTEST_8_TYPENAMES_(T)>
-class GTEST_8_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
- GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6,
- GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
- f5_(f5), f6_(f6), f7_(f7) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
- f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
-
- template <GTEST_8_TYPENAMES_(U)>
- tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_8_TYPENAMES_(U)>
- tuple& operator=(const GTEST_8_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_8_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- f4_ = t.f4_;
- f5_ = t.f5_;
- f6_ = t.f6_;
- f7_ = t.f7_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
- T4 f4_;
- T5 f5_;
- T6 f6_;
- T7 f7_;
-};
-
-template <GTEST_9_TYPENAMES_(T)>
-class GTEST_9_TUPLE_(T) {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
- GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
- GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4),
- f5_(f5), f6_(f6), f7_(f7), f8_(f8) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
- f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
-
- template <GTEST_9_TYPENAMES_(U)>
- tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_9_TYPENAMES_(U)>
- tuple& operator=(const GTEST_9_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_9_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- f4_ = t.f4_;
- f5_ = t.f5_;
- f6_ = t.f6_;
- f7_ = t.f7_;
- f8_ = t.f8_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
- T4 f4_;
- T5 f5_;
- T6 f6_;
- T7 f7_;
- T8 f8_;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-class tuple {
- public:
- template <int k> friend class gtest_internal::Get;
-
- tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(),
- f9_() {}
-
- explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1,
- GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4,
- GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7,
- GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2),
- f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {}
-
- tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_),
- f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {}
-
- template <GTEST_10_TYPENAMES_(U)>
- tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_),
- f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_),
- f9_(t.f9_) {}
-
- tuple& operator=(const tuple& t) { return CopyFrom(t); }
-
- template <GTEST_10_TYPENAMES_(U)>
- tuple& operator=(const GTEST_10_TUPLE_(U)& t) {
- return CopyFrom(t);
- }
-
- GTEST_DECLARE_TUPLE_AS_FRIEND_
-
- template <GTEST_10_TYPENAMES_(U)>
- tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) {
- f0_ = t.f0_;
- f1_ = t.f1_;
- f2_ = t.f2_;
- f3_ = t.f3_;
- f4_ = t.f4_;
- f5_ = t.f5_;
- f6_ = t.f6_;
- f7_ = t.f7_;
- f8_ = t.f8_;
- f9_ = t.f9_;
- return *this;
- }
-
- T0 f0_;
- T1 f1_;
- T2 f2_;
- T3 f3_;
- T4 f4_;
- T5 f5_;
- T6 f6_;
- T7 f7_;
- T8 f8_;
- T9 f9_;
-};
-
-// 6.1.3.2 Tuple creation functions.
-
-// Known limitations: we don't support passing an
-// std::tr1::reference_wrapper<T> to make_tuple(). And we don't
-// implement tie().
-
-inline tuple<> make_tuple() { return tuple<>(); }
-
-template <GTEST_1_TYPENAMES_(T)>
-inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) {
- return GTEST_1_TUPLE_(T)(f0);
-}
-
-template <GTEST_2_TYPENAMES_(T)>
-inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) {
- return GTEST_2_TUPLE_(T)(f0, f1);
-}
-
-template <GTEST_3_TYPENAMES_(T)>
-inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) {
- return GTEST_3_TUPLE_(T)(f0, f1, f2);
-}
-
-template <GTEST_4_TYPENAMES_(T)>
-inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3) {
- return GTEST_4_TUPLE_(T)(f0, f1, f2, f3);
-}
-
-template <GTEST_5_TYPENAMES_(T)>
-inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3, const T4& f4) {
- return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4);
-}
-
-template <GTEST_6_TYPENAMES_(T)>
-inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3, const T4& f4, const T5& f5) {
- return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5);
-}
-
-template <GTEST_7_TYPENAMES_(T)>
-inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3, const T4& f4, const T5& f5, const T6& f6) {
- return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6);
-}
-
-template <GTEST_8_TYPENAMES_(T)>
-inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) {
- return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7);
-}
-
-template <GTEST_9_TYPENAMES_(T)>
-inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
- const T8& f8) {
- return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8);
-}
-
-template <GTEST_10_TYPENAMES_(T)>
-inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2,
- const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7,
- const T8& f8, const T9& f9) {
- return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9);
-}
-
-// 6.1.3.3 Tuple helper classes.
-
-template <typename Tuple> struct tuple_size;
-
-template <GTEST_0_TYPENAMES_(T)>
-struct tuple_size<GTEST_0_TUPLE_(T) > {
- static const int value = 0;
-};
-
-template <GTEST_1_TYPENAMES_(T)>
-struct tuple_size<GTEST_1_TUPLE_(T) > {
- static const int value = 1;
-};
-
-template <GTEST_2_TYPENAMES_(T)>
-struct tuple_size<GTEST_2_TUPLE_(T) > {
- static const int value = 2;
-};
-
-template <GTEST_3_TYPENAMES_(T)>
-struct tuple_size<GTEST_3_TUPLE_(T) > {
- static const int value = 3;
-};
-
-template <GTEST_4_TYPENAMES_(T)>
-struct tuple_size<GTEST_4_TUPLE_(T) > {
- static const int value = 4;
-};
-
-template <GTEST_5_TYPENAMES_(T)>
-struct tuple_size<GTEST_5_TUPLE_(T) > {
- static const int value = 5;
-};
-
-template <GTEST_6_TYPENAMES_(T)>
-struct tuple_size<GTEST_6_TUPLE_(T) > {
- static const int value = 6;
-};
-
-template <GTEST_7_TYPENAMES_(T)>
-struct tuple_size<GTEST_7_TUPLE_(T) > {
- static const int value = 7;
-};
-
-template <GTEST_8_TYPENAMES_(T)>
-struct tuple_size<GTEST_8_TUPLE_(T) > {
- static const int value = 8;
-};
-
-template <GTEST_9_TYPENAMES_(T)>
-struct tuple_size<GTEST_9_TUPLE_(T) > {
- static const int value = 9;
-};
-
-template <GTEST_10_TYPENAMES_(T)>
-struct tuple_size<GTEST_10_TUPLE_(T) > {
- static const int value = 10;
-};
-
-template <int k, class Tuple>
-struct tuple_element {
- typedef typename gtest_internal::TupleElement<
- k < (tuple_size<Tuple>::value), k, Tuple>::type type;
-};
-
-#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type
-
-// 6.1.3.4 Element access.
-
-namespace gtest_internal {
-
-template <>
-class Get<0> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
- Field(Tuple& t) { return t.f0_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple))
- ConstField(const Tuple& t) { return t.f0_; }
-};
-
-template <>
-class Get<1> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
- Field(Tuple& t) { return t.f1_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple))
- ConstField(const Tuple& t) { return t.f1_; }
-};
-
-template <>
-class Get<2> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
- Field(Tuple& t) { return t.f2_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple))
- ConstField(const Tuple& t) { return t.f2_; }
-};
-
-template <>
-class Get<3> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
- Field(Tuple& t) { return t.f3_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple))
- ConstField(const Tuple& t) { return t.f3_; }
-};
-
-template <>
-class Get<4> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
- Field(Tuple& t) { return t.f4_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple))
- ConstField(const Tuple& t) { return t.f4_; }
-};
-
-template <>
-class Get<5> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
- Field(Tuple& t) { return t.f5_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple))
- ConstField(const Tuple& t) { return t.f5_; }
-};
-
-template <>
-class Get<6> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
- Field(Tuple& t) { return t.f6_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple))
- ConstField(const Tuple& t) { return t.f6_; }
-};
-
-template <>
-class Get<7> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
- Field(Tuple& t) { return t.f7_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple))
- ConstField(const Tuple& t) { return t.f7_; }
-};
-
-template <>
-class Get<8> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
- Field(Tuple& t) { return t.f8_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple))
- ConstField(const Tuple& t) { return t.f8_; }
-};
-
-template <>
-class Get<9> {
- public:
- template <class Tuple>
- static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
- Field(Tuple& t) { return t.f9_; } // NOLINT
-
- template <class Tuple>
- static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple))
- ConstField(const Tuple& t) { return t.f9_; }
-};
-
-} // namespace gtest_internal
-
-template <int k, GTEST_10_TYPENAMES_(T)>
-GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
-get(GTEST_10_TUPLE_(T)& t) {
- return gtest_internal::Get<k>::Field(t);
-}
-
-template <int k, GTEST_10_TYPENAMES_(T)>
-GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T)))
-get(const GTEST_10_TUPLE_(T)& t) {
- return gtest_internal::Get<k>::ConstField(t);
-}
-
-// 6.1.3.5 Relational operators
-
-// We only implement == and !=, as we don't have a need for the rest yet.
-
-namespace gtest_internal {
-
-// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the
-// first k fields of t1 equals the first k fields of t2.
-// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if
-// k1 != k2.
-template <int kSize1, int kSize2>
-struct SameSizeTuplePrefixComparator;
-
-template <>
-struct SameSizeTuplePrefixComparator<0, 0> {
- template <class Tuple1, class Tuple2>
- static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) {
- return true;
- }
-};
-
-template <int k>
-struct SameSizeTuplePrefixComparator<k, k> {
- template <class Tuple1, class Tuple2>
- static bool Eq(const Tuple1& t1, const Tuple2& t2) {
- return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) &&
- ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2);
- }
-};
-
-} // namespace gtest_internal
-
-template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
-inline bool operator==(const GTEST_10_TUPLE_(T)& t,
- const GTEST_10_TUPLE_(U)& u) {
- return gtest_internal::SameSizeTuplePrefixComparator<
- tuple_size<GTEST_10_TUPLE_(T) >::value,
- tuple_size<GTEST_10_TUPLE_(U) >::value>::Eq(t, u);
-}
-
-template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)>
-inline bool operator!=(const GTEST_10_TUPLE_(T)& t,
- const GTEST_10_TUPLE_(U)& u) { return !(t == u); }
-
-// 6.1.4 Pairs.
-// Unimplemented.
-
-} // namespace tr1
-} // namespace std
-
-#undef GTEST_0_TUPLE_
-#undef GTEST_1_TUPLE_
-#undef GTEST_2_TUPLE_
-#undef GTEST_3_TUPLE_
-#undef GTEST_4_TUPLE_
-#undef GTEST_5_TUPLE_
-#undef GTEST_6_TUPLE_
-#undef GTEST_7_TUPLE_
-#undef GTEST_8_TUPLE_
-#undef GTEST_9_TUPLE_
-#undef GTEST_10_TUPLE_
-
-#undef GTEST_0_TYPENAMES_
-#undef GTEST_1_TYPENAMES_
-#undef GTEST_2_TYPENAMES_
-#undef GTEST_3_TYPENAMES_
-#undef GTEST_4_TYPENAMES_
-#undef GTEST_5_TYPENAMES_
-#undef GTEST_6_TYPENAMES_
-#undef GTEST_7_TYPENAMES_
-#undef GTEST_8_TYPENAMES_
-#undef GTEST_9_TYPENAMES_
-#undef GTEST_10_TYPENAMES_
-
-#undef GTEST_DECLARE_TUPLE_AS_FRIEND_
-#undef GTEST_BY_REF_
-#undef GTEST_ADD_REF_
-#undef GTEST_TUPLE_ELEMENT_
-
-#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
index e46f7cf..3d7542d 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/include/gtest/internal/gtest-type-util.h
@@ -30,17 +30,17 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
// Type utilities needed for implementing typed and type-parameterized
// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// Currently we support at most 50 types in a list, and at most 50
-// type-parameterized tests in one type-parameterized test case.
+// type-parameterized tests in one type-parameterized test suite.
// Please contact [email protected] if you need
// more.
+// GOOGLETEST_CM0001 DO NOT DELETE
+
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
@@ -57,6 +57,22 @@
namespace testing {
namespace internal {
+// Canonicalizes a given name with respect to the Standard C++ Library.
+// This handles removing the inline namespace within `std` that is
+// used by various standard libraries (e.g., `std::__1`). Names outside
+// of namespace std are returned unmodified.
+inline std::string CanonicalizeForStdLibVersioning(std::string s) {
+ static const char prefix[] = "std::__";
+ if (s.compare(0, strlen(prefix), prefix) == 0) {
+ std::string::size_type end = s.find("::", strlen(prefix));
+ if (end != s.npos) {
+ // Erase everything between the initial `std` and the second `::`.
+ s.erase(strlen("std"), end - strlen("std"));
+ }
+ }
+ return s;
+}
+
// GetTypeName<T>() returns a human-readable name of type T.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
@@ -72,10 +88,10 @@
# if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_
- char* const readable_name = __cxa_demangle(name, 0, 0, &status);
+ char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
const std::string name_str(status == 0 ? readable_name : name);
free(readable_name);
- return name_str;
+ return CanonicalizeForStdLibVersioning(name_str);
# else
return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
@@ -89,18 +105,6 @@
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
-// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same
-// type. This can be used as a compile-time assertion to ensure that
-// two types are equal.
-
-template <typename T1, typename T2>
-struct AssertTypeEq;
-
-template <typename T>
-struct AssertTypeEq<T, T> {
- typedef bool type;
-};
-
// A unique type used as the default value for the arguments of class
// template Types. This allows us to simulate variadic templates
// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't
@@ -3295,8 +3299,8 @@
};
// The TypeList template makes it possible to use either a single type
-// or a Types<...> list in TYPED_TEST_CASE() and
-// INSTANTIATE_TYPED_TEST_CASE_P().
+// or a Types<...> list in TYPED_TEST_SUITE() and
+// INSTANTIATE_TYPED_TEST_SUITE_P().
template <typename T>
struct TypeList {
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-all.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-all.cc
index 0a9cee5..ad29290 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-all.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-all.cc
@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Markus Heule)
-//
-// Google C++ Testing Framework (Google Test)
+// Google C++ Testing and Mocking Framework (Google Test)
//
// Sometimes it's desirable to build Google Test by compiling a single file.
// This file serves this purpose.
@@ -42,6 +41,7 @@
#include "src/gtest.cc"
#include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc"
+#include "src/gtest-matchers.cc"
#include "src/gtest-port.cc"
#include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc"
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-death-test.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-death-test.cc
index cb8a836..5d1031b 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-death-test.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-death-test.cc
@@ -26,12 +26,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan), [email protected] (Vlad Losev)
+
//
// This file implements death tests.
#include "gtest/gtest-death-test.h"
+
+#include <utility>
+
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/custom/gtest.h"
@@ -62,26 +64,36 @@
# include <spawn.h>
# endif // GTEST_OS_QNX
+# if GTEST_OS_FUCHSIA
+# include <lib/fdio/fd.h>
+# include <lib/fdio/io.h>
+# include <lib/fdio/spawn.h>
+# include <lib/zx/channel.h>
+# include <lib/zx/port.h>
+# include <lib/zx/process.h>
+# include <lib/zx/socket.h>
+# include <zircon/processargs.h>
+# include <zircon/syscalls.h>
+# include <zircon/syscalls/policy.h>
+# include <zircon/syscalls/port.h>
+# endif // GTEST_OS_FUCHSIA
+
#endif // GTEST_HAS_DEATH_TEST
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-string.h"
-
-// Indicates that this translation unit is part of Google Test's
-// implementation. It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error. This trick exists to
-// prevent the accidental inclusion of gtest-internal-inl.h in the
-// user's code.
-#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
-#undef GTEST_IMPLEMENTATION_
namespace testing {
// Constants.
// The default death test style.
-static const char kDefaultDeathTestStyle[] = "fast";
+//
+// This is defined in internal/gtest-port.h as "fast", but can be overridden by
+// a definition in internal/custom/gtest-port.h. The recommended value, which is
+// used internally at Google, is "threadsafe".
+static const char kDefaultDeathTestStyle[] = GTEST_DEFAULT_DEATH_TEST_STYLE;
GTEST_DEFINE_string_(
death_test_style,
@@ -110,8 +122,8 @@
"Indicates the file, line number, temporal index of "
"the single death test to run, and a file descriptor to "
"which a success code may be sent, all separated by "
- "the '|' characters. This flag is specified if and only if the current "
- "process is a sub-process launched for running a thread-safe "
+ "the '|' characters. This flag is specified if and only if the "
+ "current process is a sub-process launched for running a thread-safe "
"death test. FOR INTERNAL USE ONLY.");
} // namespace internal
@@ -121,7 +133,7 @@
// Valid only for fast death tests. Indicates the code is running in the
// child process of a fast style death test.
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
static bool g_in_fast_death_test_child = false;
# endif
@@ -131,10 +143,10 @@
// tests. IMPORTANT: This is an internal utility. Using it may break the
// implementation of death tests. User code MUST NOT use it.
bool InDeathTestChild() {
-# if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
- // On Windows, death tests are thread-safe regardless of the value of the
- // death_test_style flag.
+ // On Windows and Fuchsia, death tests are thread-safe regardless of the value
+ // of the death_test_style flag.
return !GTEST_FLAG(internal_run_death_test).empty();
# else
@@ -154,7 +166,7 @@
// ExitedWithCode function-call operator.
bool ExitedWithCode::operator()(int exit_status) const {
-# if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
return exit_status == exit_code_;
@@ -162,10 +174,10 @@
return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_;
-# endif // GTEST_OS_WINDOWS
+# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
}
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// KilledBySignal constructor.
KilledBySignal::KilledBySignal(int signum) : signum_(signum) {
}
@@ -182,7 +194,7 @@
# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_)
return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_;
}
-# endif // !GTEST_OS_WINDOWS
+# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
namespace internal {
@@ -193,7 +205,7 @@
static std::string ExitSummary(int exit_code) {
Message m;
-# if GTEST_OS_WINDOWS
+# if GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
m << "Exited with exit status " << exit_code;
@@ -209,7 +221,7 @@
m << " (core dumped)";
}
# endif
-# endif // GTEST_OS_WINDOWS
+# endif // GTEST_OS_WINDOWS || GTEST_OS_FUCHSIA
return m.GetString();
}
@@ -220,7 +232,7 @@
return !ExitedWithCode(0)(exit_status);
}
-# if !GTEST_OS_WINDOWS
+# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Generates a textual failure message when a death test finds more than
// one thread running, or cannot determine the number of threads, prior
// to executing the given statement. It is the responsibility of the
@@ -229,13 +241,19 @@
Message msg;
msg << "Death tests use fork(), which is unsafe particularly"
<< " in a threaded context. For this test, " << GTEST_NAME_ << " ";
- if (thread_count == 0)
+ if (thread_count == 0) {
msg << "couldn't detect the number of threads.";
- else
+ } else {
msg << "detected " << thread_count << " threads.";
+ }
+ msg << " See "
+ "https://github.com/google/googletest/blob/master/googletest/docs/"
+ "advanced.md#death-tests-and-threads"
+ << " for more explanation and suggested solutions, especially if"
+ << " this is the last message you see before your test times out.";
return msg.GetString();
}
-# endif // !GTEST_OS_WINDOWS
+# endif // !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
// Flag characters for reporting a death test that did not die.
static const char kDeathTestLived = 'L';
@@ -243,6 +261,13 @@
static const char kDeathTestThrew = 'T';
static const char kDeathTestInternalError = 'I';
+#if GTEST_OS_FUCHSIA
+
+// File descriptor used for the pipe in the child process.
+static const int kFuchsiaReadPipeFd = 3;
+
+#endif
+
// An enumeration describing all of the possible ways that a death test can
// conclude. DIED means that the process died while executing the test
// code; LIVED means that process lived beyond the end of the test code;
@@ -250,8 +275,6 @@
// statement, which is not allowed; THREW means that the test statement
// returned control by throwing an exception. IN_PROGRESS means the test
// has not yet concluded.
-// TODO([email protected]): Unify names and possibly values for
-// AbortReason, DeathTestOutcome, and flag characters above.
enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW };
// Routine for aborting the program which is safe to call from an
@@ -259,13 +282,13 @@
// message is propagated back to the parent process. Otherwise, the
// message is simply printed to stderr. In either case, the program
// then exits with status 1.
-void DeathTestAbort(const std::string& message) {
+static void DeathTestAbort(const std::string& message) {
// On a POSIX system, this function may be called from a threadsafe-style
// death test child process, which operates on a very small stack. Use
// the heap for any additional non-minuscule memory requirements.
const InternalRunDeathTestFlag* const flag =
GetUnitTestImpl()->internal_run_death_test_flag();
- if (flag != NULL) {
+ if (flag != nullptr) {
FILE* parent = posix::FDOpen(flag->write_fd(), "w");
fputc(kDeathTestInternalError, parent);
fprintf(parent, "%s", message.c_str());
@@ -345,7 +368,7 @@
// for the current test.
DeathTest::DeathTest() {
TestInfo* const info = GetUnitTestImpl()->current_test_info();
- if (info == NULL) {
+ if (info == nullptr) {
DeathTestAbort("Cannot run a death test outside of a TEST or "
"TEST_F construct");
}
@@ -353,10 +376,11 @@
// Creates and returns a death test by dispatching to the current
// death test factory.
-bool DeathTest::Create(const char* statement, const RE* regex,
- const char* file, int line, DeathTest** test) {
+bool DeathTest::Create(const char* statement,
+ Matcher<const std::string&> matcher, const char* file,
+ int line, DeathTest** test) {
return GetUnitTestImpl()->death_test_factory()->Create(
- statement, regex, file, line, test);
+ statement, std::move(matcher), file, line, test);
}
const char* DeathTest::LastMessage() {
@@ -372,9 +396,9 @@
// Provides cross platform implementation for some death functionality.
class DeathTestImpl : public DeathTest {
protected:
- DeathTestImpl(const char* a_statement, const RE* a_regex)
+ DeathTestImpl(const char* a_statement, Matcher<const std::string&> matcher)
: statement_(a_statement),
- regex_(a_regex),
+ matcher_(std::move(matcher)),
spawned_(false),
status_(-1),
outcome_(IN_PROGRESS),
@@ -382,13 +406,12 @@
write_fd_(-1) {}
// read_fd_ is expected to be closed and cleared by a derived class.
- ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
+ ~DeathTestImpl() override { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); }
- void Abort(AbortReason reason);
- virtual bool Passed(bool status_ok);
+ void Abort(AbortReason reason) override;
+ bool Passed(bool status_ok) override;
const char* statement() const { return statement_; }
- const RE* regex() const { return regex_; }
bool spawned() const { return spawned_; }
void set_spawned(bool is_spawned) { spawned_ = is_spawned; }
int status() const { return status_; }
@@ -406,13 +429,15 @@
// case of unexpected codes.
void ReadAndInterpretStatusByte();
+ // Returns stderr output from the child process.
+ virtual std::string GetErrorLogs();
+
private:
// The textual content of the code this object is testing. This class
// doesn't own this string and should not attempt to delete it.
const char* const statement_;
- // The regular expression which test output must match. DeathTestImpl
- // doesn't own this object and should not attempt to delete it.
- const RE* const regex_;
+ // A matcher that's expected to match the stderr output by the child process.
+ Matcher<const std::string&> matcher_;
// True if the death test child process has been successfully spawned.
bool spawned_;
// The exit status of the child process.
@@ -474,6 +499,10 @@
set_read_fd(-1);
}
+std::string DeathTestImpl::GetErrorLogs() {
+ return GetCapturedStderr();
+}
+
// Signals that the death test code which should have exited, didn't.
// Should be called only in a death test child process.
// Writes a status byte to the child's status file descriptor, then
@@ -527,22 +556,21 @@
// in the format specified by wait(2). On Windows, this is the
// value supplied to the ExitProcess() API or a numeric code
// of the exception that terminated the program.
-// regex: A regular expression object to be applied to
-// the test's captured standard error output; the death test
-// fails if it does not match.
+// matcher_: A matcher that's expected to match the stderr output by the child
+// process.
//
// Argument:
// status_ok: true if exit_status is acceptable in the context of
// this particular death test, which fails if it is false
//
-// Returns true iff all of the above conditions are met. Otherwise, the
-// first failing condition, in the order given above, is the one that is
+// Returns true if and only if all of the above conditions are met. Otherwise,
+// the first failing condition, in the order given above, is the one that is
// reported. Also sets the last death test message string.
bool DeathTestImpl::Passed(bool status_ok) {
if (!spawned())
return false;
- const std::string error_message = GetCapturedStderr();
+ const std::string error_message = GetErrorLogs();
bool success = false;
Message buffer;
@@ -563,13 +591,15 @@
break;
case DIED:
if (status_ok) {
- const bool matched = RE::PartialMatch(error_message.c_str(), *regex());
- if (matched) {
+ if (matcher_.Matches(error_message)) {
success = true;
} else {
+ std::ostringstream stream;
+ matcher_.DescribeTo(&stream);
buffer << " Result: died but not with expected error.\n"
- << " Expected: " << regex()->pattern() << "\n"
- << "Actual msg:\n" << FormatDeathTestOutput(error_message);
+ << " Expected: " << stream.str() << "\n"
+ << "Actual msg:\n"
+ << FormatDeathTestOutput(error_message);
}
} else {
buffer << " Result: died but not with expected exit code:\n"
@@ -618,11 +648,11 @@
//
class WindowsDeathTest : public DeathTestImpl {
public:
- WindowsDeathTest(const char* a_statement,
- const RE* a_regex,
- const char* file,
- int line)
- : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {}
+ WindowsDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
+ const char* file, int line)
+ : DeathTestImpl(a_statement, std::move(matcher)),
+ file_(file),
+ line_(line) {}
// All of these virtual functions are inherited from DeathTest.
virtual int Wait();
@@ -699,7 +729,7 @@
const TestInfo* const info = impl->current_test_info();
const int death_test_index = info->result()->death_test_count();
- if (flag != NULL) {
+ if (flag != nullptr) {
// ParseInternalRunDeathTestFlag() has performed all the necessary
// processing.
set_write_fd(flag->write_fd());
@@ -708,8 +738,8 @@
// WindowsDeathTest uses an anonymous pipe to communicate results of
// a death test.
- SECURITY_ATTRIBUTES handles_are_inheritable = {
- sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
+ SECURITY_ATTRIBUTES handles_are_inheritable = {sizeof(SECURITY_ATTRIBUTES),
+ nullptr, TRUE};
HANDLE read_handle, write_handle;
GTEST_DEATH_TEST_CHECK_(
::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable,
@@ -720,13 +750,13 @@
write_handle_.Reset(write_handle);
event_handle_.Reset(::CreateEvent(
&handles_are_inheritable,
- TRUE, // The event will automatically reset to non-signaled state.
- FALSE, // The initial state is non-signalled.
- NULL)); // The even is unnamed.
- GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL);
- const std::string filter_flag =
- std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" +
- info->test_case_name() + "." + info->name();
+ TRUE, // The event will automatically reset to non-signaled state.
+ FALSE, // The initial state is non-signalled.
+ nullptr)); // The even is unnamed.
+ GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != nullptr);
+ const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
+ kFilterFlag + "=" + info->test_suite_name() +
+ "." + info->name();
const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag +
"=" + file_ + "|" + StreamableToString(line_) + "|" +
@@ -739,10 +769,9 @@
"|" + StreamableToString(reinterpret_cast<size_t>(event_handle_.Get()));
char executable_path[_MAX_PATH + 1]; // NOLINT
- GTEST_DEATH_TEST_CHECK_(
- _MAX_PATH + 1 != ::GetModuleFileNameA(NULL,
- executable_path,
- _MAX_PATH));
+ GTEST_DEATH_TEST_CHECK_(_MAX_PATH + 1 != ::GetModuleFileNameA(nullptr,
+ executable_path,
+ _MAX_PATH));
std::string command_line =
std::string(::GetCommandLineA()) + " " + filter_flag + " \"" +
@@ -763,33 +792,290 @@
startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
PROCESS_INFORMATION process_info;
- GTEST_DEATH_TEST_CHECK_(::CreateProcessA(
- executable_path,
- const_cast<char*>(command_line.c_str()),
- NULL, // Retuned process handle is not inheritable.
- NULL, // Retuned thread handle is not inheritable.
- TRUE, // Child inherits all inheritable handles (for write_handle_).
- 0x0, // Default creation flags.
- NULL, // Inherit the parent's environment.
- UnitTest::GetInstance()->original_working_dir(),
- &startup_info,
- &process_info) != FALSE);
+ GTEST_DEATH_TEST_CHECK_(
+ ::CreateProcessA(
+ executable_path, const_cast<char*>(command_line.c_str()),
+ nullptr, // Retuned process handle is not inheritable.
+ nullptr, // Retuned thread handle is not inheritable.
+ TRUE, // Child inherits all inheritable handles (for write_handle_).
+ 0x0, // Default creation flags.
+ nullptr, // Inherit the parent's environment.
+ UnitTest::GetInstance()->original_working_dir(), &startup_info,
+ &process_info) != FALSE);
child_handle_.Reset(process_info.hProcess);
::CloseHandle(process_info.hThread);
set_spawned(true);
return OVERSEE_TEST;
}
-# else // We are not on Windows.
+
+# elif GTEST_OS_FUCHSIA
+
+class FuchsiaDeathTest : public DeathTestImpl {
+ public:
+ FuchsiaDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
+ const char* file, int line)
+ : DeathTestImpl(a_statement, std::move(matcher)),
+ file_(file),
+ line_(line) {}
+
+ // All of these virtual functions are inherited from DeathTest.
+ int Wait() override;
+ TestRole AssumeRole() override;
+ std::string GetErrorLogs() override;
+
+ private:
+ // The name of the file in which the death test is located.
+ const char* const file_;
+ // The line number on which the death test is located.
+ const int line_;
+ // The stderr data captured by the child process.
+ std::string captured_stderr_;
+
+ zx::process child_process_;
+ zx::channel exception_channel_;
+ zx::socket stderr_socket_;
+};
+
+// Utility class for accumulating command-line arguments.
+class Arguments {
+ public:
+ Arguments() { args_.push_back(nullptr); }
+
+ ~Arguments() {
+ for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
+ ++i) {
+ free(*i);
+ }
+ }
+ void AddArgument(const char* argument) {
+ args_.insert(args_.end() - 1, posix::StrDup(argument));
+ }
+
+ template <typename Str>
+ void AddArguments(const ::std::vector<Str>& arguments) {
+ for (typename ::std::vector<Str>::const_iterator i = arguments.begin();
+ i != arguments.end();
+ ++i) {
+ args_.insert(args_.end() - 1, posix::StrDup(i->c_str()));
+ }
+ }
+ char* const* Argv() {
+ return &args_[0];
+ }
+
+ int size() {
+ return args_.size() - 1;
+ }
+
+ private:
+ std::vector<char*> args_;
+};
+
+// Waits for the child in a death test to exit, returning its exit
+// status, or 0 if no child process exists. As a side effect, sets the
+// outcome data member.
+int FuchsiaDeathTest::Wait() {
+ const int kProcessKey = 0;
+ const int kSocketKey = 1;
+ const int kExceptionKey = 2;
+
+ if (!spawned())
+ return 0;
+
+ // Create a port to wait for socket/task/exception events.
+ zx_status_t status_zx;
+ zx::port port;
+ status_zx = zx::port::create(0, &port);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+ // Register to wait for the child process to terminate.
+ status_zx = child_process_.wait_async(
+ port, kProcessKey, ZX_PROCESS_TERMINATED, ZX_WAIT_ASYNC_ONCE);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+ // Register to wait for the socket to be readable or closed.
+ status_zx = stderr_socket_.wait_async(
+ port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
+ ZX_WAIT_ASYNC_ONCE);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+ // Register to wait for an exception.
+ status_zx = exception_channel_.wait_async(
+ port, kExceptionKey, ZX_CHANNEL_READABLE, ZX_WAIT_ASYNC_ONCE);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+ bool process_terminated = false;
+ bool socket_closed = false;
+ do {
+ zx_port_packet_t packet = {};
+ status_zx = port.wait(zx::time::infinite(), &packet);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+ if (packet.key == kExceptionKey) {
+ // Process encountered an exception. Kill it directly rather than
+ // letting other handlers process the event. We will get a kProcessKey
+ // event when the process actually terminates.
+ status_zx = child_process_.kill();
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+ } else if (packet.key == kProcessKey) {
+ // Process terminated.
+ GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
+ GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_PROCESS_TERMINATED);
+ process_terminated = true;
+ } else if (packet.key == kSocketKey) {
+ GTEST_DEATH_TEST_CHECK_(ZX_PKT_IS_SIGNAL_ONE(packet.type));
+ if (packet.signal.observed & ZX_SOCKET_READABLE) {
+ // Read data from the socket.
+ constexpr size_t kBufferSize = 1024;
+ do {
+ size_t old_length = captured_stderr_.length();
+ size_t bytes_read = 0;
+ captured_stderr_.resize(old_length + kBufferSize);
+ status_zx = stderr_socket_.read(
+ 0, &captured_stderr_.front() + old_length, kBufferSize,
+ &bytes_read);
+ captured_stderr_.resize(old_length + bytes_read);
+ } while (status_zx == ZX_OK);
+ if (status_zx == ZX_ERR_PEER_CLOSED) {
+ socket_closed = true;
+ } else {
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_ERR_SHOULD_WAIT);
+ status_zx = stderr_socket_.wait_async(
+ port, kSocketKey, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
+ ZX_WAIT_ASYNC_ONCE);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+ }
+ } else {
+ GTEST_DEATH_TEST_CHECK_(packet.signal.observed & ZX_SOCKET_PEER_CLOSED);
+ socket_closed = true;
+ }
+ }
+ } while (!process_terminated && !socket_closed);
+
+ ReadAndInterpretStatusByte();
+
+ zx_info_process_t buffer;
+ status_zx = child_process_.get_info(
+ ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr);
+ GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+
+ GTEST_DEATH_TEST_CHECK_(buffer.exited);
+ set_status(buffer.return_code);
+ return status();
+}
+
+// The AssumeRole process for a Fuchsia death test. It creates a child
+// process with the same executable as the current process to run the
+// death test. The child process is given the --gtest_filter and
+// --gtest_internal_run_death_test flags such that it knows to run the
+// current death test only.
+DeathTest::TestRole FuchsiaDeathTest::AssumeRole() {
+ const UnitTestImpl* const impl = GetUnitTestImpl();
+ const InternalRunDeathTestFlag* const flag =
+ impl->internal_run_death_test_flag();
+ const TestInfo* const info = impl->current_test_info();
+ const int death_test_index = info->result()->death_test_count();
+
+ if (flag != nullptr) {
+ // ParseInternalRunDeathTestFlag() has performed all the necessary
+ // processing.
+ set_write_fd(kFuchsiaReadPipeFd);
+ return EXECUTE_TEST;
+ }
+
+ // Flush the log buffers since the log streams are shared with the child.
+ FlushInfoLog();
+
+ // Build the child process command line.
+ const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
+ kFilterFlag + "=" + info->test_suite_name() +
+ "." + info->name();
+ const std::string internal_flag =
+ std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
+ + file_ + "|"
+ + StreamableToString(line_) + "|"
+ + StreamableToString(death_test_index);
+ Arguments args;
+ args.AddArguments(GetInjectableArgvs());
+ args.AddArgument(filter_flag.c_str());
+ args.AddArgument(internal_flag.c_str());
+
+ // Build the pipe for communication with the child.
+ zx_status_t status;
+ zx_handle_t child_pipe_handle;
+ int child_pipe_fd;
+ status = fdio_pipe_half(&child_pipe_fd, &child_pipe_handle);
+ GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+ set_read_fd(child_pipe_fd);
+
+ // Set the pipe handle for the child.
+ fdio_spawn_action_t spawn_actions[2] = {};
+ fdio_spawn_action_t* add_handle_action = &spawn_actions[0];
+ add_handle_action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;
+ add_handle_action->h.id = PA_HND(PA_FD, kFuchsiaReadPipeFd);
+ add_handle_action->h.handle = child_pipe_handle;
+
+ // Create a socket pair will be used to receive the child process' stderr.
+ zx::socket stderr_producer_socket;
+ status =
+ zx::socket::create(0, &stderr_producer_socket, &stderr_socket_);
+ GTEST_DEATH_TEST_CHECK_(status >= 0);
+ int stderr_producer_fd = -1;
+ status =
+ fdio_fd_create(stderr_producer_socket.release(), &stderr_producer_fd);
+ GTEST_DEATH_TEST_CHECK_(status >= 0);
+
+ // Make the stderr socket nonblocking.
+ GTEST_DEATH_TEST_CHECK_(fcntl(stderr_producer_fd, F_SETFL, 0) == 0);
+
+ fdio_spawn_action_t* add_stderr_action = &spawn_actions[1];
+ add_stderr_action->action = FDIO_SPAWN_ACTION_CLONE_FD;
+ add_stderr_action->fd.local_fd = stderr_producer_fd;
+ add_stderr_action->fd.target_fd = STDERR_FILENO;
+
+ // Create a child job.
+ zx_handle_t child_job = ZX_HANDLE_INVALID;
+ status = zx_job_create(zx_job_default(), 0, & child_job);
+ GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+ zx_policy_basic_t policy;
+ policy.condition = ZX_POL_NEW_ANY;
+ policy.policy = ZX_POL_ACTION_ALLOW;
+ status = zx_job_set_policy(
+ child_job, ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC, &policy, 1);
+ GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+
+ // Create an exception channel attached to the |child_job|, to allow
+ // us to suppress the system default exception handler from firing.
+ status =
+ zx_task_create_exception_channel(
+ child_job, 0, exception_channel_.reset_and_get_address());
+ GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+
+ // Spawn the child process.
+ status = fdio_spawn_etc(
+ child_job, FDIO_SPAWN_CLONE_ALL, args.Argv()[0], args.Argv(), nullptr,
+ 2, spawn_actions, child_process_.reset_and_get_address(), nullptr);
+ GTEST_DEATH_TEST_CHECK_(status == ZX_OK);
+
+ set_spawned(true);
+ return OVERSEE_TEST;
+}
+
+std::string FuchsiaDeathTest::GetErrorLogs() {
+ return captured_stderr_;
+}
+
+#else // We are neither on Windows, nor on Fuchsia.
// ForkingDeathTest provides implementations for most of the abstract
// methods of the DeathTest interface. Only the AssumeRole method is
// left undefined.
class ForkingDeathTest : public DeathTestImpl {
public:
- ForkingDeathTest(const char* statement, const RE* regex);
+ ForkingDeathTest(const char* statement, Matcher<const std::string&> matcher);
// All of these virtual functions are inherited from DeathTest.
- virtual int Wait();
+ int Wait() override;
protected:
void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; }
@@ -800,9 +1086,9 @@
};
// Constructs a ForkingDeathTest.
-ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex)
- : DeathTestImpl(a_statement, a_regex),
- child_pid_(-1) {}
+ForkingDeathTest::ForkingDeathTest(const char* a_statement,
+ Matcher<const std::string&> matcher)
+ : DeathTestImpl(a_statement, std::move(matcher)), child_pid_(-1) {}
// Waits for the child in a death test to exit, returning its exit
// status, or 0 if no child process exists. As a side effect, sets the
@@ -823,9 +1109,9 @@
// in the child process.
class NoExecDeathTest : public ForkingDeathTest {
public:
- NoExecDeathTest(const char* a_statement, const RE* a_regex) :
- ForkingDeathTest(a_statement, a_regex) { }
- virtual TestRole AssumeRole();
+ NoExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher)
+ : ForkingDeathTest(a_statement, std::move(matcher)) {}
+ TestRole AssumeRole() override;
};
// The AssumeRole process for a fork-and-run death test. It implements a
@@ -878,16 +1164,18 @@
// only this specific death test to be run.
class ExecDeathTest : public ForkingDeathTest {
public:
- ExecDeathTest(const char* a_statement, const RE* a_regex,
- const char* file, int line) :
- ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { }
- virtual TestRole AssumeRole();
+ ExecDeathTest(const char* a_statement, Matcher<const std::string&> matcher,
+ const char* file, int line)
+ : ForkingDeathTest(a_statement, std::move(matcher)),
+ file_(file),
+ line_(line) {}
+ TestRole AssumeRole() override;
+
private:
- static ::std::vector<testing::internal::string>
- GetArgvsForDeathTestChildProcess() {
- ::std::vector<testing::internal::string> args = GetInjectableArgvs();
+ static ::std::vector<std::string> GetArgvsForDeathTestChildProcess() {
+ ::std::vector<std::string> args = GetInjectableArgvs();
# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
- ::std::vector<testing::internal::string> extra_args =
+ ::std::vector<std::string> extra_args =
GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_();
args.insert(args.end(), extra_args.begin(), extra_args.end());
# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_)
@@ -902,9 +1190,7 @@
// Utility class for accumulating command-line arguments.
class Arguments {
public:
- Arguments() {
- args_.push_back(NULL);
- }
+ Arguments() { args_.push_back(nullptr); }
~Arguments() {
for (std::vector<char*>::iterator i = args_.begin(); i != args_.end();
@@ -986,6 +1272,7 @@
}
# endif // !GTEST_OS_QNX
+# if GTEST_HAS_CLONE
// Two utility routines that together determine the direction the stack
// grows.
// This could be accomplished more elegantly by a single recursive
@@ -995,20 +1282,26 @@
// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining
// StackLowerThanAddress into StackGrowsDown, which then doesn't give
// correct answer.
-void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_;
-void StackLowerThanAddress(const void* ptr, bool* result) {
+static void StackLowerThanAddress(const void* ptr,
+ bool* result) GTEST_NO_INLINE_;
+// HWAddressSanitizer add a random tag to the MSB of the local variable address,
+// making comparison result unpredictable.
+GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
+static void StackLowerThanAddress(const void* ptr, bool* result) {
int dummy;
*result = (&dummy < ptr);
}
// Make sure AddressSanitizer does not tamper with the stack here.
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
-bool StackGrowsDown() {
+GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
+static bool StackGrowsDown() {
int dummy;
bool result;
StackLowerThanAddress(&dummy, &result);
return result;
}
+# endif // GTEST_HAS_CLONE
// Spawns a child process with the same executable as the current process in
// a thread-safe manner and instructs it to run the death test. The
@@ -1046,7 +1339,8 @@
fd_flags | FD_CLOEXEC));
struct inheritance inherit = {0};
// spawn is a system call.
- child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron());
+ child_pid =
+ spawn(args.argv[0], 0, nullptr, &inherit, args.argv, GetEnviron());
// Restores the current working directory.
GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1);
GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd));
@@ -1070,9 +1364,9 @@
if (!use_fork) {
static const bool stack_grows_down = StackGrowsDown();
- const size_t stack_size = getpagesize() * 2;
+ const auto stack_size = static_cast<size_t>(getpagesize() * 2);
// MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead.
- void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE,
+ void* const stack = mmap(nullptr, stack_size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED);
@@ -1086,8 +1380,9 @@
void* const stack_top =
static_cast<char*>(stack) +
(stack_grows_down ? stack_size - kMaxStackAlignment : 0);
- GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment &&
- reinterpret_cast<intptr_t>(stack_top) % kMaxStackAlignment == 0);
+ GTEST_DEATH_TEST_CHECK_(
+ static_cast<size_t>(stack_size) > kMaxStackAlignment &&
+ reinterpret_cast<uintptr_t>(stack_top) % kMaxStackAlignment == 0);
child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args);
@@ -1104,7 +1399,7 @@
# endif // GTEST_OS_QNX
# if GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_SYSCALL_(
- sigaction(SIGPROF, &saved_sigprof_action, NULL));
+ sigaction(SIGPROF, &saved_sigprof_action, nullptr));
# endif // GTEST_OS_LINUX
GTEST_DEATH_TEST_CHECK_(child_pid != -1);
@@ -1122,7 +1417,7 @@
const TestInfo* const info = impl->current_test_info();
const int death_test_index = info->result()->death_test_count();
- if (flag != NULL) {
+ if (flag != nullptr) {
set_write_fd(flag->write_fd());
return EXECUTE_TEST;
}
@@ -1133,9 +1428,9 @@
// it be closed when the child process does an exec:
GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1);
- const std::string filter_flag =
- std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "="
- + info->test_case_name() + "." + info->name();
+ const std::string filter_flag = std::string("--") + GTEST_FLAG_PREFIX_ +
+ kFilterFlag + "=" + info->test_suite_name() +
+ "." + info->name();
const std::string internal_flag =
std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "="
+ file_ + "|" + StreamableToString(line_) + "|"
@@ -1168,7 +1463,8 @@
// by the "test" argument to its address. If the test should be
// skipped, sets that pointer to NULL. Returns true, unless the
// flag is set to an invalid value.
-bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
+bool DefaultDeathTestFactory::Create(const char* statement,
+ Matcher<const std::string&> matcher,
const char* file, int line,
DeathTest** test) {
UnitTestImpl* const impl = GetUnitTestImpl();
@@ -1177,7 +1473,7 @@
const int death_test_index = impl->current_test_info()
->increment_death_test_count();
- if (flag != NULL) {
+ if (flag != nullptr) {
if (death_test_index > flag->index()) {
DeathTest::set_last_death_test_message(
"Death test count (" + StreamableToString(death_test_index)
@@ -1188,7 +1484,7 @@
if (!(flag->file() == file && flag->line() == line &&
flag->index() == death_test_index)) {
- *test = NULL;
+ *test = nullptr;
return true;
}
}
@@ -1197,15 +1493,22 @@
if (GTEST_FLAG(death_test_style) == "threadsafe" ||
GTEST_FLAG(death_test_style) == "fast") {
- *test = new WindowsDeathTest(statement, regex, file, line);
+ *test = new WindowsDeathTest(statement, std::move(matcher), file, line);
+ }
+
+# elif GTEST_OS_FUCHSIA
+
+ if (GTEST_FLAG(death_test_style) == "threadsafe" ||
+ GTEST_FLAG(death_test_style) == "fast") {
+ *test = new FuchsiaDeathTest(statement, std::move(matcher), file, line);
}
# else
if (GTEST_FLAG(death_test_style) == "threadsafe") {
- *test = new ExecDeathTest(statement, regex, file, line);
+ *test = new ExecDeathTest(statement, std::move(matcher), file, line);
} else if (GTEST_FLAG(death_test_style) == "fast") {
- *test = new NoExecDeathTest(statement, regex);
+ *test = new NoExecDeathTest(statement, std::move(matcher));
}
# endif // GTEST_OS_WINDOWS
@@ -1224,7 +1527,7 @@
// Recreates the pipe and event handles from the provided parameters,
// signals the event, and returns a file descriptor wrapped around the pipe
// handle. This function is called in the child process only.
-int GetStatusFileDescriptor(unsigned int parent_process_id,
+static int GetStatusFileDescriptor(unsigned int parent_process_id,
size_t write_handle_as_size_t,
size_t event_handle_as_size_t) {
AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE,
@@ -1235,15 +1538,13 @@
StreamableToString(parent_process_id));
}
- // TODO([email protected]): Replace the following check with a
- // compile-time assertion when available.
GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t));
const HANDLE write_handle =
reinterpret_cast<HANDLE>(write_handle_as_size_t);
HANDLE dup_write_handle;
- // The newly initialized handle is accessible only in in the parent
+ // The newly initialized handle is accessible only in the parent
// process. To obtain one accessible within the child, we need to use
// DuplicateHandle.
if (!::DuplicateHandle(parent_process_handle.Get(), write_handle,
@@ -1292,7 +1593,7 @@
// initialized from the GTEST_FLAG(internal_run_death_test) flag if
// the flag is specified; otherwise returns NULL.
InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() {
- if (GTEST_FLAG(internal_run_death_test) == "") return NULL;
+ if (GTEST_FLAG(internal_run_death_test) == "") return nullptr;
// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
// can use it here.
@@ -1320,6 +1621,16 @@
write_fd = GetStatusFileDescriptor(parent_process_id,
write_handle_as_size_t,
event_handle_as_size_t);
+
+# elif GTEST_OS_FUCHSIA
+
+ if (fields.size() != 3
+ || !ParseNaturalNumber(fields[1], &line)
+ || !ParseNaturalNumber(fields[2], &index)) {
+ DeathTestAbort("Bad --gtest_internal_run_death_test flag: "
+ + GTEST_FLAG(internal_run_death_test));
+ }
+
# else
if (fields.size() != 4
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-filepath.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-filepath.cc
index 3bb2754..bd7b99f 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-filepath.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-filepath.cc
@@ -26,28 +26,25 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: [email protected] (Keith Ray)
-#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-filepath.h"
-#include "gtest/internal/gtest-port.h"
#include <stdlib.h>
+#include "gtest/internal/gtest-port.h"
+#include "gtest/gtest-message.h"
#if GTEST_OS_WINDOWS_MOBILE
# include <windows.h>
#elif GTEST_OS_WINDOWS
# include <direct.h>
# include <io.h>
-#elif GTEST_OS_SYMBIAN
-// Symbian OpenC has PATH_MAX in sys/syslimits.h
-# include <sys/syslimits.h>
#else
# include <limits.h>
# include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE
+#include "gtest/internal/gtest-string.h"
+
#if GTEST_OS_WINDOWS
# define GTEST_PATH_MAX_ _MAX_PATH
#elif defined(PATH_MAX)
@@ -58,8 +55,6 @@
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#endif // GTEST_OS_WINDOWS
-#include "gtest/internal/gtest-string.h"
-
namespace testing {
namespace internal {
@@ -97,13 +92,14 @@
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
- // Windows CE doesn't have a current directory, so we just return
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
+ GTEST_OS_WINDOWS_RT || ARDUINO || defined(ESP_PLATFORM)
+ // These platforms do not have a current directory, so we just return
// something reasonable.
return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
- return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd);
+ return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
#else
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
char* result = getcwd(cwd, sizeof(cwd));
@@ -111,9 +107,9 @@
// getcwd will likely fail in NaCl due to the sandbox, so return something
// reasonable. The user may have provided a shim implementation for getcwd,
// however, so fallback only when failure is detected.
- return FilePath(result == NULL ? kCurrentDirectoryString : cwd);
+ return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
# endif // GTEST_OS_NACL
- return FilePath(result == NULL ? "" : cwd);
+ return FilePath(result == nullptr ? "" : cwd);
#endif // GTEST_OS_WINDOWS_MOBILE
}
@@ -138,8 +134,8 @@
#if GTEST_HAS_ALT_PATH_SEP_
const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator);
// Comparing two pointers of which only one is NULL is undefined.
- if (last_alt_sep != NULL &&
- (last_sep == NULL || last_alt_sep > last_sep)) {
+ if (last_alt_sep != nullptr &&
+ (last_sep == nullptr || last_alt_sep > last_sep)) {
return last_alt_sep;
}
#endif
@@ -167,7 +163,7 @@
const char* const last_sep = FindLastPathSeparator();
std::string dir;
if (last_sep) {
- dir = std::string(c_str(), last_sep + 1 - c_str());
+ dir = std::string(c_str(), static_cast<size_t>(last_sep + 1 - c_str()));
} else {
dir = kCurrentDirectoryString;
}
@@ -252,9 +248,6 @@
// root directory per disk drive.)
bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS
- // TODO([email protected]): on Windows a network share like
- // \\server\share can be a root directory, although it cannot be the
- // current directory. Handle this properly.
return pathname_.length() == 3 && IsAbsolutePath();
#else
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
@@ -326,7 +319,7 @@
#if GTEST_OS_WINDOWS_MOBILE
FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
- int result = CreateDirectory(unicode, NULL) ? 0 : -1;
+ int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
delete [] unicode;
#elif GTEST_OS_WINDOWS
int result = _mkdir(pathname_.c_str());
@@ -352,9 +345,8 @@
// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
-// TODO([email protected]): handle Windows network shares (e.g. \\server\share).
void FilePath::Normalize() {
- if (pathname_.c_str() == NULL) {
+ if (pathname_.c_str() == nullptr) {
pathname_ = "";
return;
}
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-internal-inl.h b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-internal-inl.h
index ed8a682..8ed70da 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-internal-inl.h
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-internal-inl.h
@@ -27,24 +27,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// Utility functions and classes used by the Google C++ testing framework.
-//
-// Author: [email protected] (Zhanyong Wan)
-//
+// Utility functions and classes used by the Google C++ testing framework.//
// This file contains purely Google Test's internal implementation. Please
// DO NOT #INCLUDE IT IN A USER PROGRAM.
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
#define GTEST_SRC_GTEST_INTERNAL_INL_H_
-// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is
-// part of Google Test's implementation; otherwise it's undefined.
-#if !GTEST_IMPLEMENTATION_
-// If this file is included from the user's code, just say no.
-# error "gtest-internal-inl.h is part of Google Test's internal implementation."
-# error "It must not be included except by Google Test itself."
-#endif // GTEST_IMPLEMENTATION_
-
#ifndef _WIN32_WCE
# include <errno.h>
#endif // !_WIN32_WCE
@@ -53,6 +42,7 @@
#include <string.h> // For memmove.
#include <algorithm>
+#include <memory>
#include <string>
#include <vector>
@@ -67,9 +57,12 @@
# include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS
-#include "gtest/gtest.h" // NOLINT
+#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
+GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
+/* class A needs to have dll-interface to be used by clients of class B */)
+
namespace testing {
// Declares the flags.
@@ -94,6 +87,7 @@
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kPrintTimeFlag[] = "print_time";
+const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
@@ -105,14 +99,14 @@
// A valid random seed must be in [1, kMaxRandomSeed].
const int kMaxRandomSeed = 99999;
-// g_help_flag is true iff the --help flag or an equivalent form is
-// specified on the command line.
+// g_help_flag is true if and only if the --help flag or an equivalent form
+// is specified on the command line.
GTEST_API_ extern bool g_help_flag;
// Returns the current time in milliseconds.
GTEST_API_ TimeInMillis GetTimeInMillis();
-// Returns true iff Google Test should use colors in the output.
+// Returns true if and only if Google Test should use colors in the output.
GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
// Formats the given time in milliseconds as seconds.
@@ -174,6 +168,7 @@
list_tests_ = GTEST_FLAG(list_tests);
output_ = GTEST_FLAG(output);
print_time_ = GTEST_FLAG(print_time);
+ print_utf8_ = GTEST_FLAG(print_utf8);
random_seed_ = GTEST_FLAG(random_seed);
repeat_ = GTEST_FLAG(repeat);
shuffle_ = GTEST_FLAG(shuffle);
@@ -195,6 +190,7 @@
GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_;
GTEST_FLAG(print_time) = print_time_;
+ GTEST_FLAG(print_utf8) = print_utf8_;
GTEST_FLAG(random_seed) = random_seed_;
GTEST_FLAG(repeat) = repeat_;
GTEST_FLAG(shuffle) = shuffle_;
@@ -216,6 +212,7 @@
bool list_tests_;
std::string output_;
bool print_time_;
+ bool print_utf8_;
internal::Int32 random_seed_;
internal::Int32 repeat_;
bool shuffle_;
@@ -234,7 +231,7 @@
// Converts a wide string to a narrow string in UTF-8 encoding.
// The wide string is assumed to have the following encoding:
-// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
// UTF-32 if sizeof(wchar_t) == 4 (on Linux)
// Parameter str points to a null-terminated wide string.
// Parameter num_chars may additionally limit the number
@@ -269,8 +266,8 @@
GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val);
// Given the total number of shards, the shard index, and the test id,
-// returns true iff the test should be run on this shard. The test id is
-// some arbitrary but unique non-negative integer assigned to each test
+// returns true if and only if the test should be run on this shard. The test id
+// is some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards.
GTEST_API_ bool ShouldRunTestOnShard(
int total_shards, int shard_index, int test_id);
@@ -301,7 +298,8 @@
// in range [0, v.size()).
template <typename E>
inline E GetElementOr(const std::vector<E>& v, int i, E default_value) {
- return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i];
+ return (i < 0 || i >= static_cast<int>(v.size())) ? default_value
+ : v[static_cast<size_t>(i)];
}
// Performs an in-place shuffle of a range of the vector's elements.
@@ -323,8 +321,11 @@
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
for (int range_width = end - begin; range_width >= 2; range_width--) {
const int last_in_range = begin + range_width - 1;
- const int selected = begin + random->Generate(range_width);
- std::swap((*v)[selected], (*v)[last_in_range]);
+ const int selected =
+ begin +
+ static_cast<int>(random->Generate(static_cast<UInt32>(range_width)));
+ std::swap((*v)[static_cast<size_t>(selected)],
+ (*v)[static_cast<size_t>(last_in_range)]);
}
}
@@ -351,7 +352,7 @@
// TestPropertyKeyIs has NO default constructor.
explicit TestPropertyKeyIs(const std::string& key) : key_(key) {}
- // Returns true iff the test name of test property matches on key_.
+ // Returns true if and only if the test name of test property matches on key_.
bool operator()(const TestProperty& test_property) const {
return test_property.key() == key_;
}
@@ -384,17 +385,17 @@
// Functions for processing the gtest_filter flag.
- // Returns true iff the wildcard pattern matches the string. The
- // first ':' or '\0' character in pattern marks the end of it.
+ // Returns true if and only if the wildcard pattern matches the string.
+ // The first ':' or '\0' character in pattern marks the end of it.
//
// This recursive algorithm isn't very efficient, but is clear and
// works well enough for matching test names, which are short.
static bool PatternMatchesString(const char *pattern, const char *str);
- // Returns true iff the user-specified filter matches the test case
- // name and the test name.
- static bool FilterMatchesTest(const std::string &test_case_name,
- const std::string &test_name);
+ // Returns true if and only if the user-specified filter matches the test
+ // suite name and the test name.
+ static bool FilterMatchesTest(const std::string& test_suite_name,
+ const std::string& test_name);
#if GTEST_OS_WINDOWS
// Function for supporting the gtest_catch_exception flag.
@@ -426,7 +427,7 @@
// in the trace.
// skip_count - the number of top frames to be skipped; doesn't count
// against max_depth.
- virtual string CurrentStackTrace(int max_depth, int skip_count) = 0;
+ virtual std::string CurrentStackTrace(int max_depth, int skip_count) = 0;
// UponLeavingGTest() should be called immediately before Google Test calls
// user code. It saves some information about the current stack that
@@ -446,10 +447,20 @@
public:
OsStackTraceGetter() {}
- virtual string CurrentStackTrace(int max_depth, int skip_count);
- virtual void UponLeavingGTest();
+ std::string CurrentStackTrace(int max_depth, int skip_count) override;
+ void UponLeavingGTest() override;
private:
+#if GTEST_HAS_ABSL
+ Mutex mutex_; // Protects all internal state.
+
+ // We save the stack frame below the frame that calls user code.
+ // We do this because the address of the frame immediately below
+ // the user code changes between the call to UponLeavingGTest()
+ // and any calls to the stack trace code from within the user code.
+ void* caller_frame_ = nullptr;
+#endif // GTEST_HAS_ABSL
+
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
};
@@ -468,7 +479,7 @@
explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
// Implements the TestPartResultReporterInterface. Reports the test part
// result in the current test.
- virtual void ReportTestPartResult(const TestPartResult& result);
+ void ReportTestPartResult(const TestPartResult& result) override;
private:
UnitTestImpl* const unit_test_;
@@ -484,7 +495,7 @@
explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test);
// Implements the TestPartResultReporterInterface. The implementation just
// delegates to the current global test part result reporter of *unit_test_.
- virtual void ReportTestPartResult(const TestPartResult& result);
+ void ReportTestPartResult(const TestPartResult& result) override;
private:
UnitTestImpl* const unit_test_;
@@ -522,22 +533,25 @@
void SetTestPartResultReporterForCurrentThread(
TestPartResultReporterInterface* reporter);
- // Gets the number of successful test cases.
- int successful_test_case_count() const;
+ // Gets the number of successful test suites.
+ int successful_test_suite_count() const;
- // Gets the number of failed test cases.
- int failed_test_case_count() const;
+ // Gets the number of failed test suites.
+ int failed_test_suite_count() const;
- // Gets the number of all test cases.
- int total_test_case_count() const;
+ // Gets the number of all test suites.
+ int total_test_suite_count() const;
- // Gets the number of all test cases that contain at least one test
+ // Gets the number of all test suites that contain at least one test
// that should run.
- int test_case_to_run_count() const;
+ int test_suite_to_run_count() const;
// Gets the number of successful tests.
int successful_test_count() const;
+ // Gets the number of skipped tests.
+ int skipped_test_count() const;
+
// Gets the number of failed tests.
int failed_test_count() const;
@@ -563,27 +577,33 @@
// Gets the elapsed time, in milliseconds.
TimeInMillis elapsed_time() const { return elapsed_time_; }
- // Returns true iff the unit test passed (i.e. all test cases passed).
+ // Returns true if and only if the unit test passed (i.e. all test suites
+ // passed).
bool Passed() const { return !Failed(); }
- // Returns true iff the unit test failed (i.e. some test case failed
- // or something outside of all tests failed).
+ // Returns true if and only if the unit test failed (i.e. some test suite
+ // failed or something outside of all tests failed).
bool Failed() const {
- return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed();
+ return failed_test_suite_count() > 0 || ad_hoc_test_result()->Failed();
}
- // Gets the i-th test case among all the test cases. i can range from 0 to
- // total_test_case_count() - 1. If i is not in that range, returns NULL.
- const TestCase* GetTestCase(int i) const {
- const int index = GetElementOr(test_case_indices_, i, -1);
- return index < 0 ? NULL : test_cases_[i];
+ // Gets the i-th test suite among all the test suites. i can range from 0 to
+ // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+ const TestSuite* GetTestSuite(int i) const {
+ const int index = GetElementOr(test_suite_indices_, i, -1);
+ return index < 0 ? nullptr : test_suites_[static_cast<size_t>(i)];
}
- // Gets the i-th test case among all the test cases. i can range from 0 to
- // total_test_case_count() - 1. If i is not in that range, returns NULL.
- TestCase* GetMutableTestCase(int i) {
- const int index = GetElementOr(test_case_indices_, i, -1);
- return index < 0 ? NULL : test_cases_[index];
+ // Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ const TestCase* GetTestCase(int i) const { return GetTestSuite(i); }
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+ // Gets the i-th test suite among all the test suites. i can range from 0 to
+ // total_test_suite_count() - 1. If i is not in that range, returns NULL.
+ TestSuite* GetMutableSuiteCase(int i) {
+ const int index = GetElementOr(test_suite_indices_, i, -1);
+ return index < 0 ? nullptr : test_suites_[static_cast<size_t>(index)];
}
// Provides access to the event listener list.
@@ -620,30 +640,38 @@
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
- // Finds and returns a TestCase with the given name. If one doesn't
+ // Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it.
//
// Arguments:
//
- // test_case_name: name of the test case
+ // test_suite_name: name of the test suite
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
- // set_up_tc: pointer to the function that sets up the test case
- // tear_down_tc: pointer to the function that tears down the test case
- TestCase* GetTestCase(const char* test_case_name,
- const char* type_param,
- Test::SetUpTestCaseFunc set_up_tc,
- Test::TearDownTestCaseFunc tear_down_tc);
+ // set_up_tc: pointer to the function that sets up the test suite
+ // tear_down_tc: pointer to the function that tears down the test suite
+ TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
+ internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc);
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ TestCase* GetTestCase(const char* test_case_name, const char* type_param,
+ internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc) {
+ return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
+ }
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Adds a TestInfo to the unit test.
//
// Arguments:
//
- // set_up_tc: pointer to the function that sets up the test case
- // tear_down_tc: pointer to the function that tears down the test case
+ // set_up_tc: pointer to the function that sets up the test suite
+ // tear_down_tc: pointer to the function that tears down the test suite
// test_info: the TestInfo object
- void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc,
- Test::TearDownTestCaseFunc tear_down_tc,
+ void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc,
TestInfo* test_info) {
// In order to support thread-safe death tests, we need to
// remember the original working directory when the test program
@@ -658,23 +686,20 @@
<< "Failed to get the current working directory.";
}
- GetTestCase(test_info->test_case_name(),
- test_info->type_param(),
- set_up_tc,
- tear_down_tc)->AddTestInfo(test_info);
+ GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
+ set_up_tc, tear_down_tc)
+ ->AddTestInfo(test_info);
}
-#if GTEST_HAS_PARAM_TEST
- // Returns ParameterizedTestCaseRegistry object used to keep track of
+ // Returns ParameterizedTestSuiteRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
- internal::ParameterizedTestCaseRegistry& parameterized_test_registry() {
+ internal::ParameterizedTestSuiteRegistry& parameterized_test_registry() {
return parameterized_test_registry_;
}
-#endif // GTEST_HAS_PARAM_TEST
- // Sets the TestCase object for the test that's currently running.
- void set_current_test_case(TestCase* a_current_test_case) {
- current_test_case_ = a_current_test_case;
+ // Sets the TestSuite object for the test that's currently running.
+ void set_current_test_suite(TestSuite* a_current_test_suite) {
+ current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
@@ -685,7 +710,7 @@
}
// Registers all parameterized tests defined using TEST_P and
- // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter
+ // INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has guards
// protecting from registering the tests more then once. If
// value-parameterized tests are disabled, RegisterParameterizedTests is
@@ -700,7 +725,7 @@
// Clears the results of all tests, except the ad hoc tests.
void ClearNonAdHocTestResult() {
- ForEach(test_cases_, TestCase::ClearTestCaseResult);
+ ForEach(test_suites_, TestSuite::ClearTestSuiteResult);
}
// Clears the results of ad-hoc test assertions.
@@ -709,7 +734,7 @@
}
// Adds a TestProperty to the current TestResult object when invoked in a
- // context of a test or a test case, or to the global property set. If the
+ // context of a test or a test suite, or to the global property set. If the
// result already contains a property with the same key, the value will be
// updated.
void RecordProperty(const TestProperty& test_property);
@@ -721,7 +746,7 @@
// Matches the full name of each test against the user-specified
// filter to decide whether the test should run, then records the
- // result in each TestCase and TestInfo object.
+ // result in each TestSuite and TestInfo object.
// If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests
// based on sharding variables in the environment.
// Returns the number of tests that should run.
@@ -730,7 +755,7 @@
// Prints the names of the tests matching the user-specified filter flag.
void ListTestsMatchingFilter();
- const TestCase* current_test_case() const { return current_test_case_; }
+ const TestSuite* current_test_suite() const { return current_test_suite_; }
TestInfo* current_test_info() { return current_test_info_; }
const TestInfo* current_test_info() const { return current_test_info_; }
@@ -791,11 +816,11 @@
// Gets the random number generator.
internal::Random* random() { return &random_; }
- // Shuffles all test cases, and the tests within each test case,
+ // Shuffles all test suites, and the tests within each test suite,
// making sure that death tests are still run first.
void ShuffleTests();
- // Restores the test cases and tests to their order before the first shuffle.
+ // Restores the test suites and tests to their order before the first shuffle.
void UnshuffleTests();
// Returns the value of GTEST_FLAG(catch_exceptions) at the moment
@@ -835,33 +860,31 @@
// before/after the tests are run.
std::vector<Environment*> environments_;
- // The vector of TestCases in their original order. It owns the
+ // The vector of TestSuites in their original order. It owns the
// elements in the vector.
- std::vector<TestCase*> test_cases_;
+ std::vector<TestSuite*> test_suites_;
- // Provides a level of indirection for the test case list to allow
- // easy shuffling and restoring the test case order. The i-th
- // element of this vector is the index of the i-th test case in the
+ // Provides a level of indirection for the test suite list to allow
+ // easy shuffling and restoring the test suite order. The i-th
+ // element of this vector is the index of the i-th test suite in the
// shuffled order.
- std::vector<int> test_case_indices_;
+ std::vector<int> test_suite_indices_;
-#if GTEST_HAS_PARAM_TEST
// ParameterizedTestRegistry object used to register value-parameterized
// tests.
- internal::ParameterizedTestCaseRegistry parameterized_test_registry_;
+ internal::ParameterizedTestSuiteRegistry parameterized_test_registry_;
// Indicates whether RegisterParameterizedTests() has been called already.
bool parameterized_tests_registered_;
-#endif // GTEST_HAS_PARAM_TEST
- // Index of the last death test case registered. Initially -1.
- int last_death_test_case_;
+ // Index of the last death test suite registered. Initially -1.
+ int last_death_test_suite_;
- // This points to the TestCase for the currently running test. It
- // changes as Google Test goes through one test case after another.
+ // This points to the TestSuite for the currently running test. It
+ // changes as Google Test goes through one test suite after another.
// When no test is running, this is set to NULL and Google Test
// stores assertion results in ad_hoc_test_result_. Initially NULL.
- TestCase* current_test_case_;
+ TestSuite* current_test_suite_;
// This points to the TestInfo for the currently running test. It
// changes as Google Test goes through one test after another. When
@@ -889,7 +912,7 @@
// desired.
OsStackTraceGetterInterface* os_stack_trace_getter_;
- // True iff PostFlagParsingInit() has been called.
+ // True if and only if PostFlagParsingInit() has been called.
bool post_flag_parse_init_performed_;
// The random number seed used at the beginning of the test run.
@@ -908,8 +931,8 @@
#if GTEST_HAS_DEATH_TEST
// The decomposed components of the gtest_internal_run_death_test flag,
// parsed when RUN_ALL_TESTS is called.
- internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
- internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_;
+ std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
+ std::unique_ptr<internal::DeathTestFactory> death_test_factory_;
#endif // GTEST_HAS_DEATH_TEST
// A per-thread stack of traces created by the SCOPED_TRACE() macro.
@@ -992,8 +1015,6 @@
const bool parse_success = *end == '\0' && errno == 0;
- // TODO([email protected]): Convert this to compile time assertion when it is
- // available.
GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed));
const Integer result = static_cast<Integer>(parsed);
@@ -1032,7 +1053,7 @@
#if GTEST_CAN_STREAM_RESULTS_
// Streams test results to the given port on the given host machine.
-class GTEST_API_ StreamingListener : public EmptyTestEventListener {
+class StreamingListener : public EmptyTestEventListener {
public:
// Abstract base class for writing strings to a socket.
class AbstractSocketWriter {
@@ -1040,37 +1061,35 @@
virtual ~AbstractSocketWriter() {}
// Sends a string to the socket.
- virtual void Send(const string& message) = 0;
+ virtual void Send(const std::string& message) = 0;
// Closes the socket.
virtual void CloseConnection() {}
// Sends a string and a newline to the socket.
- void SendLn(const string& message) {
- Send(message + "\n");
- }
+ void SendLn(const std::string& message) { Send(message + "\n"); }
};
// Concrete class for actually writing strings to a socket.
class SocketWriter : public AbstractSocketWriter {
public:
- SocketWriter(const string& host, const string& port)
+ SocketWriter(const std::string& host, const std::string& port)
: sockfd_(-1), host_name_(host), port_num_(port) {
MakeConnection();
}
- virtual ~SocketWriter() {
+ ~SocketWriter() override {
if (sockfd_ != -1)
CloseConnection();
}
// Sends a string to the socket.
- virtual void Send(const string& message) {
+ void Send(const std::string& message) override {
GTEST_CHECK_(sockfd_ != -1)
<< "Send() can be called only when there is a connection.";
- const int len = static_cast<int>(message.length());
- if (write(sockfd_, message.c_str(), len) != len) {
+ const auto len = static_cast<size_t>(message.length());
+ if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
GTEST_LOG_(WARNING)
<< "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_;
@@ -1082,7 +1101,7 @@
void MakeConnection();
// Closes the socket.
- void CloseConnection() {
+ void CloseConnection() override {
GTEST_CHECK_(sockfd_ != -1)
<< "CloseConnection() can be called only when there is a connection.";
@@ -1091,26 +1110,28 @@
}
int sockfd_; // socket file descriptor
- const string host_name_;
- const string port_num_;
+ const std::string host_name_;
+ const std::string port_num_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);
}; // class SocketWriter
// Escapes '=', '&', '%', and '\n' characters in str as "%xx".
- static string UrlEncode(const char* str);
+ static std::string UrlEncode(const char* str);
- StreamingListener(const string& host, const string& port)
- : socket_writer_(new SocketWriter(host, port)) { Start(); }
+ StreamingListener(const std::string& host, const std::string& port)
+ : socket_writer_(new SocketWriter(host, port)) {
+ Start();
+ }
explicit StreamingListener(AbstractSocketWriter* socket_writer)
: socket_writer_(socket_writer) { Start(); }
- void OnTestProgramStart(const UnitTest& /* unit_test */) {
+ void OnTestProgramStart(const UnitTest& /* unit_test */) override {
SendLn("event=TestProgramStart");
}
- void OnTestProgramEnd(const UnitTest& unit_test) {
+ void OnTestProgramEnd(const UnitTest& unit_test) override {
// Note that Google Test current only report elapsed time for each
// test iteration, not for the entire test program.
SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed()));
@@ -1119,42 +1140,47 @@
socket_writer_->CloseConnection();
}
- void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) {
+ void OnTestIterationStart(const UnitTest& /* unit_test */,
+ int iteration) override {
SendLn("event=TestIterationStart&iteration=" +
StreamableToString(iteration));
}
- void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) {
+ void OnTestIterationEnd(const UnitTest& unit_test,
+ int /* iteration */) override {
SendLn("event=TestIterationEnd&passed=" +
FormatBool(unit_test.Passed()) + "&elapsed_time=" +
StreamableToString(unit_test.elapsed_time()) + "ms");
}
- void OnTestCaseStart(const TestCase& test_case) {
+ // Note that "event=TestCaseStart" is a wire format and has to remain
+ // "case" for compatibilty
+ void OnTestCaseStart(const TestCase& test_case) override {
SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
}
- void OnTestCaseEnd(const TestCase& test_case) {
- SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed())
- + "&elapsed_time=" + StreamableToString(test_case.elapsed_time())
- + "ms");
+ // Note that "event=TestCaseEnd" is a wire format and has to remain
+ // "case" for compatibilty
+ void OnTestCaseEnd(const TestCase& test_case) override {
+ SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) +
+ "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) +
+ "ms");
}
- void OnTestStart(const TestInfo& test_info) {
+ void OnTestStart(const TestInfo& test_info) override {
SendLn(std::string("event=TestStart&name=") + test_info.name());
}
- void OnTestEnd(const TestInfo& test_info) {
+ void OnTestEnd(const TestInfo& test_info) override {
SendLn("event=TestEnd&passed=" +
FormatBool((test_info.result())->Passed()) +
"&elapsed_time=" +
StreamableToString((test_info.result())->elapsed_time()) + "ms");
}
- void OnTestPartResult(const TestPartResult& test_part_result) {
+ void OnTestPartResult(const TestPartResult& test_part_result) override {
const char* file_name = test_part_result.file_name();
- if (file_name == NULL)
- file_name = "";
+ if (file_name == nullptr) file_name = "";
SendLn("event=TestPartResult&file=" + UrlEncode(file_name) +
"&line=" + StreamableToString(test_part_result.line_number()) +
"&message=" + UrlEncode(test_part_result.message()));
@@ -1162,15 +1188,15 @@
private:
// Sends the given message and a newline to the socket.
- void SendLn(const string& message) { socket_writer_->SendLn(message); }
+ void SendLn(const std::string& message) { socket_writer_->SendLn(message); }
// Called at the start of streaming to notify the receiver what
// protocol we are using.
void Start() { SendLn("gtest_streaming_protocol_version=1.0"); }
- string FormatBool(bool value) { return value ? "1" : "0"; }
+ std::string FormatBool(bool value) { return value ? "1" : "0"; }
- const scoped_ptr<AbstractSocketWriter> socket_writer_;
+ const std::unique_ptr<AbstractSocketWriter> socket_writer_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
}; // class StreamingListener
@@ -1180,4 +1206,6 @@
} // namespace internal
} // namespace testing
+GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
+
#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-matchers.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-matchers.cc
new file mode 100644
index 0000000..7d2fb68
--- /dev/null
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-matchers.cc
@@ -0,0 +1,97 @@
+// Copyright 2007, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The Google C++ Testing and Mocking Framework (Google Test)
+//
+// This file implements just enough of the matcher interface to allow
+// EXPECT_DEATH and friends to accept a matcher argument.
+
+#include "gtest/internal/gtest-internal.h"
+#include "gtest/internal/gtest-port.h"
+#include "gtest/gtest-matchers.h"
+
+#include <string>
+
+namespace testing {
+
+// Constructs a matcher that matches a const std::string& whose value is
+// equal to s.
+Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }
+
+// Constructs a matcher that matches a const std::string& whose value is
+// equal to s.
+Matcher<const std::string&>::Matcher(const char* s) {
+ *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a std::string whose value is equal to
+// s.
+Matcher<std::string>::Matcher(const std::string& s) { *this = Eq(s); }
+
+// Constructs a matcher that matches a std::string whose value is equal to
+// s.
+Matcher<std::string>::Matcher(const char* s) { *this = Eq(std::string(s)); }
+
+#if GTEST_HAS_ABSL
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(const std::string& s) {
+ *this = Eq(s);
+}
+
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(const char* s) {
+ *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a const absl::string_view& whose value is
+// equal to s.
+Matcher<const absl::string_view&>::Matcher(absl::string_view s) {
+ *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(const std::string& s) { *this = Eq(s); }
+
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(const char* s) {
+ *this = Eq(std::string(s));
+}
+
+// Constructs a matcher that matches a absl::string_view whose value is equal to
+// s.
+Matcher<absl::string_view>::Matcher(absl::string_view s) {
+ *this = Eq(std::string(s));
+}
+#endif // GTEST_HAS_ABSL
+
+} // namespace testing
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-port.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-port.cc
index 6aeef49..fc5ba6b 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-port.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-port.cc
@@ -26,22 +26,25 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
#include "gtest/internal/gtest-port.h"
#include <limits.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <fstream>
+#include <memory>
#if GTEST_OS_WINDOWS
# include <windows.h>
# include <io.h>
# include <sys/stat.h>
# include <map> // Used in ThreadLocal.
+# ifdef _MSC_VER
+# include <crtdbg.h>
+# endif // _MSC_VER
#else
# include <unistd.h>
#endif // GTEST_OS_WINDOWS
@@ -52,6 +55,14 @@
# include <mach/vm_map.h>
#endif // GTEST_OS_MAC
+#if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
+ GTEST_OS_NETBSD || GTEST_OS_OPENBSD
+# include <sys/sysctl.h>
+# if GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
+# include <sys/user.h>
+# endif
+#endif
+
#if GTEST_OS_QNX
# include <devctl.h>
# include <fcntl.h>
@@ -63,19 +74,16 @@
# include <sys/types.h>
#endif // GTEST_OS_AIX
+#if GTEST_OS_FUCHSIA
+# include <zircon/process.h>
+# include <zircon/syscalls.h>
+#endif // GTEST_OS_FUCHSIA
+
#include "gtest/gtest-spi.h"
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
-
-// Indicates that this translation unit is part of Google Test's
-// implementation. It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error. This trick exists to
-// prevent the accidental inclusion of gtest-internal-inl.h in the
-// user's code.
-#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
-#undef GTEST_IMPLEMENTATION_
namespace testing {
namespace internal {
@@ -93,7 +101,7 @@
namespace {
template <typename T>
-T ReadProcFileField(const string& filename, int field) {
+T ReadProcFileField(const std::string& filename, int field) {
std::string dummy;
std::ifstream file(filename.c_str());
while (field-- > 0) {
@@ -107,9 +115,9 @@
// Returns the number of active threads, or 0 when there is an error.
size_t GetThreadCount() {
- const string filename =
+ const std::string filename =
(Message() << "/proc/" << getpid() << "/stat").GetString();
- return ReadProcFileField<int>(filename, 19);
+ return ReadProcFileField<size_t>(filename, 19);
}
#elif GTEST_OS_MAC
@@ -131,6 +139,81 @@
}
}
+#elif GTEST_OS_DRAGONFLY || GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD || \
+ GTEST_OS_NETBSD
+
+#if GTEST_OS_NETBSD
+#undef KERN_PROC
+#define KERN_PROC KERN_PROC2
+#define kinfo_proc kinfo_proc2
+#endif
+
+#if GTEST_OS_DRAGONFLY
+#define KP_NLWP(kp) (kp.kp_nthreads)
+#elif GTEST_OS_FREEBSD || GTEST_OS_GNU_KFREEBSD
+#define KP_NLWP(kp) (kp.ki_numthreads)
+#elif GTEST_OS_NETBSD
+#define KP_NLWP(kp) (kp.p_nlwps)
+#endif
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+ int mib[] = {
+ CTL_KERN,
+ KERN_PROC,
+ KERN_PROC_PID,
+ getpid(),
+#if GTEST_OS_NETBSD
+ sizeof(struct kinfo_proc),
+ 1,
+#endif
+ };
+ u_int miblen = sizeof(mib) / sizeof(mib[0]);
+ struct kinfo_proc info;
+ size_t size = sizeof(info);
+ if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
+ return 0;
+ }
+ return static_cast<size_t>(KP_NLWP(info));
+}
+#elif GTEST_OS_OPENBSD
+
+// Returns the number of threads running in the process, or 0 to indicate that
+// we cannot detect it.
+size_t GetThreadCount() {
+ int mib[] = {
+ CTL_KERN,
+ KERN_PROC,
+ KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
+ getpid(),
+ sizeof(struct kinfo_proc),
+ 0,
+ };
+ u_int miblen = sizeof(mib) / sizeof(mib[0]);
+
+ // get number of structs
+ size_t size;
+ if (sysctl(mib, miblen, NULL, &size, NULL, 0)) {
+ return 0;
+ }
+ mib[5] = size / mib[4];
+
+ // populate array of structs
+ struct kinfo_proc info[mib[5]];
+ if (sysctl(mib, miblen, &info, &size, NULL, 0)) {
+ return 0;
+ }
+
+ // exclude empty members
+ int nthreads = 0;
+ for (int i = 0; i < size / mib[4]; i++) {
+ if (info[i].p_tid != -1)
+ nthreads++;
+ }
+ return nthreads;
+}
+
#elif GTEST_OS_QNX
// Returns the number of threads running in the process, or 0 to indicate that
@@ -142,7 +225,7 @@
}
procfs_info process_info;
const int status =
- devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
+ devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), nullptr);
close(fd);
if (status == EOK) {
return static_cast<size_t>(process_info.num_threads);
@@ -156,7 +239,7 @@
size_t GetThreadCount() {
struct procentry64 entry;
pid_t pid = getpid();
- int status = getprocs64(&entry, sizeof(entry), NULL, 0, &pid, 1);
+ int status = getprocs64(&entry, sizeof(entry), nullptr, 0, &pid, 1);
if (status == 1) {
return entry.pi_thcount;
} else {
@@ -164,6 +247,25 @@
}
}
+#elif GTEST_OS_FUCHSIA
+
+size_t GetThreadCount() {
+ int dummy_buffer;
+ size_t avail;
+ zx_status_t status = zx_object_get_info(
+ zx_process_self(),
+ ZX_INFO_PROCESS_THREADS,
+ &dummy_buffer,
+ 0,
+ nullptr,
+ &avail);
+ if (status == ZX_OK) {
+ return avail;
+ } else {
+ return 0;
+ }
+}
+
#else
size_t GetThreadCount() {
@@ -177,7 +279,7 @@
#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS
void SleepMilliseconds(int n) {
- ::Sleep(n);
+ ::Sleep(static_cast<DWORD>(n));
}
AutoHandle::AutoHandle()
@@ -215,15 +317,15 @@
bool AutoHandle::IsCloseable() const {
// Different Windows APIs may use either of these values to represent an
// invalid handle.
- return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE;
+ return handle_ != nullptr && handle_ != INVALID_HANDLE_VALUE;
}
Notification::Notification()
- : event_(::CreateEvent(NULL, // Default security attributes.
- TRUE, // Do not reset automatically.
- FALSE, // Initially unset.
- NULL)) { // Anonymous event.
- GTEST_CHECK_(event_.Get() != NULL);
+ : event_(::CreateEvent(nullptr, // Default security attributes.
+ TRUE, // Do not reset automatically.
+ FALSE, // Initially unset.
+ nullptr)) { // Anonymous event.
+ GTEST_CHECK_(event_.Get() != nullptr);
}
void Notification::Notify() {
@@ -246,13 +348,10 @@
Mutex::~Mutex() {
// Static mutexes are leaked intentionally. It is not thread-safe to try
// to clean them up.
- // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires
- // nothing to clean it up but is available only on Vista and later.
- // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx
if (type_ == kDynamic) {
::DeleteCriticalSection(critical_section_);
delete critical_section_;
- critical_section_ = NULL;
+ critical_section_ = nullptr;
}
}
@@ -279,6 +378,41 @@
<< "The current thread is not holding the mutex @" << this;
}
+namespace {
+
+#ifdef _MSC_VER
+// Use the RAII idiom to flag mem allocs that are intentionally never
+// deallocated. The motivation is to silence the false positive mem leaks
+// that are reported by the debug version of MS's CRT which can only detect
+// if an alloc is missing a matching deallocation.
+// Example:
+// MemoryIsNotDeallocated memory_is_not_deallocated;
+// critical_section_ = new CRITICAL_SECTION;
+//
+class MemoryIsNotDeallocated
+{
+ public:
+ MemoryIsNotDeallocated() : old_crtdbg_flag_(0) {
+ old_crtdbg_flag_ = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ // Set heap allocation block type to _IGNORE_BLOCK so that MS debug CRT
+ // doesn't report mem leak if there's no matching deallocation.
+ _CrtSetDbgFlag(old_crtdbg_flag_ & ~_CRTDBG_ALLOC_MEM_DF);
+ }
+
+ ~MemoryIsNotDeallocated() {
+ // Restore the original _CRTDBG_ALLOC_MEM_DF flag
+ _CrtSetDbgFlag(old_crtdbg_flag_);
+ }
+
+ private:
+ int old_crtdbg_flag_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(MemoryIsNotDeallocated);
+};
+#endif // _MSC_VER
+
+} // namespace
+
// Initializes owner_thread_id_ and critical_section_ in static mutexes.
void Mutex::ThreadSafeLazyInit() {
// Dynamic mutexes are initialized in the constructor.
@@ -289,7 +423,13 @@
// If critical_section_init_phase_ was 0 before the exchange, we
// are the first to test it and need to perform the initialization.
owner_thread_id_ = 0;
- critical_section_ = new CRITICAL_SECTION;
+ {
+ // Use RAII to flag that following mem alloc is never deallocated.
+#ifdef _MSC_VER
+ MemoryIsNotDeallocated memory_is_not_deallocated;
+#endif // _MSC_VER
+ critical_section_ = new CRITICAL_SECTION;
+ }
::InitializeCriticalSection(critical_section_);
// Updates the critical_section_init_phase_ to 2 to signal
// initialization complete.
@@ -328,17 +468,16 @@
Notification* thread_can_start) {
ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start);
DWORD thread_id;
- // TODO(yukawa): Consider to use _beginthreadex instead.
HANDLE thread_handle = ::CreateThread(
- NULL, // Default security.
- 0, // Default stack size.
+ nullptr, // Default security.
+ 0, // Default stack size.
&ThreadWithParamSupport::ThreadMain,
- param, // Parameter to ThreadMainStatic
- 0x0, // Default creation flags.
+ param, // Parameter to ThreadMainStatic
+ 0x0, // Default creation flags.
&thread_id); // Need a valid pointer for the call to work under Win98.
- GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error "
- << ::GetLastError() << ".";
- if (thread_handle == NULL) {
+ GTEST_CHECK_(thread_handle != nullptr)
+ << "CreateThread failed with error " << ::GetLastError() << ".";
+ if (thread_handle == nullptr) {
delete param;
}
return thread_handle;
@@ -350,15 +489,15 @@
: runnable_(runnable),
thread_can_start_(thread_can_start) {
}
- scoped_ptr<Runnable> runnable_;
+ std::unique_ptr<Runnable> runnable_;
// Does not own.
Notification* thread_can_start_;
};
static DWORD WINAPI ThreadMain(void* ptr) {
// Transfers ownership.
- scoped_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
- if (param->thread_can_start_ != NULL)
+ std::unique_ptr<ThreadMainParam> param(static_cast<ThreadMainParam*>(ptr));
+ if (param->thread_can_start_ != nullptr)
param->thread_can_start_->WaitForNotification();
param->runnable_->Run();
return 0;
@@ -416,7 +555,7 @@
thread_local_values
.insert(std::make_pair(
thread_local_instance,
- linked_ptr<ThreadLocalValueHolderBase>(
+ std::shared_ptr<ThreadLocalValueHolderBase>(
thread_local_instance->NewValueForCurrentThread())))
.first;
}
@@ -425,7 +564,7 @@
static void OnThreadLocalDestroyed(
const ThreadLocalBase* thread_local_instance) {
- std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
+ std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
// Clean up the ThreadLocalValues data structure while holding the lock, but
// defer the destruction of the ThreadLocalValueHolderBases.
{
@@ -453,7 +592,7 @@
static void OnThreadExit(DWORD thread_id) {
GTEST_CHECK_(thread_id != 0) << ::GetLastError();
- std::vector<linked_ptr<ThreadLocalValueHolderBase> > value_holders;
+ std::vector<std::shared_ptr<ThreadLocalValueHolderBase> > value_holders;
// Clean up the ThreadIdToThreadLocals data structure while holding the
// lock, but defer the destruction of the ThreadLocalValueHolderBases.
{
@@ -480,7 +619,8 @@
private:
// In a particular thread, maps a ThreadLocal object to its value.
typedef std::map<const ThreadLocalBase*,
- linked_ptr<ThreadLocalValueHolderBase> > ThreadLocalValues;
+ std::shared_ptr<ThreadLocalValueHolderBase> >
+ ThreadLocalValues;
// Stores all ThreadIdToThreadLocals having values in a thread, indexed by
// thread's ID.
typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
@@ -495,18 +635,17 @@
HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION,
FALSE,
thread_id);
- GTEST_CHECK_(thread != NULL);
+ GTEST_CHECK_(thread != nullptr);
// We need to pass a valid thread ID pointer into CreateThread for it
// to work correctly under Win98.
DWORD watcher_thread_id;
HANDLE watcher_thread = ::CreateThread(
- NULL, // Default security.
- 0, // Default stack size
+ nullptr, // Default security.
+ 0, // Default stack size
&ThreadLocalRegistryImpl::WatcherThreadFunc,
reinterpret_cast<LPVOID>(new ThreadIdAndHandle(thread_id, thread)),
- CREATE_SUSPENDED,
- &watcher_thread_id);
- GTEST_CHECK_(watcher_thread != NULL);
+ CREATE_SUSPENDED, &watcher_thread_id);
+ GTEST_CHECK_(watcher_thread != nullptr);
// Give the watcher thread the same priority as ours to avoid being
// blocked by it.
::SetThreadPriority(watcher_thread,
@@ -531,7 +670,10 @@
// Returns map of thread local instances.
static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() {
mutex_.AssertHeld();
- static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals;
+#ifdef _MSC_VER
+ MemoryIsNotDeallocated memory_is_not_deallocated;
+#endif // _MSC_VER
+ static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals();
return map;
}
@@ -573,7 +715,7 @@
free(const_cast<char*>(pattern_));
}
-// Returns true iff regular expression re matches the entire str.
+// Returns true if and only if regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false;
@@ -581,8 +723,8 @@
return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
}
-// Returns true iff regular expression re matches a substring of str
-// (including str itself).
+// Returns true if and only if regular expression re matches a substring of
+// str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) {
if (!re.is_valid_) return false;
@@ -622,14 +764,14 @@
#elif GTEST_USES_SIMPLE_RE
-// Returns true iff ch appears anywhere in str (excluding the
+// Returns true if and only if ch appears anywhere in str (excluding the
// terminating '\0' character).
bool IsInSet(char ch, const char* str) {
- return ch != '\0' && strchr(str, ch) != NULL;
+ return ch != '\0' && strchr(str, ch) != nullptr;
}
-// Returns true iff ch belongs to the given classification. Unlike
-// similar functions in <ctype.h>, these aren't affected by the
+// Returns true if and only if ch belongs to the given classification.
+// Unlike similar functions in <ctype.h>, these aren't affected by the
// current locale.
bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
bool IsAsciiPunct(char ch) {
@@ -642,13 +784,13 @@
('0' <= ch && ch <= '9') || ch == '_';
}
-// Returns true iff "\\c" is a supported escape sequence.
+// Returns true if and only if "\\c" is a supported escape sequence.
bool IsValidEscape(char c) {
return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
}
-// Returns true iff the given atom (specified by escaped and pattern)
-// matches ch. The result is undefined if the atom is invalid.
+// Returns true if and only if the given atom (specified by escaped and
+// pattern) matches ch. The result is undefined if the atom is invalid.
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
if (escaped) { // "\\p" where p is pattern_char.
switch (pattern_char) {
@@ -671,7 +813,7 @@
}
// Helper function used by ValidateRegex() to format error messages.
-std::string FormatRegexSyntaxError(const char* regex, int index) {
+static std::string FormatRegexSyntaxError(const char* regex, int index) {
return (Message() << "Syntax error at index " << index
<< " in simple regular expression \"" << regex << "\": ").GetString();
}
@@ -679,17 +821,14 @@
// Generates non-fatal failures and returns false if regex is invalid;
// otherwise returns true.
bool ValidateRegex(const char* regex) {
- if (regex == NULL) {
- // TODO([email protected]): fix the source file location in the
- // assertion failures to match where the regex is used in user
- // code.
+ if (regex == nullptr) {
ADD_FAILURE() << "NULL is not a valid simple regular expression.";
return false;
}
bool is_valid = true;
- // True iff ?, *, or + can follow the previous atom.
+ // True if and only if ?, *, or + can follow the previous atom.
bool prev_repeatable = false;
for (int i = 0; regex[i]; i++) {
if (regex[i] == '\\') { // An escape sequence
@@ -765,8 +904,8 @@
return false;
}
-// Returns true iff regex matches a prefix of str. regex must be a
-// valid simple regular expression and not start with "^", or the
+// Returns true if and only if regex matches a prefix of str. regex must
+// be a valid simple regular expression and not start with "^", or the
// result is undefined.
bool MatchRegexAtHead(const char* regex, const char* str) {
if (*regex == '\0') // An empty regex matches a prefix of anything.
@@ -796,8 +935,8 @@
}
}
-// Returns true iff regex matches any substring of str. regex must be
-// a valid simple regular expression, or the result is undefined.
+// Returns true if and only if regex matches any substring of str. regex must
+// be a valid simple regular expression, or the result is undefined.
//
// The algorithm is recursive, but the recursion depth doesn't exceed
// the regex length, so we won't need to worry about running out of
@@ -805,8 +944,7 @@
// exponential with respect to the regex length + the string length,
// but usually it's must faster (often close to linear).
bool MatchRegexAnywhere(const char* regex, const char* str) {
- if (regex == NULL || str == NULL)
- return false;
+ if (regex == nullptr || str == nullptr) return false;
if (*regex == '^')
return MatchRegexAtHead(regex + 1, str);
@@ -826,21 +964,21 @@
free(const_cast<char*>(full_pattern_));
}
-// Returns true iff regular expression re matches the entire str.
+// Returns true if and only if regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
}
-// Returns true iff regular expression re matches a substring of str
-// (including str itself).
+// Returns true if and only if regular expression re matches a substring of
+// str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
}
// Initializes an RE from its string representation.
void RE::Init(const char* regex) {
- pattern_ = full_pattern_ = NULL;
- if (regex != NULL) {
+ pattern_ = full_pattern_ = nullptr;
+ if (regex != nullptr) {
pattern_ = posix::StrDup(regex);
}
@@ -878,7 +1016,7 @@
// Formats a source file path and a line number as they would appear
// in an error message from the compiler used to compile this code.
GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
- const std::string file_name(file == NULL ? kUnknownFile : file);
+ const std::string file_name(file == nullptr ? kUnknownFile : file);
if (line < 0) {
return file_name + ":";
@@ -897,7 +1035,7 @@
// to the file location it produces, unlike FormatFileLocation().
GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
const char* file, int line) {
- const std::string file_name(file == NULL ? kUnknownFile : file);
+ const std::string file_name(file == nullptr ? kUnknownFile : file);
if (line < 0)
return file_name;
@@ -923,9 +1061,10 @@
posix::Abort();
}
}
+
// Disable Microsoft deprecation warnings for POSIX functions called from
// this class (creat, dup, dup2, and close)
-GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
+GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
#if GTEST_HAS_STREAM_REDIRECTION
@@ -963,20 +1102,22 @@
// code as part of a regular standalone executable, which doesn't
// run in a Dalvik process (e.g. when running it through 'adb shell').
//
- // The location /sdcard is directly accessible from native code
- // and is the only location (unofficially) supported by the Android
- // team. It's generally a symlink to the real SD Card mount point
- // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or
- // other OEM-customized locations. Never rely on these, and always
- // use /sdcard.
- char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
+ // The location /data/local/tmp is directly accessible from native code.
+ // '/sdcard' and other variants cannot be relied on, as they are not
+ // guaranteed to be mounted, or may have a delay in mounting.
+ char name_template[] = "/data/local/tmp/gtest_captured_stream.XXXXXX";
# else
char name_template[] = "/tmp/captured_stream.XXXXXX";
# endif // GTEST_OS_LINUX_ANDROID
const int captured_fd = mkstemp(name_template);
+ if (captured_fd == -1) {
+ GTEST_LOG_(WARNING)
+ << "Failed to create tmp file " << name_template
+ << " for test; does the test have access to the /tmp directory?";
+ }
filename_ = name_template;
# endif // GTEST_OS_WINDOWS
- fflush(NULL);
+ fflush(nullptr);
dup2(captured_fd, fd_);
close(captured_fd);
}
@@ -988,13 +1129,17 @@
std::string GetCapturedString() {
if (uncaptured_fd_ != -1) {
// Restores the original stream.
- fflush(NULL);
+ fflush(nullptr);
dup2(uncaptured_fd_, fd_);
close(uncaptured_fd_);
uncaptured_fd_ = -1;
}
FILE* const file = posix::FOpen(filename_.c_str(), "r");
+ if (file == nullptr) {
+ GTEST_LOG_(FATAL) << "Failed to open tmp file " << filename_
+ << " for capturing stream.";
+ }
const std::string content = ReadEntireFile(file);
posix::FClose(file);
return content;
@@ -1009,14 +1154,15 @@
GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
};
-GTEST_DISABLE_MSC_WARNINGS_POP_()
+GTEST_DISABLE_MSC_DEPRECATED_POP_()
-static CapturedStream* g_captured_stderr = NULL;
-static CapturedStream* g_captured_stdout = NULL;
+static CapturedStream* g_captured_stderr = nullptr;
+static CapturedStream* g_captured_stdout = nullptr;
// Starts capturing an output stream (stdout/stderr).
-void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
- if (*stream != NULL) {
+static void CaptureStream(int fd, const char* stream_name,
+ CapturedStream** stream) {
+ if (*stream != nullptr) {
GTEST_LOG_(FATAL) << "Only one " << stream_name
<< " capturer can exist at a time.";
}
@@ -1024,11 +1170,11 @@
}
// Stops capturing the output stream and returns the captured string.
-std::string GetCapturedStream(CapturedStream** captured_stream) {
+static std::string GetCapturedStream(CapturedStream** captured_stream) {
const std::string content = (*captured_stream)->GetCapturedString();
delete *captured_stream;
- *captured_stream = NULL;
+ *captured_stream = nullptr;
return content;
}
@@ -1055,23 +1201,9 @@
#endif // GTEST_HAS_STREAM_REDIRECTION
-std::string TempDir() {
-#if GTEST_OS_WINDOWS_MOBILE
- return "\\temp\\";
-#elif GTEST_OS_WINDOWS
- const char* temp_dir = posix::GetEnv("TEMP");
- if (temp_dir == NULL || temp_dir[0] == '\0')
- return "\\temp\\";
- else if (temp_dir[strlen(temp_dir) - 1] == '\\')
- return temp_dir;
- else
- return std::string(temp_dir) + "\\";
-#elif GTEST_OS_LINUX_ANDROID
- return "/sdcard/";
-#else
- return "/tmp/";
-#endif // GTEST_OS_WINDOWS_MOBILE
-}
+
+
+
size_t GetFileSize(FILE* file) {
fseek(file, 0, SEEK_END);
@@ -1101,22 +1233,30 @@
}
#if GTEST_HAS_DEATH_TEST
+static const std::vector<std::string>* g_injected_test_argvs =
+ nullptr; // Owned.
-static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
- NULL; // Owned.
-
-void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
- if (g_injected_test_argvs != argvs)
- delete g_injected_test_argvs;
- g_injected_test_argvs = argvs;
-}
-
-const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
- if (g_injected_test_argvs != NULL) {
+std::vector<std::string> GetInjectableArgvs() {
+ if (g_injected_test_argvs != nullptr) {
return *g_injected_test_argvs;
}
return GetArgvs();
}
+
+void SetInjectableArgvs(const std::vector<std::string>* new_argvs) {
+ if (g_injected_test_argvs != new_argvs) delete g_injected_test_argvs;
+ g_injected_test_argvs = new_argvs;
+}
+
+void SetInjectableArgvs(const std::vector<std::string>& new_argvs) {
+ SetInjectableArgvs(
+ new std::vector<std::string>(new_argvs.begin(), new_argvs.end()));
+}
+
+void ClearInjectableArgvs() {
+ delete g_injected_test_argvs;
+ g_injected_test_argvs = nullptr;
+}
#endif // GTEST_HAS_DEATH_TEST
#if GTEST_OS_WINDOWS_MOBILE
@@ -1148,7 +1288,7 @@
// unchanged and returns false.
bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
// Parses the environment variable as a decimal integer.
- char* end = NULL;
+ char* end = nullptr;
const long long_value = strtol(str, &end, 10); // NOLINT
// Has strtol() consumed all characters in the string?
@@ -1187,15 +1327,16 @@
// Reads and returns the Boolean environment variable corresponding to
// the given flag; if it's not set, returns default_value.
//
-// The value is considered true iff it's not "0".
+// The value is considered true if and only if it's not "0".
bool BoolFromGTestEnv(const char* flag, bool default_value) {
#if defined(GTEST_GET_BOOL_FROM_ENV_)
return GTEST_GET_BOOL_FROM_ENV_(flag, default_value);
-#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
+#else
const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str());
- return string_value == NULL ?
- default_value : strcmp(string_value, "0") != 0;
+ return string_value == nullptr ? default_value
+ : strcmp(string_value, "0") != 0;
+#endif // defined(GTEST_GET_BOOL_FROM_ENV_)
}
// Reads and returns a 32-bit integer stored in the environment
@@ -1204,10 +1345,10 @@
Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
#if defined(GTEST_GET_INT32_FROM_ENV_)
return GTEST_GET_INT32_FROM_ENV_(flag, default_value);
-#endif // defined(GTEST_GET_INT32_FROM_ENV_)
+#else
const std::string env_var = FlagToEnvVar(flag);
const char* const string_value = posix::GetEnv(env_var.c_str());
- if (string_value == NULL) {
+ if (string_value == nullptr) {
// The environment variable is not set.
return default_value;
}
@@ -1222,37 +1363,36 @@
}
return result;
+#endif // defined(GTEST_GET_INT32_FROM_ENV_)
+}
+
+// As a special case for the 'output' flag, if GTEST_OUTPUT is not
+// set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
+// system. The value of XML_OUTPUT_FILE is a filename without the
+// "xml:" prefix of GTEST_OUTPUT.
+// Note that this is meant to be called at the call site so it does
+// not check that the flag is 'output'
+// In essence this checks an env variable called XML_OUTPUT_FILE
+// and if it is set we prepend "xml:" to its value, if it not set we return ""
+std::string OutputFlagAlsoCheckEnvVar(){
+ std::string default_value_for_output_flag = "";
+ const char* xml_output_file_env = posix::GetEnv("XML_OUTPUT_FILE");
+ if (nullptr != xml_output_file_env) {
+ default_value_for_output_flag = std::string("xml:") + xml_output_file_env;
+ }
+ return default_value_for_output_flag;
}
// Reads and returns the string environment variable corresponding to
// the given flag; if it's not set, returns default_value.
-std::string StringFromGTestEnv(const char* flag, const char* default_value) {
+const char* StringFromGTestEnv(const char* flag, const char* default_value) {
#if defined(GTEST_GET_STRING_FROM_ENV_)
return GTEST_GET_STRING_FROM_ENV_(flag, default_value);
-#endif // defined(GTEST_GET_STRING_FROM_ENV_)
+#else
const std::string env_var = FlagToEnvVar(flag);
- const char* value = posix::GetEnv(env_var.c_str());
- if (value != NULL) {
- return value;
- }
-
- // As a special case for the 'output' flag, if GTEST_OUTPUT is not
- // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build
- // system. The value of XML_OUTPUT_FILE is a filename without the
- // "xml:" prefix of GTEST_OUTPUT.
- //
- // The net priority order after flag processing is thus:
- // --gtest_output command line flag
- // GTEST_OUTPUT environment variable
- // XML_OUTPUT_FILE environment variable
- // 'default_value'
- if (strcmp(flag, "output") == 0) {
- value = posix::GetEnv("XML_OUTPUT_FILE");
- if (value != NULL) {
- return std::string("xml:") + value;
- }
- }
- return default_value;
+ const char* const value = posix::GetEnv(env_var.c_str());
+ return value == nullptr ? default_value : value;
+#endif // defined(GTEST_GET_STRING_FROM_ENV_)
}
} // namespace internal
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-printers.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-printers.cc
index a2df412..3337be3 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-printers.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-printers.cc
@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
-// Google Test - The Google C++ Testing Framework
+
+// Google Test - The Google C++ Testing and Mocking Framework
//
// This file implements a universal value printer that can print a
// value of any type T:
@@ -43,12 +42,13 @@
// defines Foo.
#include "gtest/gtest-printers.h"
-#include <ctype.h>
#include <stdio.h>
+#include <cctype>
#include <cwchar>
#include <ostream> // NOLINT
#include <string>
#include "gtest/internal/gtest-port.h"
+#include "src/gtest-internal-inl.h"
namespace testing {
@@ -59,6 +59,7 @@
// Prints a segment of bytes in the given object.
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
+GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start,
size_t count, ostream* os) {
@@ -89,7 +90,6 @@
// If the object size is bigger than kThreshold, we'll have to omit
// some details by printing only the first and the last kChunkSize
// bytes.
- // TODO(wan): let the user control the threshold using a flag.
if (count < kThreshold) {
PrintByteSegmentInObjectTo(obj_bytes, 0, count, os);
} else {
@@ -123,7 +123,7 @@
// 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,
@@ -144,7 +144,8 @@
// which is the type of c.
template <typename UnsignedChar, typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
- switch (static_cast<wchar_t>(c)) {
+ wchar_t w_c = static_cast<wchar_t>(c);
+ switch (w_c) {
case L'\0':
*os << "\\0";
break;
@@ -176,11 +177,14 @@
*os << "\\v";
break;
default:
- if (IsPrintableAscii(c)) {
+ if (IsPrintableAscii(w_c)) {
*os << static_cast<char>(c);
return kAsIs;
} else {
- *os << "\\x" + String::FormatHexInt(static_cast<UnsignedChar>(c));
+ ostream::fmtflags flags = os->flags();
+ *os << "\\x" << std::hex << std::uppercase
+ << static_cast<int>(static_cast<UnsignedChar>(c));
+ os->flags(flags);
return kHexEscape;
}
}
@@ -227,13 +231,13 @@
return;
*os << " (" << static_cast<int>(c);
- // 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)) {
// Do nothing.
} else {
- *os << ", 0x" << String::FormatHexInt(static_cast<UnsignedChar>(c));
+ *os << ", 0x" << String::FormatHexInt(static_cast<int>(c));
}
*os << ")";
}
@@ -258,12 +262,14 @@
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
+GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
-static void PrintCharsAsStringTo(
+static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
bool is_previous_hex = false;
+ CharFormat print_format = kAsIs;
for (size_t index = 0; index < len; ++index) {
const CharType cur = begin[index];
if (is_previous_hex && IsXDigit(cur)) {
@@ -273,8 +279,13 @@
*os << "\" " << kQuoteBegin;
}
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
+ // Remember if any characters required hex escaping.
+ if (is_previous_hex) {
+ print_format = kHexEscape;
+ }
}
*os << "\"";
+ return print_format;
}
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
@@ -282,6 +293,7 @@
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
+GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void UniversalPrintCharArray(
const CharType* begin, size_t len, ostream* os) {
@@ -318,7 +330,7 @@
// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
- if (s == NULL) {
+ if (s == nullptr) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
@@ -335,33 +347,90 @@
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
- if (s == NULL) {
+ if (s == nullptr) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
- PrintCharsAsStringTo(s, std::wcslen(s), os);
+ PrintCharsAsStringTo(s, wcslen(s), os);
}
}
#endif // wchar_t is native
-// Prints a ::string object.
-#if GTEST_HAS_GLOBAL_STRING
-void PrintStringTo(const ::string& s, ostream* os) {
- PrintCharsAsStringTo(s.data(), s.size(), os);
+namespace {
+
+bool ContainsUnprintableControlCodes(const char* str, size_t length) {
+ const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
+
+ for (size_t i = 0; i < length; i++) {
+ unsigned char ch = *s++;
+ if (std::iscntrl(ch)) {
+ switch (ch) {
+ case '\t':
+ case '\n':
+ case '\r':
+ break;
+ default:
+ return true;
+ }
+ }
+ }
+ return false;
}
-#endif // GTEST_HAS_GLOBAL_STRING
+
+bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; }
+
+bool IsValidUTF8(const char* str, size_t length) {
+ const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
+
+ for (size_t i = 0; i < length;) {
+ unsigned char lead = s[i++];
+
+ if (lead <= 0x7f) {
+ continue; // single-byte character (ASCII) 0..7F
+ }
+ if (lead < 0xc2) {
+ return false; // trail byte or non-shortest form
+ } else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
+ ++i; // 2-byte character
+ } else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
+ IsUTF8TrailByte(s[i]) &&
+ IsUTF8TrailByte(s[i + 1]) &&
+ // check for non-shortest form and surrogate
+ (lead != 0xe0 || s[i] >= 0xa0) &&
+ (lead != 0xed || s[i] < 0xa0)) {
+ i += 2; // 3-byte character
+ } else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
+ IsUTF8TrailByte(s[i]) &&
+ IsUTF8TrailByte(s[i + 1]) &&
+ IsUTF8TrailByte(s[i + 2]) &&
+ // check for non-shortest form
+ (lead != 0xf0 || s[i] >= 0x90) &&
+ (lead != 0xf4 || s[i] < 0x90)) {
+ i += 3; // 4-byte character
+ } else {
+ return false;
+ }
+ }
+ return true;
+}
+
+void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
+ if (!ContainsUnprintableControlCodes(str, length) &&
+ IsValidUTF8(str, length)) {
+ *os << "\n As Text: \"" << str << "\"";
+ }
+}
+
+} // anonymous namespace
void PrintStringTo(const ::std::string& s, ostream* os) {
- PrintCharsAsStringTo(s.data(), s.size(), os);
+ if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
+ if (GTEST_FLAG(print_utf8)) {
+ ConditionalPrintAsText(s.data(), s.size(), os);
+ }
+ }
}
-// Prints a ::wstring object.
-#if GTEST_HAS_GLOBAL_WSTRING
-void PrintWideStringTo(const ::wstring& s, ostream* os) {
- PrintCharsAsStringTo(s.data(), s.size(), os);
-}
-#endif // GTEST_HAS_GLOBAL_WSTRING
-
#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-test-part.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-test-part.cc
index fb0e354..178317a 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-test-part.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-test-part.cc
@@ -26,21 +26,12 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Markus Heule)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
#include "gtest/gtest-test-part.h"
-
-// Indicates that this translation unit is part of Google Test's
-// implementation. It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error. This trick exists to
-// prevent the accidental inclusion of gtest-internal-inl.h in the
-// user's code.
-#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
-#undef GTEST_IMPLEMENTATION_
namespace testing {
@@ -50,18 +41,21 @@
// in it.
std::string TestPartResult::ExtractSummary(const char* message) {
const char* const stack_trace = strstr(message, internal::kStackTraceMarker);
- return stack_trace == NULL ? message :
- std::string(message, stack_trace);
+ return stack_trace == nullptr ? message : std::string(message, stack_trace);
}
// Prints a TestPartResult object.
std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
- return os
- << result.file_name() << ":" << result.line_number() << ": "
- << (result.type() == TestPartResult::kSuccess ? "Success" :
- result.type() == TestPartResult::kFatalFailure ? "Fatal failure" :
- "Non-fatal failure") << ":\n"
- << result.message() << std::endl;
+ return os << result.file_name() << ":" << result.line_number() << ": "
+ << (result.type() == TestPartResult::kSuccess
+ ? "Success"
+ : result.type() == TestPartResult::kSkip
+ ? "Skipped"
+ : result.type() == TestPartResult::kFatalFailure
+ ? "Fatal failure"
+ : "Non-fatal failure")
+ << ":\n"
+ << result.message() << std::endl;
}
// Appends a TestPartResult to the array.
@@ -76,7 +70,7 @@
internal::posix::Abort();
}
- return array_[index];
+ return array_[static_cast<size_t>(index)];
}
// Returns the number of TestPartResult objects in the array.
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-typed-test.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-typed-test.cc
index df1eef4..8677caf 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-typed-test.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest-typed-test.cc
@@ -26,10 +26,10 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Author: [email protected] (Zhanyong Wan)
+
#include "gtest/gtest-typed-test.h"
+
#include "gtest/gtest.h"
namespace testing {
@@ -48,7 +48,7 @@
static std::vector<std::string> SplitIntoTestNames(const char* src) {
std::vector<std::string> name_vec;
src = SkipSpaces(src);
- for (; src != NULL; src = SkipComma(src)) {
+ for (; src != nullptr; src = SkipComma(src)) {
name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src)));
}
return name_vec;
@@ -57,7 +57,7 @@
// Verifies that registered_tests match the test names in
// registered_tests_; returns registered_tests if successful, or
// aborts the program otherwise.
-const char* TypedTestCasePState::VerifyRegisteredTestNames(
+const char* TypedTestSuitePState::VerifyRegisteredTestNames(
const char* file, int line, const char* registered_tests) {
typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
registered_ = true;
@@ -89,7 +89,7 @@
tests.insert(name);
} else {
errors << "No test named " << name
- << " can be found in this test case.\n";
+ << " can be found in this test suite.\n";
}
}
diff --git a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc
index d882ab2..a5b4e5a 100644
--- a/src/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc
+++ b/src/llvm-project/llvm/utils/unittest/googletest/src/gtest.cc
@@ -26,10 +26,9 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
//
-// Author: [email protected] (Zhanyong Wan)
-//
-// The Google C++ Testing Framework (Google Test)
+// The Google C++ Testing and Mocking Framework (Google Test)
#include "gtest/gtest.h"
#include "gtest/internal/custom/gtest.h"
@@ -55,8 +54,6 @@
#if GTEST_OS_LINUX
-// TODO([email protected]): Use autoconf to detect availability of
-// gettimeofday().
# define GTEST_HAS_GETTIMEOFDAY_ 1
# include <fcntl.h> // NOLINT
@@ -69,10 +66,6 @@
# include <unistd.h> // NOLINT
# include <string>
-#elif GTEST_OS_SYMBIAN
-# define GTEST_HAS_GETTIMEOFDAY_ 1
-# include <sys/time.h> // NOLINT
-
#elif GTEST_OS_ZOS
# define GTEST_HAS_GETTIMEOFDAY_ 1
# include <sys/time.h> // NOLINT
@@ -87,6 +80,11 @@
#elif GTEST_OS_WINDOWS // We are on Windows proper.
+# include <windows.h> // NOLINT
+# undef min
+
+# include <crtdbg.h> // NOLINT
+# include <debugapi.h> // NOLINT
# include <io.h> // NOLINT
# include <sys/timeb.h> // NOLINT
# include <sys/types.h> // NOLINT
@@ -94,25 +92,13 @@
# if GTEST_OS_WINDOWS_MINGW
// MinGW has gettimeofday() but not _ftime64().
-// TODO([email protected]): Use autoconf to detect availability of
-// gettimeofday().
-// TODO([email protected]): There are other ways to get the time on
-// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW
-// supports these. consider using them instead.
# define GTEST_HAS_GETTIMEOFDAY_ 1
# include <sys/time.h> // NOLINT
# endif // GTEST_OS_WINDOWS_MINGW
-// cpplint thinks that the header is already included, so we want to
-// silence it.
-# include <windows.h> // NOLINT
-# undef min
-
#else
// Assume other platforms have gettimeofday().
-// TODO([email protected]): Use autoconf to detect availability of
-// gettimeofday().
# define GTEST_HAS_GETTIMEOFDAY_ 1
// cpplint thinks that the header is already included, so we want to
@@ -133,19 +119,25 @@
# include <sys/types.h> // NOLINT
#endif
-// Indicates that this translation unit is part of Google Test's
-// implementation. It must come before gtest-internal-inl.h is
-// included, or there will be a compiler error. This trick is to
-// prevent a user from accidentally including gtest-internal-inl.h in
-// his code.
-#define GTEST_IMPLEMENTATION_ 1
#include "src/gtest-internal-inl.h"
-#undef GTEST_IMPLEMENTATION_
#if GTEST_OS_WINDOWS
# define vsnprintf _vsnprintf
#endif // GTEST_OS_WINDOWS
+#if GTEST_OS_MAC
+#ifndef GTEST_OS_IOS
+#include <crt_externs.h>
+#endif
+#endif
+
+#if GTEST_HAS_ABSL
+#include "absl/debugging/failure_signal_handler.h"
+#include "absl/debugging/stacktrace.h"
+#include "absl/debugging/symbolize.h"
+#include "absl/strings/str_cat.h"
+#endif // GTEST_HAS_ABSL
+
namespace testing {
using internal::CountIf;
@@ -155,20 +147,22 @@
// Constants.
-// A test whose test case name or test name matches this filter is
+// A test whose test suite name or test name matches this filter is
// disabled and not run.
static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*";
-// A test case whose name matches this filter is considered a death
-// test case and will be run before test cases whose name doesn't
+// A test suite whose name matches this filter is considered a death
+// test suite and will be run before test suites whose name doesn't
// match this filter.
-static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*";
+static const char kDeathTestSuiteFilter[] = "*DeathTest:*DeathTest/*";
// A test filter that matches everything.
static const char kUniversalFilter[] = "*";
-// The default output file for XML output.
-static const char kDefaultOutputFile[] = "test_detail.xml";
+// The default output format.
+static const char kDefaultOutputFormat[] = "xml";
+// The default output file.
+static const char kDefaultOutputFile[] = "test_detail";
// The environment variable name for the test shard index.
static const char kTestShardIndex[] = "GTEST_SHARD_INDEX";
@@ -183,19 +177,35 @@
// stack trace.
const char kStackTraceMarker[] = "\nStack trace:\n";
-// g_help_flag is true iff the --help flag or an equivalent form is
-// specified on the command line.
+// g_help_flag is true if and only if the --help flag or an equivalent form
+// is specified on the command line.
bool g_help_flag = false;
+// Utilty function to Open File for Writing
+static FILE* OpenFileForWriting(const std::string& output_file) {
+ FILE* fileout = nullptr;
+ FilePath output_file_path(output_file);
+ FilePath output_dir(output_file_path.RemoveFileName());
+
+ if (output_dir.CreateDirectoriesRecursively()) {
+ fileout = posix::FOpen(output_file.c_str(), "w");
+ }
+ if (fileout == nullptr) {
+ GTEST_LOG_(FATAL) << "Unable to open file \"" << output_file << "\"";
+ }
+ return fileout;
+}
+
} // namespace internal
+// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY
+// environment variable.
static const char* GetDefaultFilter() {
-#ifdef GTEST_TEST_FILTER_ENV_VAR_
- const char* const testbridge_test_only = getenv(GTEST_TEST_FILTER_ENV_VAR_);
- if (testbridge_test_only != NULL) {
+ const char* const testbridge_test_only =
+ internal::posix::GetEnv("TESTBRIDGE_TEST_ONLY");
+ if (testbridge_test_only != nullptr) {
return testbridge_test_only;
}
-#endif // GTEST_TEST_FILTER_ENV_VAR_
return kUniversalFilter;
}
@@ -205,15 +215,14 @@
"Run disabled tests too, in addition to the tests normally being run.");
GTEST_DEFINE_bool_(
- break_on_failure,
- internal::BoolFromGTestEnv("break_on_failure", false),
- "True iff a failed assertion should be a debugger break-point.");
+ break_on_failure, internal::BoolFromGTestEnv("break_on_failure", false),
+ "True if and only if a failed assertion should be a debugger "
+ "break-point.");
-GTEST_DEFINE_bool_(
- catch_exceptions,
- internal::BoolFromGTestEnv("catch_exceptions", true),
- "True iff " GTEST_NAME_
- " should catch exceptions and treat them as test failures.");
+GTEST_DEFINE_bool_(catch_exceptions,
+ internal::BoolFromGTestEnv("catch_exceptions", true),
+ "True if and only if " GTEST_NAME_
+ " should catch exceptions and treat them as test failures.");
GTEST_DEFINE_string_(
color,
@@ -232,26 +241,41 @@
"exclude). A test is run if it matches one of the positive "
"patterns and does not match any of the negative patterns.");
+GTEST_DEFINE_bool_(
+ install_failure_signal_handler,
+ internal::BoolFromGTestEnv("install_failure_signal_handler", false),
+ "If true and supported on the current platform, " GTEST_NAME_ " should "
+ "install a signal handler that dumps debugging information when fatal "
+ "signals are raised.");
+
GTEST_DEFINE_bool_(list_tests, false,
"List all tests without running them.");
+// The net priority order after flag processing is thus:
+// --gtest_output command line flag
+// GTEST_OUTPUT environment variable
+// XML_OUTPUT_FILE environment variable
+// ''
GTEST_DEFINE_string_(
output,
- internal::StringFromGTestEnv("output", ""),
- "A format (currently must be \"xml\"), optionally followed "
- "by a colon and an output file name or directory. A directory "
- "is indicated by a trailing pathname separator. "
+ internal::StringFromGTestEnv("output",
+ internal::OutputFlagAlsoCheckEnvVar().c_str()),
+ "A format (defaults to \"xml\" but can be specified to be \"json\"), "
+ "optionally followed by a colon and an output file name or directory. "
+ "A directory is indicated by a trailing pathname separator. "
"Examples: \"xml:filename.xml\", \"xml::directoryname/\". "
"If a directory is specified, output files will be created "
"within that directory, with file-names based on the test "
"executable's name and, if necessary, made unique by adding "
"digits.");
-GTEST_DEFINE_bool_(
- print_time,
- internal::BoolFromGTestEnv("print_time", true),
- "True iff " GTEST_NAME_
- " should display elapsed time in text output.");
+GTEST_DEFINE_bool_(print_time, internal::BoolFromGTestEnv("print_time", true),
+ "True if and only if " GTEST_NAME_
+ " should display elapsed time in text output.");
+
+GTEST_DEFINE_bool_(print_utf8, internal::BoolFromGTestEnv("print_utf8", true),
+ "True if and only if " GTEST_NAME_
+ " prints UTF8 characters as text.");
GTEST_DEFINE_int32_(
random_seed,
@@ -265,16 +289,14 @@
"How many times to repeat each test. Specify a negative number "
"for repeating forever. Useful for shaking out flaky tests.");
-GTEST_DEFINE_bool_(
- show_internal_stack_frames, false,
- "True iff " GTEST_NAME_ " should include internal stack frames when "
- "printing test failure stack traces.");
+GTEST_DEFINE_bool_(show_internal_stack_frames, false,
+ "True if and only if " GTEST_NAME_
+ " should include internal stack frames when "
+ "printing test failure stack traces.");
-GTEST_DEFINE_bool_(
- shuffle,
- internal::BoolFromGTestEnv("shuffle", false),
- "True iff " GTEST_NAME_
- " should randomize tests' order on every run.");
+GTEST_DEFINE_bool_(shuffle, internal::BoolFromGTestEnv("shuffle", false),
+ "True if and only if " GTEST_NAME_
+ " should randomize tests' order on every run.");
GTEST_DEFINE_int32_(
stack_trace_depth,
@@ -294,7 +316,7 @@
internal::BoolFromGTestEnv("throw_on_failure", false),
"When this flag is specified, a failed assertion will throw an exception "
"if exceptions are enabled or exit the program with a non-zero code "
- "otherwise.");
+ "otherwise. For use with an external test framework.");
#if GTEST_USE_OWN_FLAGFILE_FLAG_
GTEST_DEFINE_string_(
@@ -310,7 +332,8 @@
// than kMaxRange.
UInt32 Random::Generate(UInt32 range) {
// These constants are the same as are used in glibc's rand(3).
- state_ = (1103515245U*state_ + 12345U) % kMaxRange;
+ // Use wider types than necessary to prevent unsigned overflow diagnostics.
+ state_ = static_cast<UInt32>(1103515245ULL*state_ + 12345U) % kMaxRange;
GTEST_CHECK_(range > 0)
<< "Cannot generate a number in the range [0, 0).";
@@ -324,16 +347,16 @@
return state_ % range;
}
-// GTestIsInitialized() returns true iff the user has initialized
+// GTestIsInitialized() returns true if and only if the user has initialized
// Google Test. Useful for catching the user mistake of not initializing
// Google Test before calling RUN_ALL_TESTS().
static bool GTestIsInitialized() { return GetArgvs().size() > 0; }
-// Iterates over a vector of TestCases, keeping a running sum of the
+// Iterates over a vector of TestSuites, keeping a running sum of the
// results of calling a given int-returning method on each.
// Returns the sum.
-static int SumOverTestCaseList(const std::vector<TestCase*>& case_list,
- int (TestCase::*method)() const) {
+static int SumOverTestSuiteList(const std::vector<TestSuite*>& case_list,
+ int (TestSuite::*method)() const) {
int sum = 0;
for (size_t i = 0; i < case_list.size(); i++) {
sum += (case_list[i]->*method)();
@@ -341,20 +364,20 @@
return sum;
}
-// Returns true iff the test case passed.
-static bool TestCasePassed(const TestCase* test_case) {
- return test_case->should_run() && test_case->Passed();
+// Returns true if and only if the test suite passed.
+static bool TestSuitePassed(const TestSuite* test_suite) {
+ return test_suite->should_run() && test_suite->Passed();
}
-// Returns true iff the test case failed.
-static bool TestCaseFailed(const TestCase* test_case) {
- return test_case->should_run() && test_case->Failed();
+// Returns true if and only if the test suite failed.
+static bool TestSuiteFailed(const TestSuite* test_suite) {
+ return test_suite->should_run() && test_suite->Failed();
}
-// Returns true iff test_case contains at least one test that should
-// run.
-static bool ShouldRunTestCase(const TestCase* test_case) {
- return test_case->should_run();
+// Returns true if and only if test_suite contains at least one test that
+// should run.
+static bool ShouldRunTestSuite(const TestSuite* test_suite) {
+ return test_suite->should_run();
}
// AssertHelper constructor.
@@ -380,16 +403,16 @@
); // NOLINT
}
-// Mutex for linked pointers.
-GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex);
-
// A copy of all command line arguments. Set by InitGoogleTest().
-::std::vector<testing::internal::string> g_argvs;
+static ::std::vector<std::string> g_argvs;
-const ::std::vector<testing::internal::string>& GetArgvs() {
+::std::vector<std::string> GetArgvs() {
#if defined(GTEST_CUSTOM_GET_ARGVS_)
- return GTEST_CUSTOM_GET_ARGVS_();
-#else // defined(GTEST_CUSTOM_GET_ARGVS_)
+ // GTEST_CUSTOM_GET_ARGVS_() may return a container of std::string or
+ // ::string. This code converts it to the appropriate type.
+ const auto& custom = GTEST_CUSTOM_GET_ARGVS_();
+ return ::std::vector<std::string>(custom.begin(), custom.end());
+#else // defined(GTEST_CUSTOM_GET_ARGVS_)
return g_argvs;
#endif // defined(GTEST_CUSTOM_GET_ARGVS_)
}
@@ -399,7 +422,7 @@
FilePath GetCurrentExecutableName() {
FilePath result;
-#if GTEST_OS_WINDOWS
+#if GTEST_OS_WINDOWS || GTEST_OS_OS2
result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe"));
#else
result.Set(FilePath(GetArgvs()[0]));
@@ -413,34 +436,32 @@
// Returns the output format, or "" for normal printed output.
std::string UnitTestOptions::GetOutputFormat() {
const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
- if (gtest_output_flag == NULL) return std::string("");
-
const char* const colon = strchr(gtest_output_flag, ':');
- return (colon == NULL) ?
- std::string(gtest_output_flag) :
- std::string(gtest_output_flag, colon - gtest_output_flag);
+ return (colon == nullptr)
+ ? std::string(gtest_output_flag)
+ : std::string(gtest_output_flag,
+ static_cast<size_t>(colon - gtest_output_flag));
}
// Returns the name of the requested output file, or the default if none
// was explicitly specified.
std::string UnitTestOptions::GetAbsolutePathToOutputFile() {
const char* const gtest_output_flag = GTEST_FLAG(output).c_str();
- if (gtest_output_flag == NULL)
- return "";
+
+ std::string format = GetOutputFormat();
+ if (format.empty())
+ format = std::string(kDefaultOutputFormat);
const char* const colon = strchr(gtest_output_flag, ':');
- if (colon == NULL)
- return internal::FilePath::ConcatPaths(
+ if (colon == nullptr)
+ return internal::FilePath::MakeFileName(
internal::FilePath(
UnitTest::GetInstance()->original_working_dir()),
- internal::FilePath(kDefaultOutputFile)).string();
+ internal::FilePath(kDefaultOutputFile), 0,
+ format.c_str()).string();
internal::FilePath output_name(colon + 1);
if (!output_name.IsAbsolutePath())
- // TODO([email protected]): on Windows \some\path is not an absolute
- // path (as its meaning depends on the current drive), yet the
- // following logic for turning it into an absolute path is wrong.
- // Fix it.
output_name = internal::FilePath::ConcatPaths(
internal::FilePath(UnitTest::GetInstance()->original_working_dir()),
internal::FilePath(colon + 1));
@@ -454,8 +475,8 @@
return result.string();
}
-// Returns true iff the wildcard pattern matches the string. The
-// first ':' or '\0' character in pattern marks the end of it.
+// Returns true if and only if the wildcard pattern matches the string.
+// The first ':' or '\0' character in pattern marks the end of it.
//
// This recursive algorithm isn't very efficient, but is clear and
// works well enough for matching test names, which are short.
@@ -488,7 +509,7 @@
cur_pattern = strchr(cur_pattern, ':');
// Returns if no more pattern can be found.
- if (cur_pattern == NULL) {
+ if (cur_pattern == nullptr) {
return false;
}
@@ -497,11 +518,11 @@
}
}
-// Returns true iff the user-specified filter matches the test case
-// name and the test name.
-bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name,
- const std::string &test_name) {
- const std::string& full_name = test_case_name + "." + test_name.c_str();
+// Returns true if and only if the user-specified filter matches the test
+// suite name and the test name.
+bool UnitTestOptions::FilterMatchesTest(const std::string& test_suite_name,
+ const std::string& test_name) {
+ const std::string& full_name = test_suite_name + "." + test_name.c_str();
// Split --gtest_filter at '-', if there is one, to separate into
// positive filter and negative filter portions
@@ -509,7 +530,7 @@
const char* const dash = strchr(p, '-');
std::string positive;
std::string negative;
- if (dash == NULL) {
+ if (dash == nullptr) {
positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter
negative = "";
} else {
@@ -628,12 +649,12 @@
// This predicate-formatter checks that 'results' contains a test part
// failure of the given type and that the failure message contains the
// given substring.
-AssertionResult HasOneFailure(const char* /* results_expr */,
- const char* /* type_expr */,
- const char* /* substr_expr */,
- const TestPartResultArray& results,
- TestPartResult::Type type,
- const string& substr) {
+static AssertionResult HasOneFailure(const char* /* results_expr */,
+ const char* /* type_expr */,
+ const char* /* substr_expr */,
+ const TestPartResultArray& results,
+ TestPartResult::Type type,
+ const std::string& substr) {
const std::string expected(type == TestPartResult::kFatalFailure ?
"1 fatal failure" :
"1 non-fatal failure");
@@ -654,7 +675,7 @@
<< r;
}
- if (strstr(r.message(), substr.c_str()) == NULL) {
+ if (strstr(r.message(), substr.c_str()) == nullptr) {
return AssertionFailure() << "Expected: " << expected << " containing \""
<< substr << "\"\n"
<< " Actual:\n"
@@ -667,13 +688,10 @@
// The constructor of SingleFailureChecker remembers where to look up
// test part results, what type of failure we expect, and what
// substring the failure message should contain.
-SingleFailureChecker:: SingleFailureChecker(
- const TestPartResultArray* results,
- TestPartResult::Type type,
- const string& substr)
- : results_(results),
- type_(type),
- substr_(substr) {}
+SingleFailureChecker::SingleFailureChecker(const TestPartResultArray* results,
+ TestPartResult::Type type,
+ const std::string& substr)
+ : results_(results), type_(type), substr_(substr) {}
// The destructor of SingleFailureChecker verifies that the given
// TestPartResultArray contains exactly one failure that has the given
@@ -726,61 +744,66 @@
per_thread_test_part_result_reporter_.set(reporter);
}
-// Gets the number of successful test cases.
-int UnitTestImpl::successful_test_case_count() const {
- return CountIf(test_cases_, TestCasePassed);
+// Gets the number of successful test suites.
+int UnitTestImpl::successful_test_suite_count() const {
+ return CountIf(test_suites_, TestSuitePassed);
}
-// Gets the number of failed test cases.
-int UnitTestImpl::failed_test_case_count() const {
- return CountIf(test_cases_, TestCaseFailed);
+// Gets the number of failed test suites.
+int UnitTestImpl::failed_test_suite_count() const {
+ return CountIf(test_suites_, TestSuiteFailed);
}
-// Gets the number of all test cases.
-int UnitTestImpl::total_test_case_count() const {
- return static_cast<int>(test_cases_.size());
+// Gets the number of all test suites.
+int UnitTestImpl::total_test_suite_count() const {
+ return static_cast<int>(test_suites_.size());
}
-// Gets the number of all test cases that contain at least one test
+// Gets the number of all test suites that contain at least one test
// that should run.
-int UnitTestImpl::test_case_to_run_count() const {
- return CountIf(test_cases_, ShouldRunTestCase);
+int UnitTestImpl::test_suite_to_run_count() const {
+ return CountIf(test_suites_, ShouldRunTestSuite);
}
// Gets the number of successful tests.
int UnitTestImpl::successful_test_count() const {
- return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count);
+ return SumOverTestSuiteList(test_suites_, &TestSuite::successful_test_count);
+}
+
+// Gets the number of skipped tests.
+int UnitTestImpl::skipped_test_count() const {
+ return SumOverTestSuiteList(test_suites_, &TestSuite::skipped_test_count);
}
// Gets the number of failed tests.
int UnitTestImpl::failed_test_count() const {
- return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count);
+ return SumOverTestSuiteList(test_suites_, &TestSuite::failed_test_count);
}
// Gets the number of disabled tests that will be reported in the XML report.
int UnitTestImpl::reportable_disabled_test_count() const {
- return SumOverTestCaseList(test_cases_,
- &TestCase::reportable_disabled_test_count);
+ return SumOverTestSuiteList(test_suites_,
+ &TestSuite::reportable_disabled_test_count);
}
// Gets the number of disabled tests.
int UnitTestImpl::disabled_test_count() const {
- return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count);
+ return SumOverTestSuiteList(test_suites_, &TestSuite::disabled_test_count);
}
// Gets the number of tests to be printed in the XML report.
int UnitTestImpl::reportable_test_count() const {
- return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count);
+ return SumOverTestSuiteList(test_suites_, &TestSuite::reportable_test_count);
}
// Gets the number of all tests.
int UnitTestImpl::total_test_count() const {
- return SumOverTestCaseList(test_cases_, &TestCase::total_test_count);
+ return SumOverTestSuiteList(test_suites_, &TestSuite::total_test_count);
}
// Gets the number of tests that should run.
int UnitTestImpl::test_to_run_count() const {
- return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count);
+ return SumOverTestSuiteList(test_suites_, &TestSuite::test_to_run_count);
}
// Returns the current OS stack trace as an std::string.
@@ -814,8 +837,6 @@
SYSTEMTIME now_systime;
FILETIME now_filetime;
ULARGE_INTEGER now_int64;
- // TODO([email protected]): Shouldn't this just use
- // GetSystemTimeAsFileTime()?
GetSystemTime(&now_systime);
if (SystemTimeToFileTime(&now_systime, &now_filetime)) {
now_int64.LowPart = now_filetime.dwLowDateTime;
@@ -830,16 +851,14 @@
// MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996
// (deprecated function) there.
- // TODO([email protected]): Use GetTickCount()? Or use
- // SystemTimeToFileTime()
- GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996)
+ GTEST_DISABLE_MSC_DEPRECATED_PUSH_()
_ftime64(&now);
- GTEST_DISABLE_MSC_WARNINGS_POP_()
+ GTEST_DISABLE_MSC_DEPRECATED_POP_()
return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm;
#elif GTEST_HAS_GETTIMEOFDAY_
struct timeval now;
- gettimeofday(&now, NULL);
+ gettimeofday(&now, nullptr);
return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000;
#else
# error "Don't know how to get the current time on your system."
@@ -856,11 +875,10 @@
// value using delete[]. Returns the wide string, or NULL if the
// input is NULL.
LPCWSTR String::AnsiToUtf16(const char* ansi) {
- if (!ansi) return NULL;
+ if (!ansi) return nullptr;
const int length = strlen(ansi);
const int unicode_length =
- MultiByteToWideChar(CP_ACP, 0, ansi, length,
- NULL, 0);
+ MultiByteToWideChar(CP_ACP, 0, ansi, length, nullptr, 0);
WCHAR* unicode = new WCHAR[unicode_length + 1];
MultiByteToWideChar(CP_ACP, 0, ansi, length,
unicode, unicode_length);
@@ -873,33 +891,33 @@
// value using delete[]. Returns the ANSI string, or NULL if the
// input is NULL.
const char* String::Utf16ToAnsi(LPCWSTR utf16_str) {
- if (!utf16_str) return NULL;
- const int ansi_length =
- WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
- NULL, 0, NULL, NULL);
+ if (!utf16_str) return nullptr;
+ const int ansi_length = WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, nullptr,
+ 0, nullptr, nullptr);
char* ansi = new char[ansi_length + 1];
- WideCharToMultiByte(CP_ACP, 0, utf16_str, -1,
- ansi, ansi_length, NULL, NULL);
+ WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, ansi, ansi_length, nullptr,
+ nullptr);
ansi[ansi_length] = 0;
return ansi;
}
#endif // GTEST_OS_WINDOWS_MOBILE
-// Compares two C strings. Returns true iff they have the same content.
+// Compares two C strings. Returns true if and only if they have the same
+// content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A NULL
// C string is considered different to any non-NULL C string,
// including the empty string.
bool String::CStringEquals(const char * lhs, const char * rhs) {
- if ( lhs == NULL ) return rhs == NULL;
+ if (lhs == nullptr) return rhs == nullptr;
- if ( rhs == NULL ) return false;
+ if (rhs == nullptr) return false;
return strcmp(lhs, rhs) == 0;
}
-#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+#if GTEST_HAS_STD_WSTRING
// Converts an array of wide chars to a narrow string using the UTF-8
// encoding, and streams the result to the given Message object.
@@ -917,7 +935,7 @@
}
}
-#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING
+#endif // GTEST_HAS_STD_WSTRING
void SplitString(const ::std::string& str, char delimiter,
::std::vector< ::std::string>* dest) {
@@ -967,15 +985,6 @@
}
#endif // GTEST_HAS_STD_WSTRING
-#if GTEST_HAS_GLOBAL_WSTRING
-// Converts the given wide string to a narrow string using the UTF-8
-// encoding, and streams the result to this Message object.
-Message& Message::operator <<(const ::wstring& wstr) {
- internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this);
- return *this;
-}
-#endif // GTEST_HAS_GLOBAL_WSTRING
-
// Gets the text streamed to this object so far as an std::string.
// Each '\0' character in the buffer is replaced with "\\0".
std::string Message::GetString() const {
@@ -986,10 +995,9 @@
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult::AssertionResult(const AssertionResult& other)
: success_(other.success_),
- message_(other.message_.get() != NULL ?
- new ::std::string(*other.message_) :
- static_cast< ::std::string*>(NULL)) {
-}
+ message_(other.message_.get() != nullptr
+ ? new ::std::string(*other.message_)
+ : static_cast< ::std::string*>(nullptr)) {}
// Swaps two AssertionResults.
void AssertionResult::swap(AssertionResult& other) {
@@ -1001,8 +1009,7 @@
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult AssertionResult::operator!() const {
AssertionResult negation(!success_);
- if (message_.get() != NULL)
- negation << *message_;
+ if (message_.get() != nullptr) negation << *message_;
return negation;
}
@@ -1171,7 +1178,7 @@
// Print a unified diff header for one hunk.
// The format is
// "@@ -<left_start>,<left_length> +<right_start>,<right_length> @@"
- // where the left/right parts are ommitted if unnecessary.
+ // where the left/right parts are omitted if unnecessary.
void PrintHeader(std::ostream* ss) const {
*ss << "@@ ";
if (removes_) {
@@ -1228,9 +1235,10 @@
for (; edit_i < edits.size(); ++edit_i) {
if (n_suffix >= context) {
// Continue only if the next hunk is very close.
- std::vector<EditType>::const_iterator it = edits.begin() + edit_i;
+ auto it = edits.begin() + static_cast<int>(edit_i);
while (it != edits.end() && *it == kMatch) ++it;
- if (it == edits.end() || (it - edits.begin()) - edit_i >= context) {
+ if (it == edits.end() ||
+ static_cast<size_t>(it - edits.begin()) - edit_i >= context) {
// There is no next edit or it is too far away.
break;
}
@@ -1306,7 +1314,7 @@
// lhs_value: "5"
// rhs_value: "6"
//
-// The ignoring_case parameter is true iff the assertion is a
+// The ignoring_case parameter is true if and only if the assertion is a
// *_STRCASEEQ*. When it's true, the string "Ignoring case" will
// be inserted into the message.
AssertionResult EqFailure(const char* lhs_expression,
@@ -1315,13 +1323,14 @@
const std::string& rhs_value,
bool ignoring_case) {
Message msg;
- msg << " Expected: " << lhs_expression;
+ msg << "Expected equality of these values:";
+ msg << "\n " << lhs_expression;
if (lhs_value != lhs_expression) {
- msg << "\n Which is: " << lhs_value;
+ msg << "\n Which is: " << lhs_value;
}
- msg << "\nTo be equal to: " << rhs_expression;
+ msg << "\n " << rhs_expression;
if (rhs_value != rhs_expression) {
- msg << "\n Which is: " << rhs_value;
+ msg << "\n Which is: " << rhs_value;
}
if (ignoring_case) {
@@ -1368,8 +1377,6 @@
const double diff = fabs(val1 - val2);
if (diff <= abs_error) return AssertionSuccess();
- // TODO(wan): do not print the value of an expression if it's
- // already a literal.
return AssertionFailure()
<< "The difference between " << expr1 << " and " << expr2
<< " is " << diff << ", which exceeds " << abs_error_expr << ", where\n"
@@ -1550,22 +1557,20 @@
// Helper functions for implementing IsSubString() and IsNotSubstring().
-// This group of overloaded functions return true iff needle is a
-// substring of haystack. NULL is considered a substring of itself
-// only.
+// This group of overloaded functions return true if and only if needle
+// is a substring of haystack. NULL is considered a substring of
+// itself only.
bool IsSubstringPred(const char* needle, const char* haystack) {
- if (needle == NULL || haystack == NULL)
- return needle == haystack;
+ if (needle == nullptr || haystack == nullptr) return needle == haystack;
- return strstr(haystack, needle) != NULL;
+ return strstr(haystack, needle) != nullptr;
}
bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
- if (needle == NULL || haystack == NULL)
- return needle == haystack;
+ if (needle == nullptr || haystack == nullptr) return needle == haystack;
- return wcsstr(haystack, needle) != NULL;
+ return wcsstr(haystack, needle) != nullptr;
}
// StringType here can be either ::std::string or ::std::wstring.
@@ -1663,7 +1668,7 @@
AssertionResult HRESULTFailureHelper(const char* expr,
const char* expected,
long hr) { // NOLINT
-# if GTEST_OS_WINDOWS_MOBILE
+# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_TV_TITLE
// Windows CE doesn't support FormatMessage.
const char error_text[] = "";
@@ -1679,12 +1684,12 @@
// Gets the system's human readable message string for this HRESULT.
char error_text[kBufSize] = { '\0' };
DWORD message_length = ::FormatMessageA(kFlags,
- 0, // no source, we're asking system
- hr, // the error
- 0, // no line width restrictions
+ 0, // no source, we're asking system
+ static_cast<DWORD>(hr), // the error
+ 0, // no line width restrictions
error_text, // output buffer
- kBufSize, // buf size
- NULL); // no arguments for inserts
+ kBufSize, // buf size
+ nullptr); // no arguments for inserts
// Trims tailing white space (FormatMessage leaves a trailing CR-LF)
for (; message_length && IsSpace(error_text[message_length - 1]);
--message_length) {
@@ -1720,7 +1725,7 @@
// Utility functions for encoding Unicode text (wide strings) in
// UTF-8.
-// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8
+// A Unicode code-point can have up to 21 bits, and is encoded in UTF-8
// like this:
//
// Code-point length Encoding
@@ -1758,7 +1763,7 @@
// to "(Invalid Unicode 0xXXXXXXXX)".
std::string CodePointToUtf8(UInt32 code_point) {
if (code_point > kMaxCodePoint4) {
- return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")";
+ return "(Invalid Unicode 0x" + String::FormatHexUInt32(code_point) + ")";
}
char str[5]; // Big enough for the largest valid code point.
@@ -1784,9 +1789,9 @@
return str;
}
-// The following two functions only make sense if the the system
+// The following two functions only make sense if the system
// uses UTF-16 for wide string encoding. All supported systems
-// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16.
+// with 16 bit wchar_t (Windows, Cygwin) do use UTF-16.
// Determines if the arguments constitute UTF-16 surrogate pair
// and thus should be combined into a single Unicode code point
@@ -1799,17 +1804,20 @@
// Creates a Unicode code point from UTF16 surrogate pair.
inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first,
wchar_t second) {
+ const auto first_u = static_cast<UInt32>(first);
+ const auto second_u = static_cast<UInt32>(second);
const UInt32 mask = (1 << 10) - 1;
- return (sizeof(wchar_t) == 2) ?
- (((first & mask) << 10) | (second & mask)) + 0x10000 :
- // This function should not be called when the condition is
- // false, but we provide a sensible default in case it is.
- static_cast<UInt32>(first);
+ return (sizeof(wchar_t) == 2)
+ ? (((first_u & mask) << 10) | (second_u & mask)) + 0x10000
+ :
+ // This function should not be called when the condition is
+ // false, but we provide a sensible default in case it is.
+ first_u;
}
// Converts a wide string to a narrow string in UTF-8 encoding.
// The wide string is assumed to have the following encoding:
-// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS)
+// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin)
// UTF-32 if sizeof(wchar_t) == 4 (on Linux)
// Parameter str points to a null-terminated wide string.
// Parameter num_chars may additionally limit the number
@@ -1846,21 +1854,21 @@
// Converts a wide C string to an std::string using the UTF-8 encoding.
// NULL will be converted to "(null)".
std::string String::ShowWideCString(const wchar_t * wide_c_str) {
- if (wide_c_str == NULL) return "(null)";
+ if (wide_c_str == nullptr) return "(null)";
return internal::WideStringToUtf8(wide_c_str, -1);
}
-// Compares two wide C strings. Returns true iff they have the same
-// content.
+// Compares two wide C strings. Returns true if and only if they have the
+// same content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A NULL
// C string is considered different to any non-NULL C string,
// including the empty string.
bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) {
- if (lhs == NULL) return rhs == NULL;
+ if (lhs == nullptr) return rhs == nullptr;
- if (rhs == NULL) return false;
+ if (rhs == nullptr) return false;
return wcscmp(lhs, rhs) == 0;
}
@@ -1896,37 +1904,35 @@
<< " vs " << PrintToString(s2);
}
-// Compares two C strings, ignoring case. Returns true iff they have
+// Compares two C strings, ignoring case. Returns true if and only if they have
// the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) {
- if (lhs == NULL)
- return rhs == NULL;
- if (rhs == NULL)
- return false;
+ if (lhs == nullptr) return rhs == nullptr;
+ if (rhs == nullptr) return false;
return posix::StrCaseCmp(lhs, rhs) == 0;
}
- // Compares two wide C strings, ignoring case. Returns true iff they
- // have the same content.
- //
- // Unlike wcscasecmp(), this function can handle NULL argument(s).
- // A NULL C string is considered different to any non-NULL wide C string,
- // including the empty string.
- // NB: The implementations on different platforms slightly differ.
- // On windows, this method uses _wcsicmp which compares according to LC_CTYPE
- // environment variable. On GNU platform this method uses wcscasecmp
- // which compares according to LC_CTYPE category of the current locale.
- // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
- // current locale.
+// Compares two wide C strings, ignoring case. Returns true if and only if they
+// have the same content.
+//
+// Unlike wcscasecmp(), this function can handle NULL argument(s).
+// A NULL C string is considered different to any non-NULL wide C string,
+// including the empty string.
+// NB: The implementations on different platforms slightly differ.
+// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
+// environment variable. On GNU platform this method uses wcscasecmp
+// which compares according to LC_CTYPE category of the current locale.
+// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
+// current locale.
bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs) {
- if (lhs == NULL) return rhs == NULL;
+ if (lhs == nullptr) return rhs == nullptr;
- if (rhs == NULL) return false;
+ if (rhs == nullptr) return false;
#if GTEST_OS_WINDOWS
return _wcsicmp(lhs, rhs) == 0;
@@ -1937,14 +1943,14 @@
// Other unknown OSes may not define it either.
wint_t left, right;
do {
- left = towlower(*lhs++);
- right = towlower(*rhs++);
+ left = towlower(static_cast<wint_t>(*lhs++));
+ right = towlower(static_cast<wint_t>(*rhs++));
} while (left && left == right);
return left == right;
#endif // OS selector
}
-// Returns true iff str ends with the given suffix, ignoring case.
+// Returns true if and only if str ends with the given suffix, ignoring case.
// Any string is considered to end with an empty suffix.
bool String::EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix) {
@@ -1963,12 +1969,17 @@
}
// Formats an int value as "%X".
-std::string String::FormatHexInt(int value) {
+std::string String::FormatHexUInt32(UInt32 value) {
std::stringstream ss;
ss << std::hex << std::uppercase << value;
return ss.str();
}
+// Formats an int value as "%X".
+std::string String::FormatHexInt(int value) {
+ return FormatHexUInt32(static_cast<UInt32>(value));
+}
+
// Formats a byte as "%02X".
std::string String::FormatByte(unsigned char value) {
std::stringstream ss;
@@ -1985,7 +1996,7 @@
const char* const end = start + str.length();
std::string result;
- result.reserve(2 * (end - start));
+ result.reserve(static_cast<size_t>(2 * (end - start)));
for (const char* ch = start; ch != end; ++ch) {
if (*ch == '\0') {
result += "\\0"; // Replaces NUL with "\\0";
@@ -2015,9 +2026,7 @@
// Creates an empty TestResult.
TestResult::TestResult()
- : death_test_count_(0),
- elapsed_time_(0) {
-}
+ : death_test_count_(0), start_timestamp_(0), elapsed_time_(0) {}
// D'tor.
TestResult::~TestResult() {
@@ -2029,7 +2038,7 @@
const TestPartResult& TestResult::GetTestPartResult(int i) const {
if (i < 0 || i >= total_part_count())
internal::posix::Abort();
- return test_part_results_.at(i);
+ return test_part_results_.at(static_cast<size_t>(i));
}
// Returns the i-th test property. i can range from 0 to
@@ -2038,7 +2047,7 @@
const TestProperty& TestResult::GetTestProperty(int i) const {
if (i < 0 || i >= test_property_count())
internal::posix::Abort();
- return test_properties_.at(i);
+ return test_properties_.at(static_cast<size_t>(i));
}
// Clears the test part results.
@@ -2086,23 +2095,18 @@
// The list of reserved attributes used in the <testsuite> element of XML
// output.
static const char* const kReservedTestSuiteAttributes[] = {
- "disabled",
- "errors",
- "failures",
- "name",
- "tests",
- "time"
-};
+ "disabled", "errors", "failures", "name", "tests", "time", "timestamp"};
// The list of reserved attributes used in the <testcase> element of XML output.
static const char* const kReservedTestCaseAttributes[] = {
- "classname",
- "name",
- "status",
- "time",
- "type_param",
- "value_param"
-};
+ "classname", "name", "status", "time", "type_param",
+ "value_param", "file", "line"};
+
+// Use a slightly different set for allowed output to ensure existing tests can
+// still RecordProperty("result") or "RecordProperty(timestamp")
+static const char* const kReservedOutputTestCaseAttributes[] = {
+ "classname", "name", "status", "time", "type_param",
+ "value_param", "file", "line", "result", "timestamp"};
template <int kSize>
std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
@@ -2124,6 +2128,22 @@
return std::vector<std::string>();
}
+// TODO(jdesprez): Merge the two getReserved attributes once skip is improved
+static std::vector<std::string> GetReservedOutputAttributesForElement(
+ const std::string& xml_element) {
+ if (xml_element == "testsuites") {
+ return ArrayAsVector(kReservedTestSuitesAttributes);
+ } else if (xml_element == "testsuite") {
+ return ArrayAsVector(kReservedTestSuiteAttributes);
+ } else if (xml_element == "testcase") {
+ return ArrayAsVector(kReservedOutputTestCaseAttributes);
+ } else {
+ GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element;
+ }
+ // This code is unreachable but some compilers may not realizes that.
+ return std::vector<std::string>();
+}
+
static std::string FormatWordList(const std::vector<std::string>& words) {
Message word_list;
for (size_t i = 0; i < words.size(); ++i) {
@@ -2138,8 +2158,9 @@
return word_list.GetString();
}
-bool ValidateTestPropertyName(const std::string& property_name,
- const std::vector<std::string>& reserved_names) {
+static bool ValidateTestPropertyName(
+ const std::string& property_name,
+ const std::vector<std::string>& reserved_names) {
if (std::find(reserved_names.begin(), reserved_names.end(), property_name) !=
reserved_names.end()) {
ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name
@@ -2166,7 +2187,17 @@
elapsed_time_ = 0;
}
-// Returns true iff the test failed.
+// Returns true off the test part was skipped.
+static bool TestPartSkipped(const TestPartResult& result) {
+ return result.skipped();
+}
+
+// Returns true if and only if the test was skipped.
+bool TestResult::Skipped() const {
+ return !Failed() && CountIf(test_part_results_, TestPartSkipped) > 0;
+}
+
+// Returns true if and only if the test failed.
bool TestResult::Failed() const {
for (int i = 0; i < total_part_count(); ++i) {
if (GetTestPartResult(i).failed())
@@ -2175,22 +2206,22 @@
return false;
}
-// Returns true iff the test part fatally failed.
+// Returns true if and only if the test part fatally failed.
static bool TestPartFatallyFailed(const TestPartResult& result) {
return result.fatally_failed();
}
-// Returns true iff the test fatally failed.
+// Returns true if and only if the test fatally failed.
bool TestResult::HasFatalFailure() const {
return CountIf(test_part_results_, TestPartFatallyFailed) > 0;
}
-// Returns true iff the test part non-fatally failed.
+// Returns true if and only if the test part non-fatally failed.
static bool TestPartNonfatallyFailed(const TestPartResult& result) {
return result.nonfatally_failed();
}
-// Returns true iff the test has a non-fatal failure.
+// Returns true if and only if the test has a non-fatal failure.
bool TestResult::HasNonfatalFailure() const {
return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0;
}
@@ -2253,25 +2284,25 @@
// AddTestPartResult.
UnitTest::GetInstance()->AddTestPartResult(
result_type,
- NULL, // No info about the source file where the exception occurred.
- -1, // We have no info on which line caused the exception.
+ nullptr, // No info about the source file where the exception occurred.
+ -1, // We have no info on which line caused the exception.
message,
- ""); // No stack trace, either.
+ ""); // No stack trace, either.
}
} // namespace internal
-// Google Test requires all tests in the same test case to use the same test
+// Google Test requires all tests in the same test suite to use the same test
// fixture class. This function checks if the current test has the
-// same fixture class as the first test in the current test case. If
+// same fixture class as the first test in the current test suite. If
// yes, it returns true; otherwise it generates a Google Test failure and
// returns false.
bool Test::HasSameFixtureClass() {
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
- const TestCase* const test_case = impl->current_test_case();
+ const TestSuite* const test_suite = impl->current_test_suite();
- // Info about the first test in the current test case.
- const TestInfo* const first_test_info = test_case->test_info_list()[0];
+ // Info about the first test in the current test suite.
+ const TestInfo* const first_test_info = test_suite->test_info_list()[0];
const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_;
const char* const first_test_name = first_test_info->name();
@@ -2287,7 +2318,7 @@
const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId();
if (first_is_TEST || this_is_TEST) {
- // Both TEST and TEST_F appear in same test case, which is incorrect.
+ // Both TEST and TEST_F appear in same test suite, which is incorrect.
// Tell the user how to fix this.
// Gets the name of the TEST and the name of the TEST_F. Note
@@ -2299,9 +2330,9 @@
first_is_TEST ? this_test_name : first_test_name;
ADD_FAILURE()
- << "All tests in the same test case must use the same test fixture\n"
- << "class, so mixing TEST_F and TEST in the same test case is\n"
- << "illegal. In test case " << this_test_info->test_case_name()
+ << "All tests in the same test suite must use the same test fixture\n"
+ << "class, so mixing TEST_F and TEST in the same test suite is\n"
+ << "illegal. In test suite " << this_test_info->test_suite_name()
<< ",\n"
<< "test " << TEST_F_name << " is defined using TEST_F but\n"
<< "test " << TEST_name << " is defined using TEST. You probably\n"
@@ -2311,15 +2342,15 @@
// Two fixture classes with the same name appear in two different
// namespaces, which is not allowed. Tell the user how to fix this.
ADD_FAILURE()
- << "All tests in the same test case must use the same test fixture\n"
- << "class. However, in test case "
- << this_test_info->test_case_name() << ",\n"
- << "you defined test " << first_test_name
- << " and test " << this_test_name << "\n"
+ << "All tests in the same test suite must use the same test fixture\n"
+ << "class. However, in test suite "
+ << this_test_info->test_suite_name() << ",\n"
+ << "you defined test " << first_test_name << " and test "
+ << this_test_name << "\n"
<< "using two different test fixture classes. This can happen if\n"
<< "the two classes are from different namespaces or translation\n"
<< "units and have the same name. You should probably rename one\n"
- << "of the classes to put the tests into different test cases.";
+ << "of the classes to put the tests into different test suites.";
}
return false;
}
@@ -2352,7 +2383,7 @@
static std::string FormatCxxExceptionMessage(const char* description,
const char* location) {
Message message;
- if (description != NULL) {
+ if (description != nullptr) {
message << "C++ exception with description \"" << description << "\"";
} else {
message << "Unknown C++ exception";
@@ -2436,6 +2467,8 @@
#if GTEST_HAS_EXCEPTIONS
try {
return HandleSehExceptionsInMethodIfSupported(object, method, location);
+ } catch (const AssertionException&) { // NOLINT
+ // This failure was reported already.
} catch (const internal::GoogleTestFailureException&) { // NOLINT
// This exception type can only be thrown by a failed Google
// Test assertion with the intention of letting another testing
@@ -2448,7 +2481,7 @@
} catch (...) { // NOLINT
internal::ReportFailureInUnknownLocation(
TestPartResult::kFatalFailure,
- FormatCxxExceptionMessage(NULL, location));
+ FormatCxxExceptionMessage(nullptr, location));
}
return static_cast<Result>(0);
#else
@@ -2468,8 +2501,9 @@
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()");
- // We will run the test only if SetUp() was successful.
- if (!HasFatalFailure()) {
+ // We will run the test only if SetUp() was successful and didn't call
+ // GTEST_SKIP().
+ if (!HasFatalFailure() && !IsSkipped()) {
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
this, &Test::TestBody, "the test body");
@@ -2483,32 +2517,36 @@
this, &Test::TearDown, "TearDown()");
}
-// Returns true iff the current test has a fatal failure.
+// Returns true if and only if the current test has a fatal failure.
bool Test::HasFatalFailure() {
return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure();
}
-// Returns true iff the current test has a non-fatal failure.
+// Returns true if and only if the current test has a non-fatal failure.
bool Test::HasNonfatalFailure() {
return internal::GetUnitTestImpl()->current_test_result()->
HasNonfatalFailure();
}
+// Returns true if and only if the current test was skipped.
+bool Test::IsSkipped() {
+ return internal::GetUnitTestImpl()->current_test_result()->Skipped();
+}
+
// class TestInfo
// Constructs a TestInfo object. It assumes ownership of the test factory
// object.
-TestInfo::TestInfo(const std::string& a_test_case_name,
- const std::string& a_name,
- const char* a_type_param,
+TestInfo::TestInfo(const std::string& a_test_suite_name,
+ const std::string& a_name, const char* a_type_param,
const char* a_value_param,
internal::CodeLocation a_code_location,
internal::TypeId fixture_class_id,
internal::TestFactoryBase* factory)
- : test_case_name_(a_test_case_name),
+ : test_suite_name_(a_test_suite_name),
name_(a_name),
- type_param_(a_type_param ? new std::string(a_type_param) : NULL),
- value_param_(a_value_param ? new std::string(a_value_param) : NULL),
+ type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
+ value_param_(a_value_param ? new std::string(a_value_param) : nullptr),
location_(a_code_location),
fixture_class_id_(fixture_class_id),
should_run_(false),
@@ -2527,7 +2565,7 @@
//
// Arguments:
//
-// test_case_name: name of the test case
+// test_suite_name: name of the test suite
// name: name of the test
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
@@ -2535,49 +2573,40 @@
// or NULL if this is not a value-parameterized test.
// code_location: code location where the test is defined
// fixture_class_id: ID of the test fixture class
-// set_up_tc: pointer to the function that sets up the test case
-// tear_down_tc: pointer to the function that tears down the test case
+// set_up_tc: pointer to the function that sets up the test suite
+// tear_down_tc: pointer to the function that tears down the test suite
// factory: pointer to the factory that creates a test object.
// The newly created TestInfo instance will assume
// ownership of the factory object.
TestInfo* MakeAndRegisterTestInfo(
- const char* test_case_name,
- const char* name,
- const char* type_param,
- const char* value_param,
- CodeLocation code_location,
- TypeId fixture_class_id,
- SetUpTestCaseFunc set_up_tc,
- TearDownTestCaseFunc tear_down_tc,
- TestFactoryBase* factory) {
+ const char* test_suite_name, const char* name, const char* type_param,
+ const char* value_param, CodeLocation code_location,
+ TypeId fixture_class_id, SetUpTestSuiteFunc set_up_tc,
+ TearDownTestSuiteFunc tear_down_tc, TestFactoryBase* factory) {
TestInfo* const test_info =
- new TestInfo(test_case_name, name, type_param, value_param,
+ new TestInfo(test_suite_name, name, type_param, value_param,
code_location, fixture_class_id, factory);
GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info);
return test_info;
}
-#if GTEST_HAS_PARAM_TEST
-void ReportInvalidTestCaseType(const char* test_case_name,
- CodeLocation code_location) {
+void ReportInvalidTestSuiteType(const char* test_suite_name,
+ CodeLocation code_location) {
Message errors;
errors
- << "Attempted redefinition of test case " << test_case_name << ".\n"
- << "All tests in the same test case must use the same test fixture\n"
- << "class. However, in test case " << test_case_name << ", you tried\n"
+ << "Attempted redefinition of test suite " << test_suite_name << ".\n"
+ << "All tests in the same test suite must use the same test fixture\n"
+ << "class. However, in test suite " << test_suite_name << ", you tried\n"
<< "to define a test using a fixture class different from the one\n"
<< "used earlier. This can happen if the two fixture classes are\n"
<< "from different namespaces and have the same name. You should\n"
<< "probably rename one of the classes to put the tests into different\n"
- << "test cases.";
+ << "test suites.";
- fprintf(stderr, "%s %s",
- FormatFileLocation(code_location.file.c_str(),
- code_location.line).c_str(),
- errors.GetString().c_str());
+ GTEST_LOG_(ERROR) << FormatFileLocation(code_location.file.c_str(),
+ code_location.line)
+ << " " << errors.GetString();
}
-#endif // GTEST_HAS_PARAM_TEST
-
} // namespace internal
namespace {
@@ -2585,7 +2614,7 @@
// A predicate that checks the test name of a TestInfo against a known
// value.
//
-// This is used for implementation of the TestCase class only. We put
+// This is used for implementation of the TestSuite class only. We put
// it in the anonymous namespace to prevent polluting the outer
// namespace.
//
@@ -2598,7 +2627,7 @@
explicit TestNameIs(const char* name)
: name_(name) {}
- // Returns true iff the test name of test_info matches name_.
+ // Returns true if and only if the test name of test_info matches name_.
bool operator()(const TestInfo * test_info) const {
return test_info && test_info->name() == name_;
}
@@ -2612,15 +2641,13 @@
namespace internal {
// This method expands all parameterized tests registered with macros TEST_P
-// and INSTANTIATE_TEST_CASE_P into regular tests and registers those.
+// and INSTANTIATE_TEST_SUITE_P into regular tests and registers those.
// This will be done just once during the program runtime.
void UnitTestImpl::RegisterParameterizedTests() {
-#if GTEST_HAS_PARAM_TEST
if (!parameterized_tests_registered_) {
parameterized_test_registry_.RegisterTests();
parameterized_tests_registered_ = true;
}
-#endif
}
} // namespace internal
@@ -2648,19 +2675,23 @@
factory_, &internal::TestFactoryBase::CreateTest,
"the test fixture's constructor");
- // Runs the test only if the test object was created and its
- // constructor didn't generate a fatal failure.
- if ((test != NULL) && !Test::HasFatalFailure()) {
+ // Runs the test if the constructor didn't generate a fatal failure or invoke
+ // GTEST_SKIP().
+ // Note that the object will not be null
+ if (!Test::HasFatalFailure() && !Test::IsSkipped()) {
// This doesn't throw as all user code that can throw are wrapped into
// exception handling code.
test->Run();
}
- // Deletes the test object.
- impl->os_stack_trace_getter()->UponLeavingGTest();
- internal::HandleExceptionsInMethodIfSupported(
- test, &Test::DeleteSelf_, "the test fixture's destructor");
+ if (test != nullptr) {
+ // Deletes the test object.
+ impl->os_stack_trace_getter()->UponLeavingGTest();
+ internal::HandleExceptionsInMethodIfSupported(
+ test, &Test::DeleteSelf_, "the test fixture's destructor");
+ }
+ result_.set_start_timestamp(start);
result_.set_elapsed_time(internal::GetTimeInMillis() - start);
// Notifies the unit test event listener that a test has just finished.
@@ -2668,134 +2699,151 @@
// Tells UnitTest to stop associating assertion results to this
// test.
- impl->set_current_test_info(NULL);
+ impl->set_current_test_info(nullptr);
}
-// class TestCase
+// class TestSuite
-// Gets the number of successful tests in this test case.
-int TestCase::successful_test_count() const {
+// Gets the number of successful tests in this test suite.
+int TestSuite::successful_test_count() const {
return CountIf(test_info_list_, TestPassed);
}
-// Gets the number of failed tests in this test case.
-int TestCase::failed_test_count() const {
+// Gets the number of successful tests in this test suite.
+int TestSuite::skipped_test_count() const {
+ return CountIf(test_info_list_, TestSkipped);
+}
+
+// Gets the number of failed tests in this test suite.
+int TestSuite::failed_test_count() const {
return CountIf(test_info_list_, TestFailed);
}
// Gets the number of disabled tests that will be reported in the XML report.
-int TestCase::reportable_disabled_test_count() const {
+int TestSuite::reportable_disabled_test_count() const {
return CountIf(test_info_list_, TestReportableDisabled);
}
-// Gets the number of disabled tests in this test case.
-int TestCase::disabled_test_count() const {
+// Gets the number of disabled tests in this test suite.
+int TestSuite::disabled_test_count() const {
return CountIf(test_info_list_, TestDisabled);
}
// Gets the number of tests to be printed in the XML report.
-int TestCase::reportable_test_count() const {
+int TestSuite::reportable_test_count() const {
return CountIf(test_info_list_, TestReportable);
}
-// Get the number of tests in this test case that should run.
-int TestCase::test_to_run_count() const {
+// Get the number of tests in this test suite that should run.
+int TestSuite::test_to_run_count() const {
return CountIf(test_info_list_, ShouldRunTest);
}
// Gets the number of all tests.
-int TestCase::total_test_count() const {
+int TestSuite::total_test_count() const {
return static_cast<int>(test_info_list_.size());
}
-// Creates a TestCase with the given name.
+// Creates a TestSuite with the given name.
//
// Arguments:
//
-// name: name of the test case
-// a_type_param: the name of the test case's type parameter, or NULL if
-// this is not a typed or a type-parameterized test case.
-// set_up_tc: pointer to the function that sets up the test case
-// tear_down_tc: pointer to the function that tears down the test case
-TestCase::TestCase(const char* a_name, const char* a_type_param,
- Test::SetUpTestCaseFunc set_up_tc,
- Test::TearDownTestCaseFunc tear_down_tc)
+// name: name of the test suite
+// a_type_param: the name of the test suite's type parameter, or NULL if
+// this is not a typed or a type-parameterized test suite.
+// set_up_tc: pointer to the function that sets up the test suite
+// tear_down_tc: pointer to the function that tears down the test suite
+TestSuite::TestSuite(const char* a_name, const char* a_type_param,
+ internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc)
: name_(a_name),
- type_param_(a_type_param ? new std::string(a_type_param) : NULL),
+ type_param_(a_type_param ? new std::string(a_type_param) : nullptr),
set_up_tc_(set_up_tc),
tear_down_tc_(tear_down_tc),
should_run_(false),
- elapsed_time_(0) {
-}
+ start_timestamp_(0),
+ elapsed_time_(0) {}
-// Destructor of TestCase.
-TestCase::~TestCase() {
+// Destructor of TestSuite.
+TestSuite::~TestSuite() {
// Deletes every Test in the collection.
ForEach(test_info_list_, internal::Delete<TestInfo>);
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
-const TestInfo* TestCase::GetTestInfo(int i) const {
+const TestInfo* TestSuite::GetTestInfo(int i) const {
const int index = GetElementOr(test_indices_, i, -1);
- return index < 0 ? NULL : test_info_list_[index];
+ return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];
}
// Returns the i-th test among all the tests. i can range from 0 to
// total_test_count() - 1. If i is not in that range, returns NULL.
-TestInfo* TestCase::GetMutableTestInfo(int i) {
+TestInfo* TestSuite::GetMutableTestInfo(int i) {
const int index = GetElementOr(test_indices_, i, -1);
- return index < 0 ? NULL : test_info_list_[index];
+ return index < 0 ? nullptr : test_info_list_[static_cast<size_t>(index)];
}
-// Adds a test to this test case. Will delete the test upon
-// destruction of the TestCase object.
-void TestCase::AddTestInfo(TestInfo * test_info) {
+// Adds a test to this test suite. Will delete the test upon
+// destruction of the TestSuite object.
+void TestSuite::AddTestInfo(TestInfo* test_info) {
test_info_list_.push_back(test_info);
test_indices_.push_back(static_cast<int>(test_indices_.size()));
}
-// Runs every test in this TestCase.
-void TestCase::Run() {
+// Runs every test in this TestSuite.
+void TestSuite::Run() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
- impl->set_current_test_case(this);
+ impl->set_current_test_suite(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
+ // Call both legacy and the new API
+ repeater->OnTestSuiteStart(*this);
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
repeater->OnTestCaseStart(*this);
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI
+
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
- this, &TestCase::RunSetUpTestCase, "SetUpTestCase()");
+ this, &TestSuite::RunSetUpTestSuite, "SetUpTestSuite()");
- const internal::TimeInMillis start = internal::GetTimeInMillis();
+ start_timestamp_ = internal::GetTimeInMillis();
for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Run();
}
- elapsed_time_ = internal::GetTimeInMillis() - start;
+ elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_;
impl->os_stack_trace_getter()->UponLeavingGTest();
internal::HandleExceptionsInMethodIfSupported(
- this, &TestCase::RunTearDownTestCase, "TearDownTestCase()");
+ this, &TestSuite::RunTearDownTestSuite, "TearDownTestSuite()");
+ // Call both legacy and the new API
+ repeater->OnTestSuiteEnd(*this);
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
repeater->OnTestCaseEnd(*this);
- impl->set_current_test_case(NULL);
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI
+
+ impl->set_current_test_suite(nullptr);
}
-// Clears the results of all tests in this test case.
-void TestCase::ClearResult() {
+// Clears the results of all tests in this test suite.
+void TestSuite::ClearResult() {
ad_hoc_test_result_.Clear();
ForEach(test_info_list_, TestInfo::ClearTestResult);
}
-// Shuffles the tests in this test case.
-void TestCase::ShuffleTests(internal::Random* random) {
+// Shuffles the tests in this test suite.
+void TestSuite::ShuffleTests(internal::Random* random) {
Shuffle(random, &test_indices_);
}
// Restores the test order to before the first shuffle.
-void TestCase::UnshuffleTests() {
+void TestSuite::UnshuffleTests() {
for (size_t i = 0; i < test_indices_.size(); i++) {
test_indices_[i] = static_cast<int>(i);
}
@@ -2818,9 +2866,9 @@
return FormatCountableNoun(test_count, "test", "tests");
}
-// Formats the count of test cases.
-static std::string FormatTestCaseCount(int test_case_count) {
- return FormatCountableNoun(test_case_count, "test case", "test cases");
+// Formats the count of test suites.
+static std::string FormatTestSuiteCount(int test_suite_count) {
+ return FormatCountableNoun(test_suite_count, "test suite", "test suites");
}
// Converts a TestPartResult::Type enum to human-friendly string
@@ -2829,6 +2877,8 @@
// between the two when viewing the test result.
static const char * TestPartResultTypeToString(TestPartResult::Type type) {
switch (type) {
+ case TestPartResult::kSkip:
+ return "Skipped";
case TestPartResult::kSuccess:
return "Success";
@@ -2876,19 +2926,11 @@
}
// class PrettyUnitTestResultPrinter
-
-enum GTestColor {
- COLOR_DEFAULT,
- COLOR_RED,
- COLOR_GREEN,
- COLOR_YELLOW
-};
-
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \
- !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
+ !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
// Returns the character attribute for the given color.
-WORD GetColorAttribute(GTestColor color) {
+static WORD GetColorAttribute(GTestColor color) {
switch (color) {
case COLOR_RED: return FOREGROUND_RED;
case COLOR_GREEN: return FOREGROUND_GREEN;
@@ -2897,27 +2939,59 @@
}
}
+static int GetBitOffset(WORD color_mask) {
+ if (color_mask == 0) return 0;
+
+ int bitOffset = 0;
+ while ((color_mask & 1) == 0) {
+ color_mask >>= 1;
+ ++bitOffset;
+ }
+ return bitOffset;
+}
+
+static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
+ // Let's reuse the BG
+ static const WORD background_mask = BACKGROUND_BLUE | BACKGROUND_GREEN |
+ BACKGROUND_RED | BACKGROUND_INTENSITY;
+ static const WORD foreground_mask = FOREGROUND_BLUE | FOREGROUND_GREEN |
+ FOREGROUND_RED | FOREGROUND_INTENSITY;
+ const WORD existing_bg = old_color_attrs & background_mask;
+
+ WORD new_color =
+ GetColorAttribute(color) | existing_bg | FOREGROUND_INTENSITY;
+ static const int bg_bitOffset = GetBitOffset(background_mask);
+ static const int fg_bitOffset = GetBitOffset(foreground_mask);
+
+ if (((new_color & background_mask) >> bg_bitOffset) ==
+ ((new_color & foreground_mask) >> fg_bitOffset)) {
+ new_color ^= FOREGROUND_INTENSITY; // invert intensity
+ }
+ return new_color;
+}
+
#else
// Returns the ANSI color code for the given color. COLOR_DEFAULT is
// an invalid input.
-const char* GetAnsiColorCode(GTestColor color) {
+static const char* GetAnsiColorCode(GTestColor color) {
switch (color) {
case COLOR_RED: return "1";
case COLOR_GREEN: return "2";
case COLOR_YELLOW: return "3";
- default: return NULL;
- };
+ default:
+ return nullptr;
+ }
}
#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE
-// Returns true iff Google Test should use colors in the output.
+// Returns true if and only if Google Test should use colors in the output.
bool ShouldUseColor(bool stdout_is_tty) {
const char* const gtest_color = GTEST_FLAG(color).c_str();
if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) {
-#if GTEST_OS_WINDOWS
+#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW
// On Windows the TERM variable is usually not set, but the
// console there does support colors.
return stdout_is_tty;
@@ -2957,15 +3031,14 @@
va_list args;
va_start(args, fmt);
-#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \
- GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT
+#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS || GTEST_OS_IOS || \
+ GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT || defined(ESP_PLATFORM)
const bool use_color = AlwaysFalse();
#else
static const bool in_color_mode =
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
-#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS
- // The '!= 0' comparison is necessary to satisfy MSVC 7.1.
+#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS
if (!use_color) {
vprintf(fmt, args);
@@ -2974,20 +3047,21 @@
}
#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \
- !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT
+ !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT && !GTEST_OS_WINDOWS_MINGW
const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
// Gets the current text color.
CONSOLE_SCREEN_BUFFER_INFO buffer_info;
GetConsoleScreenBufferInfo(stdout_handle, &buffer_info);
const WORD old_color_attrs = buffer_info.wAttributes;
+ const WORD new_color = GetNewColor(color, old_color_attrs);
// We need to flush the stream buffers into the console before each
// SetConsoleTextAttribute call lest it affect the text that is already
// printed but has not yet reached the console.
fflush(stdout);
- SetConsoleTextAttribute(stdout_handle,
- GetColorAttribute(color) | FOREGROUND_INTENSITY);
+ SetConsoleTextAttribute(stdout_handle, new_color);
+
vprintf(fmt, args);
fflush(stdout);
@@ -3001,23 +3075,22 @@
va_end(args);
}
-// Text printed in Google Test's text output and --gunit_list_tests
+// Text printed in Google Test's text output and --gtest_list_tests
// output to label the type parameter and value parameter for a test.
static const char kTypeParamLabel[] = "TypeParam";
static const char kValueParamLabel[] = "GetParam()";
-void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
+static void PrintFullTestCommentIfPresent(const TestInfo& test_info) {
const char* const type_param = test_info.type_param();
const char* const value_param = test_info.value_param();
- if (type_param != NULL || value_param != NULL) {
+ if (type_param != nullptr || value_param != nullptr) {
printf(", where ");
- if (type_param != NULL) {
+ if (type_param != nullptr) {
printf("%s = %s", kTypeParamLabel, type_param);
- if (value_param != NULL)
- printf(" and ");
+ if (value_param != nullptr) printf(" and ");
}
- if (value_param != NULL) {
+ if (value_param != nullptr) {
printf("%s = %s", kValueParamLabel, value_param);
}
}
@@ -3029,27 +3102,39 @@
class PrettyUnitTestResultPrinter : public TestEventListener {
public:
PrettyUnitTestResultPrinter() {}
- static void PrintTestName(const char * test_case, const char * test) {
- printf("%s.%s", test_case, test);
+ static void PrintTestName(const char* test_suite, const char* test) {
+ printf("%s.%s", test_suite, test);
}
// The following methods override what's in the TestEventListener class.
- virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
- virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
- virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
- virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
- virtual void OnTestCaseStart(const TestCase& test_case);
- virtual void OnTestStart(const TestInfo& test_info);
- virtual void OnTestPartResult(const TestPartResult& result);
- virtual void OnTestEnd(const TestInfo& test_info);
- virtual void OnTestCaseEnd(const TestCase& test_case);
- virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
- virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
- virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
- virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
+ void OnTestProgramStart(const UnitTest& /*unit_test*/) override {}
+ void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;
+ void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;
+ void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) override {}
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestCaseStart(const TestCase& test_case) override;
+#else
+ void OnTestSuiteStart(const TestSuite& test_suite) override;
+#endif // OnTestCaseStart
+
+ void OnTestStart(const TestInfo& test_info) override;
+
+ void OnTestPartResult(const TestPartResult& result) override;
+ void OnTestEnd(const TestInfo& test_info) override;
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestCaseEnd(const TestCase& test_case) override;
+#else
+ void OnTestSuiteEnd(const TestSuite& test_suite) override;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
+ void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;
+ void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) override {}
+ void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+ void OnTestProgramEnd(const UnitTest& /*unit_test*/) override {}
private:
static void PrintFailedTests(const UnitTest& unit_test);
+ static void PrintSkippedTests(const UnitTest& unit_test);
};
// Fired before each iteration of tests starts.
@@ -3084,7 +3169,7 @@
ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("Running %s from %s.\n",
FormatTestCount(unit_test.test_to_run_count()).c_str(),
- FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+ FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
fflush(stdout);
}
@@ -3095,22 +3180,38 @@
fflush(stdout);
}
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
const std::string counts =
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_case.name());
- if (test_case.type_param() == NULL) {
+ if (test_case.type_param() == nullptr) {
printf("\n");
} else {
printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param());
}
fflush(stdout);
}
+#else
+void PrettyUnitTestResultPrinter::OnTestSuiteStart(
+ const TestSuite& test_suite) {
+ const std::string counts =
+ FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
+ ColoredPrintf(COLOR_GREEN, "[----------] ");
+ printf("%s from %s", counts.c_str(), test_suite.name());
+ if (test_suite.type_param() == nullptr) {
+ printf("\n");
+ } else {
+ printf(", where %s = %s\n", kTypeParamLabel, test_suite.type_param());
+ }
+ fflush(stdout);
+}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
- PrintTestName(test_info.test_case_name(), test_info.name());
+ PrintTestName(test_info.test_suite_name(), test_info.name());
printf("\n");
fflush(stdout);
}
@@ -3118,22 +3219,29 @@
// Called after an assertion failure.
void PrettyUnitTestResultPrinter::OnTestPartResult(
const TestPartResult& result) {
- // If the test part succeeded, we don't need to do anything.
- if (result.type() == TestPartResult::kSuccess)
- return;
-
- // Print failure message from the assertion (e.g. expected this and got that).
- PrintTestPartResult(result);
- fflush(stdout);
+ switch (result.type()) {
+ // If the test part succeeded, or was skipped,
+ // we don't need to do anything.
+ case TestPartResult::kSkip:
+ case TestPartResult::kSuccess:
+ return;
+ default:
+ // Print failure message from the assertion
+ // (e.g. expected this and got that).
+ PrintTestPartResult(result);
+ fflush(stdout);
+ }
}
void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
if (test_info.result()->Passed()) {
ColoredPrintf(COLOR_GREEN, "[ OK ] ");
+ } else if (test_info.result()->Skipped()) {
+ ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] ");
} else {
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
}
- PrintTestName(test_info.test_case_name(), test_info.name());
+ PrintTestName(test_info.test_suite_name(), test_info.name());
if (test_info.result()->Failed())
PrintFullTestCommentIfPresent(test_info);
@@ -3146,17 +3254,29 @@
fflush(stdout);
}
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
if (!GTEST_FLAG(print_time)) return;
const std::string counts =
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(COLOR_GREEN, "[----------] ");
- printf("%s from %s (%s ms total)\n\n",
- counts.c_str(), test_case.name(),
+ printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(),
internal::StreamableToString(test_case.elapsed_time()).c_str());
fflush(stdout);
}
+#else
+void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
+ if (!GTEST_FLAG(print_time)) return;
+
+ const std::string counts =
+ FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
+ ColoredPrintf(COLOR_GREEN, "[----------] ");
+ printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(),
+ internal::StreamableToString(test_suite.elapsed_time()).c_str());
+ fflush(stdout);
+}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
const UnitTest& /*unit_test*/) {
@@ -3172,30 +3292,54 @@
return;
}
- for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
- const TestCase& test_case = *unit_test.GetTestCase(i);
- if (!test_case.should_run() || (test_case.failed_test_count() == 0)) {
+ for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+ const TestSuite& test_suite = *unit_test.GetTestSuite(i);
+ if (!test_suite.should_run() || (test_suite.failed_test_count() == 0)) {
continue;
}
- for (int j = 0; j < test_case.total_test_count(); ++j) {
- const TestInfo& test_info = *test_case.GetTestInfo(j);
- if (!test_info.should_run() || test_info.result()->Passed()) {
+ for (int j = 0; j < test_suite.total_test_count(); ++j) {
+ const TestInfo& test_info = *test_suite.GetTestInfo(j);
+ if (!test_info.should_run() || !test_info.result()->Failed()) {
continue;
}
ColoredPrintf(COLOR_RED, "[ FAILED ] ");
- printf("%s.%s", test_case.name(), test_info.name());
+ printf("%s.%s", test_suite.name(), test_info.name());
PrintFullTestCommentIfPresent(test_info);
printf("\n");
}
}
}
+// Internal helper for printing the list of skipped tests.
+void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {
+ const int skipped_test_count = unit_test.skipped_test_count();
+ if (skipped_test_count == 0) {
+ return;
+ }
+
+ for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+ const TestSuite& test_suite = *unit_test.GetTestSuite(i);
+ if (!test_suite.should_run() || (test_suite.skipped_test_count() == 0)) {
+ continue;
+ }
+ for (int j = 0; j < test_suite.total_test_count(); ++j) {
+ const TestInfo& test_info = *test_suite.GetTestInfo(j);
+ if (!test_info.should_run() || !test_info.result()->Skipped()) {
+ continue;
+ }
+ ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] ");
+ printf("%s.%s", test_suite.name(), test_info.name());
+ printf("\n");
+ }
+ }
+}
+
void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
int /*iteration*/) {
ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("%s from %s ran.",
FormatTestCount(unit_test.test_to_run_count()).c_str(),
- FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str());
+ FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
if (GTEST_FLAG(print_time)) {
printf(" (%s ms total)",
internal::StreamableToString(unit_test.elapsed_time()).c_str());
@@ -3204,6 +3348,13 @@
ColoredPrintf(COLOR_GREEN, "[ PASSED ] ");
printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
+ const int skipped_test_count = unit_test.skipped_test_count();
+ if (skipped_test_count > 0) {
+ ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] ");
+ printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str());
+ PrintSkippedTests(unit_test);
+ }
+
int num_failures = unit_test.failed_test_count();
if (!unit_test.Passed()) {
const int failed_test_count = unit_test.failed_test_count();
@@ -3236,7 +3387,7 @@
class TestEventRepeater : public TestEventListener {
public:
TestEventRepeater() : forwarding_enabled_(true) {}
- virtual ~TestEventRepeater();
+ ~TestEventRepeater() override;
void Append(TestEventListener *listener);
TestEventListener* Release(TestEventListener* listener);
@@ -3245,19 +3396,27 @@
bool forwarding_enabled() const { return forwarding_enabled_; }
void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; }
- virtual void OnTestProgramStart(const UnitTest& unit_test);
- virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration);
- virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test);
- virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test);
- virtual void OnTestCaseStart(const TestCase& test_case);
- virtual void OnTestStart(const TestInfo& test_info);
- virtual void OnTestPartResult(const TestPartResult& result);
- virtual void OnTestEnd(const TestInfo& test_info);
- virtual void OnTestCaseEnd(const TestCase& test_case);
- virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test);
- virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test);
- virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
- virtual void OnTestProgramEnd(const UnitTest& unit_test);
+ void OnTestProgramStart(const UnitTest& unit_test) override;
+ void OnTestIterationStart(const UnitTest& unit_test, int iteration) override;
+ void OnEnvironmentsSetUpStart(const UnitTest& unit_test) override;
+ void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) override;
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestCaseStart(const TestSuite& parameter) override;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestSuiteStart(const TestSuite& parameter) override;
+ void OnTestStart(const TestInfo& test_info) override;
+ void OnTestPartResult(const TestPartResult& result) override;
+ void OnTestEnd(const TestInfo& test_info) override;
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestCaseEnd(const TestCase& parameter) override;
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+ void OnTestSuiteEnd(const TestSuite& parameter) override;
+ void OnEnvironmentsTearDownStart(const UnitTest& unit_test) override;
+ void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) override;
+ void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+ void OnTestProgramEnd(const UnitTest& unit_test) override;
private:
// Controls whether events will be forwarded to listeners_. Set to false
@@ -3277,16 +3436,15 @@
listeners_.push_back(listener);
}
-// TODO([email protected]): Factor the search functionality into Vector::Find.
TestEventListener* TestEventRepeater::Release(TestEventListener *listener) {
for (size_t i = 0; i < listeners_.size(); ++i) {
if (listeners_[i] == listener) {
- listeners_.erase(listeners_.begin() + i);
+ listeners_.erase(listeners_.begin() + static_cast<int>(i));
return listener;
}
}
- return NULL;
+ return nullptr;
}
// Since most methods are very similar, use macros to reduce boilerplate.
@@ -3301,25 +3459,33 @@
}
// This defines a member that forwards the call to all listeners in reverse
// order.
-#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
-void TestEventRepeater::Name(const Type& parameter) { \
- if (forwarding_enabled_) { \
- for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \
- listeners_[i]->Name(parameter); \
- } \
- } \
-}
+#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \
+ void TestEventRepeater::Name(const Type& parameter) { \
+ if (forwarding_enabled_) { \
+ for (size_t i = listeners_.size(); i != 0; i--) { \
+ listeners_[i - 1]->Name(parameter); \
+ } \
+ } \
+ }
GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest)
GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest)
-GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase)
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REPEATER_METHOD_(OnTestCaseStart, TestSuite)
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REPEATER_METHOD_(OnTestSuiteStart, TestSuite)
GTEST_REPEATER_METHOD_(OnTestStart, TestInfo)
GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult)
GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest)
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest)
GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest)
GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo)
-GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase)
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestSuite)
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+GTEST_REVERSE_REPEATER_METHOD_(OnTestSuiteEnd, TestSuite)
GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest)
#undef GTEST_REPEATER_METHOD_
@@ -3337,8 +3503,8 @@
void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test,
int iteration) {
if (forwarding_enabled_) {
- for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) {
- listeners_[i]->OnTestIterationEnd(unit_test, iteration);
+ for (size_t i = listeners_.size(); i > 0; i--) {
+ listeners_[i - 1]->OnTestIterationEnd(unit_test, iteration);
}
}
}
@@ -3350,7 +3516,12 @@
public:
explicit XmlUnitTestResultPrinter(const char* output_file);
- virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration);
+ void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+ void ListTestsMatchingFilter(const std::vector<TestSuite*>& test_suites);
+
+ // Prints an XML summary of all unit tests.
+ static void PrintXmlTestsList(std::ostream* stream,
+ const std::vector<TestSuite*>& test_suites);
private:
// Is c a whitespace character that is normalized to a space character
@@ -3395,12 +3566,12 @@
// Streams an XML representation of a TestInfo object.
static void OutputXmlTestInfo(::std::ostream* stream,
- const char* test_case_name,
+ const char* test_suite_name,
const TestInfo& test_info);
- // Prints an XML representation of a TestCase object
- static void PrintXmlTestCase(::std::ostream* stream,
- const TestCase& test_case);
+ // Prints an XML representation of a TestSuite object
+ static void PrintXmlTestSuite(::std::ostream* stream,
+ const TestSuite& test_suite);
// Prints an XML summary of unit_test to output stream out.
static void PrintXmlUnitTest(::std::ostream* stream,
@@ -3412,6 +3583,11 @@
// to delimit this attribute from prior attributes.
static std::string TestPropertiesAsXmlAttributes(const TestResult& result);
+ // Streams an XML representation of the test properties of a TestResult
+ // object.
+ static void OutputXmlTestProperties(std::ostream* stream,
+ const TestResult& result);
+
// The output file.
const std::string output_file_;
@@ -3421,46 +3597,30 @@
// Creates a new XmlUnitTestResultPrinter.
XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
: output_file_(output_file) {
- if (output_file_.c_str() == NULL || output_file_.empty()) {
- fprintf(stderr, "XML output file may not be null\n");
- fflush(stderr);
- exit(EXIT_FAILURE);
+ if (output_file_.empty()) {
+ GTEST_LOG_(FATAL) << "XML output file may not be null";
}
}
// Called after the unit test ends.
void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
int /*iteration*/) {
- FILE* xmlout = NULL;
- FilePath output_file(output_file_);
- FilePath output_dir(output_file.RemoveFileName());
-
- if (output_dir.CreateDirectoriesRecursively()) {
- xmlout = posix::FOpen(output_file_.c_str(), "w");
- }
- if (xmlout == NULL) {
- // TODO(wan): report the reason of the failure.
- //
- // We don't do it for now as:
- //
- // 1. There is no urgent need for it.
- // 2. It's a bit involved to make the errno variable thread-safe on
- // all three operating systems (Linux, Windows, and Mac OS).
- // 3. To interpret the meaning of errno in a thread-safe way,
- // we need the strerror_r() function, which is not available on
- // Windows.
- fprintf(stderr,
- "Unable to open file \"%s\"\n",
- output_file_.c_str());
- fflush(stderr);
- exit(EXIT_FAILURE);
- }
+ FILE* xmlout = OpenFileForWriting(output_file_);
std::stringstream stream;
PrintXmlUnitTest(&stream, unit_test);
fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
fclose(xmlout);
}
+void XmlUnitTestResultPrinter::ListTestsMatchingFilter(
+ const std::vector<TestSuite*>& test_suites) {
+ FILE* xmlout = OpenFileForWriting(output_file_);
+ std::stringstream stream;
+ PrintXmlTestsList(&stream, test_suites);
+ fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
+ fclose(xmlout);
+}
+
// Returns an XML-escaped copy of the input string str. If is_attribute
// is true, the text is meant to appear as an attribute value, and
// normalizable whitespace is preserved by replacing it with character
@@ -3471,8 +3631,6 @@
// module will consist of ordinary English text.
// If this module is ever modified to produce version 1.1 XML output,
// most invalid characters can be retained using character references.
-// TODO(wan): It might be nice to have a minimally invasive, human-readable
-// escaping scheme for invalid characters, rather than dropping them.
std::string XmlUnitTestResultPrinter::EscapeXml(
const std::string& str, bool is_attribute) {
Message m;
@@ -3532,11 +3690,12 @@
// The following routines generate an XML representation of a UnitTest
// object.
+// GOOGLETEST_CM0009 DO NOT DELETE
//
// This is how Google Test concepts map to the DTD:
//
// <testsuites name="AllTests"> <-- corresponds to a UnitTest object
-// <testsuite name="testcase-name"> <-- corresponds to a TestCase object
+// <testsuite name="testcase-name"> <-- corresponds to a TestSuite object
// <testcase name="test-name"> <-- corresponds to a TestInfo object
// <failure message="...">...</failure>
// <failure message="...">...</failure>
@@ -3560,12 +3719,11 @@
// MINGW <time.h> provides neither localtime_r nor localtime_s, but uses
// Windows' localtime(), which has a thread-local tm buffer.
struct tm* tm_ptr = localtime(&seconds); // NOLINT
- if (tm_ptr == NULL)
- return false;
+ if (tm_ptr == nullptr) return false;
*out = *tm_ptr;
return true;
#else
- return localtime_r(&seconds, out) != NULL;
+ return localtime_r(&seconds, out) != nullptr;
#endif
}
@@ -3591,7 +3749,7 @@
*stream << "<![CDATA[";
for (;;) {
const char* const next_segment = strstr(segment, "]]>");
- if (next_segment != NULL) {
+ if (next_segment != nullptr) {
stream->write(
segment, static_cast<std::streamsize>(next_segment - segment));
*stream << "]]>]]><![CDATA[";
@@ -3610,7 +3768,7 @@
const std::string& name,
const std::string& value) {
const std::vector<std::string>& allowed_names =
- GetReservedAttributesForElement(element_name);
+ GetReservedOutputAttributesForElement(element_name);
GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
allowed_names.end())
@@ -3621,30 +3779,47 @@
}
// Prints an XML representation of a TestInfo object.
-// TODO(wan): There is also value in printing properties with the plain printer.
void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
- const char* test_case_name,
+ const char* test_suite_name,
const TestInfo& test_info) {
const TestResult& result = *test_info.result();
- const std::string kTestcase = "testcase";
+ const std::string kTestsuite = "testcase";
+
+ if (test_info.is_in_another_shard()) {
+ return;
+ }
*stream << " <testcase";
- OutputXmlAttribute(stream, kTestcase, "name", test_info.name());
+ OutputXmlAttribute(stream, kTestsuite, "name", test_info.name());
- if (test_info.value_param() != NULL) {
- OutputXmlAttribute(stream, kTestcase, "value_param",
+ if (test_info.value_param() != nullptr) {
+ OutputXmlAttribute(stream, kTestsuite, "value_param",
test_info.value_param());
}
- if (test_info.type_param() != NULL) {
- OutputXmlAttribute(stream, kTestcase, "type_param", test_info.type_param());
+ if (test_info.type_param() != nullptr) {
+ OutputXmlAttribute(stream, kTestsuite, "type_param",
+ test_info.type_param());
+ }
+ if (GTEST_FLAG(list_tests)) {
+ OutputXmlAttribute(stream, kTestsuite, "file", test_info.file());
+ OutputXmlAttribute(stream, kTestsuite, "line",
+ StreamableToString(test_info.line()));
+ *stream << " />\n";
+ return;
}
- OutputXmlAttribute(stream, kTestcase, "status",
+ OutputXmlAttribute(stream, kTestsuite, "status",
test_info.should_run() ? "run" : "notrun");
- OutputXmlAttribute(stream, kTestcase, "time",
+ OutputXmlAttribute(stream, kTestsuite, "result",
+ test_info.should_run()
+ ? (result.Skipped() ? "skipped" : "completed")
+ : "suppressed");
+ OutputXmlAttribute(stream, kTestsuite, "time",
FormatTimeInMillisAsSeconds(result.elapsed_time()));
- OutputXmlAttribute(stream, kTestcase, "classname", test_case_name);
- *stream << TestPropertiesAsXmlAttributes(result);
+ OutputXmlAttribute(
+ stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsIso8601(result.start_timestamp()));
+ OutputXmlAttribute(stream, kTestsuite, "classname", test_suite_name);
int failures = 0;
for (int i = 0; i < result.total_part_count(); ++i) {
@@ -3653,46 +3828,56 @@
if (++failures == 1) {
*stream << ">\n";
}
- const string location = internal::FormatCompilerIndependentFileLocation(
- part.file_name(), part.line_number());
- const string summary = location + "\n" + part.summary();
+ const std::string location =
+ internal::FormatCompilerIndependentFileLocation(part.file_name(),
+ part.line_number());
+ const std::string summary = location + "\n" + part.summary();
*stream << " <failure message=\""
<< EscapeXmlAttribute(summary.c_str())
<< "\" type=\"\">";
- const string detail = location + "\n" + part.message();
+ const std::string detail = location + "\n" + part.message();
OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str());
*stream << "</failure>\n";
}
}
- if (failures == 0)
+ if (failures == 0 && result.test_property_count() == 0) {
*stream << " />\n";
- else
+ } else {
+ if (failures == 0) {
+ *stream << ">\n";
+ }
+ OutputXmlTestProperties(stream, result);
*stream << " </testcase>\n";
+ }
}
-// Prints an XML representation of a TestCase object
-void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream,
- const TestCase& test_case) {
+// Prints an XML representation of a TestSuite object
+void XmlUnitTestResultPrinter::PrintXmlTestSuite(std::ostream* stream,
+ const TestSuite& test_suite) {
const std::string kTestsuite = "testsuite";
*stream << " <" << kTestsuite;
- OutputXmlAttribute(stream, kTestsuite, "name", test_case.name());
+ OutputXmlAttribute(stream, kTestsuite, "name", test_suite.name());
OutputXmlAttribute(stream, kTestsuite, "tests",
- StreamableToString(test_case.reportable_test_count()));
- OutputXmlAttribute(stream, kTestsuite, "failures",
- StreamableToString(test_case.failed_test_count()));
- OutputXmlAttribute(
- stream, kTestsuite, "disabled",
- StreamableToString(test_case.reportable_disabled_test_count()));
- OutputXmlAttribute(stream, kTestsuite, "errors", "0");
- OutputXmlAttribute(stream, kTestsuite, "time",
- FormatTimeInMillisAsSeconds(test_case.elapsed_time()));
- *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result())
- << ">\n";
-
- for (int i = 0; i < test_case.total_test_count(); ++i) {
- if (test_case.GetTestInfo(i)->is_reportable())
- OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i));
+ StreamableToString(test_suite.reportable_test_count()));
+ if (!GTEST_FLAG(list_tests)) {
+ OutputXmlAttribute(stream, kTestsuite, "failures",
+ StreamableToString(test_suite.failed_test_count()));
+ OutputXmlAttribute(
+ stream, kTestsuite, "disabled",
+ StreamableToString(test_suite.reportable_disabled_test_count()));
+ OutputXmlAttribute(stream, kTestsuite, "errors", "0");
+ OutputXmlAttribute(stream, kTestsuite, "time",
+ FormatTimeInMillisAsSeconds(test_suite.elapsed_time()));
+ OutputXmlAttribute(
+ stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsIso8601(test_suite.start_timestamp()));
+ *stream << TestPropertiesAsXmlAttributes(test_suite.ad_hoc_test_result());
+ }
+ *stream << ">\n";
+ for (int i = 0; i < test_suite.total_test_count(); ++i) {
+ if (test_suite.GetTestInfo(i)->is_reportable())
+ OutputXmlTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
}
*stream << " </" << kTestsuite << ">\n";
}
@@ -3713,25 +3898,46 @@
stream, kTestsuites, "disabled",
StreamableToString(unit_test.reportable_disabled_test_count()));
OutputXmlAttribute(stream, kTestsuites, "errors", "0");
+ OutputXmlAttribute(stream, kTestsuites, "time",
+ FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
OutputXmlAttribute(
stream, kTestsuites, "timestamp",
FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp()));
- OutputXmlAttribute(stream, kTestsuites, "time",
- FormatTimeInMillisAsSeconds(unit_test.elapsed_time()));
if (GTEST_FLAG(shuffle)) {
OutputXmlAttribute(stream, kTestsuites, "random_seed",
StreamableToString(unit_test.random_seed()));
}
-
*stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result());
OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
*stream << ">\n";
- for (int i = 0; i < unit_test.total_test_case_count(); ++i) {
- if (unit_test.GetTestCase(i)->reportable_test_count() > 0)
- PrintXmlTestCase(stream, *unit_test.GetTestCase(i));
+ for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+ if (unit_test.GetTestSuite(i)->reportable_test_count() > 0)
+ PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i));
+ }
+ *stream << "</" << kTestsuites << ">\n";
+}
+
+void XmlUnitTestResultPrinter::PrintXmlTestsList(
+ std::ostream* stream, const std::vector<TestSuite*>& test_suites) {
+ const std::string kTestsuites = "testsuites";
+
+ *stream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+ *stream << "<" << kTestsuites;
+
+ int total_tests = 0;
+ for (auto test_suite : test_suites) {
+ total_tests += test_suite->total_test_count();
+ }
+ OutputXmlAttribute(stream, kTestsuites, "tests",
+ StreamableToString(total_tests));
+ OutputXmlAttribute(stream, kTestsuites, "name", "AllTests");
+ *stream << ">\n";
+
+ for (auto test_suite : test_suites) {
+ PrintXmlTestSuite(stream, *test_suite);
}
*stream << "</" << kTestsuites << ">\n";
}
@@ -3749,8 +3955,403 @@
return attributes.GetString();
}
+void XmlUnitTestResultPrinter::OutputXmlTestProperties(
+ std::ostream* stream, const TestResult& result) {
+ const std::string kProperties = "properties";
+ const std::string kProperty = "property";
+
+ if (result.test_property_count() <= 0) {
+ return;
+ }
+
+ *stream << "<" << kProperties << ">\n";
+ for (int i = 0; i < result.test_property_count(); ++i) {
+ const TestProperty& property = result.GetTestProperty(i);
+ *stream << "<" << kProperty;
+ *stream << " name=\"" << EscapeXmlAttribute(property.key()) << "\"";
+ *stream << " value=\"" << EscapeXmlAttribute(property.value()) << "\"";
+ *stream << "/>\n";
+ }
+ *stream << "</" << kProperties << ">\n";
+}
+
// End XmlUnitTestResultPrinter
+// This class generates an JSON output file.
+class JsonUnitTestResultPrinter : public EmptyTestEventListener {
+ public:
+ explicit JsonUnitTestResultPrinter(const char* output_file);
+
+ void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override;
+
+ // Prints an JSON summary of all unit tests.
+ static void PrintJsonTestList(::std::ostream* stream,
+ const std::vector<TestSuite*>& test_suites);
+
+ private:
+ // Returns an JSON-escaped copy of the input string str.
+ static std::string EscapeJson(const std::string& str);
+
+ //// Verifies that the given attribute belongs to the given element and
+ //// streams the attribute as JSON.
+ static void OutputJsonKey(std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ const std::string& value,
+ const std::string& indent,
+ bool comma = true);
+ static void OutputJsonKey(std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ int value,
+ const std::string& indent,
+ bool comma = true);
+
+ // Streams a JSON representation of a TestInfo object.
+ static void OutputJsonTestInfo(::std::ostream* stream,
+ const char* test_suite_name,
+ const TestInfo& test_info);
+
+ // Prints a JSON representation of a TestSuite object
+ static void PrintJsonTestSuite(::std::ostream* stream,
+ const TestSuite& test_suite);
+
+ // Prints a JSON summary of unit_test to output stream out.
+ static void PrintJsonUnitTest(::std::ostream* stream,
+ const UnitTest& unit_test);
+
+ // Produces a string representing the test properties in a result as
+ // a JSON dictionary.
+ static std::string TestPropertiesAsJson(const TestResult& result,
+ const std::string& indent);
+
+ // The output file.
+ const std::string output_file_;
+
+ GTEST_DISALLOW_COPY_AND_ASSIGN_(JsonUnitTestResultPrinter);
+};
+
+// Creates a new JsonUnitTestResultPrinter.
+JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
+ : output_file_(output_file) {
+ if (output_file_.empty()) {
+ GTEST_LOG_(FATAL) << "JSON output file may not be null";
+ }
+}
+
+void JsonUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
+ int /*iteration*/) {
+ FILE* jsonout = OpenFileForWriting(output_file_);
+ std::stringstream stream;
+ PrintJsonUnitTest(&stream, unit_test);
+ fprintf(jsonout, "%s", StringStreamToString(&stream).c_str());
+ fclose(jsonout);
+}
+
+// Returns an JSON-escaped copy of the input string str.
+std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
+ Message m;
+
+ for (size_t i = 0; i < str.size(); ++i) {
+ const char ch = str[i];
+ switch (ch) {
+ case '\\':
+ case '"':
+ case '/':
+ m << '\\' << ch;
+ break;
+ case '\b':
+ m << "\\b";
+ break;
+ case '\t':
+ m << "\\t";
+ break;
+ case '\n':
+ m << "\\n";
+ break;
+ case '\f':
+ m << "\\f";
+ break;
+ case '\r':
+ m << "\\r";
+ break;
+ default:
+ if (ch < ' ') {
+ m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
+ } else {
+ m << ch;
+ }
+ break;
+ }
+ }
+
+ return m.GetString();
+}
+
+// The following routines generate an JSON representation of a UnitTest
+// object.
+
+// Formats the given time in milliseconds as seconds.
+static std::string FormatTimeInMillisAsDuration(TimeInMillis ms) {
+ ::std::stringstream ss;
+ ss << (static_cast<double>(ms) * 1e-3) << "s";
+ return ss.str();
+}
+
+// Converts the given epoch time in milliseconds to a date string in the
+// RFC3339 format, without the timezone information.
+static std::string FormatEpochTimeInMillisAsRFC3339(TimeInMillis ms) {
+ struct tm time_struct;
+ if (!PortableLocaltime(static_cast<time_t>(ms / 1000), &time_struct))
+ return "";
+ // YYYY-MM-DDThh:mm:ss
+ return StreamableToString(time_struct.tm_year + 1900) + "-" +
+ String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" +
+ String::FormatIntWidth2(time_struct.tm_mday) + "T" +
+ String::FormatIntWidth2(time_struct.tm_hour) + ":" +
+ String::FormatIntWidth2(time_struct.tm_min) + ":" +
+ String::FormatIntWidth2(time_struct.tm_sec) + "Z";
+}
+
+static inline std::string Indent(size_t width) {
+ return std::string(width, ' ');
+}
+
+void JsonUnitTestResultPrinter::OutputJsonKey(
+ std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ const std::string& value,
+ const std::string& indent,
+ bool comma) {
+ const std::vector<std::string>& allowed_names =
+ GetReservedOutputAttributesForElement(element_name);
+
+ GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
+ allowed_names.end())
+ << "Key \"" << name << "\" is not allowed for value \"" << element_name
+ << "\".";
+
+ *stream << indent << "\"" << name << "\": \"" << EscapeJson(value) << "\"";
+ if (comma)
+ *stream << ",\n";
+}
+
+void JsonUnitTestResultPrinter::OutputJsonKey(
+ std::ostream* stream,
+ const std::string& element_name,
+ const std::string& name,
+ int value,
+ const std::string& indent,
+ bool comma) {
+ const std::vector<std::string>& allowed_names =
+ GetReservedOutputAttributesForElement(element_name);
+
+ GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) !=
+ allowed_names.end())
+ << "Key \"" << name << "\" is not allowed for value \"" << element_name
+ << "\".";
+
+ *stream << indent << "\"" << name << "\": " << StreamableToString(value);
+ if (comma)
+ *stream << ",\n";
+}
+
+// Prints a JSON representation of a TestInfo object.
+void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
+ const char* test_suite_name,
+ const TestInfo& test_info) {
+ const TestResult& result = *test_info.result();
+ const std::string kTestsuite = "testcase";
+ const std::string kIndent = Indent(10);
+
+ *stream << Indent(8) << "{\n";
+ OutputJsonKey(stream, kTestsuite, "name", test_info.name(), kIndent);
+
+ if (test_info.value_param() != nullptr) {
+ OutputJsonKey(stream, kTestsuite, "value_param", test_info.value_param(),
+ kIndent);
+ }
+ if (test_info.type_param() != nullptr) {
+ OutputJsonKey(stream, kTestsuite, "type_param", test_info.type_param(),
+ kIndent);
+ }
+ if (GTEST_FLAG(list_tests)) {
+ OutputJsonKey(stream, kTestsuite, "file", test_info.file(), kIndent);
+ OutputJsonKey(stream, kTestsuite, "line", test_info.line(), kIndent, false);
+ *stream << "\n" << Indent(8) << "}";
+ return;
+ }
+
+ OutputJsonKey(stream, kTestsuite, "status",
+ test_info.should_run() ? "RUN" : "NOTRUN", kIndent);
+ OutputJsonKey(stream, kTestsuite, "result",
+ test_info.should_run()
+ ? (result.Skipped() ? "SKIPPED" : "COMPLETED")
+ : "SUPPRESSED",
+ kIndent);
+ OutputJsonKey(stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()),
+ kIndent);
+ OutputJsonKey(stream, kTestsuite, "time",
+ FormatTimeInMillisAsDuration(result.elapsed_time()), kIndent);
+ OutputJsonKey(stream, kTestsuite, "classname", test_suite_name, kIndent,
+ false);
+ *stream << TestPropertiesAsJson(result, kIndent);
+
+ int failures = 0;
+ for (int i = 0; i < result.total_part_count(); ++i) {
+ const TestPartResult& part = result.GetTestPartResult(i);
+ if (part.failed()) {
+ *stream << ",\n";
+ if (++failures == 1) {
+ *stream << kIndent << "\"" << "failures" << "\": [\n";
+ }
+ const std::string location =
+ internal::FormatCompilerIndependentFileLocation(part.file_name(),
+ part.line_number());
+ const std::string message = EscapeJson(location + "\n" + part.message());
+ *stream << kIndent << " {\n"
+ << kIndent << " \"failure\": \"" << message << "\",\n"
+ << kIndent << " \"type\": \"\"\n"
+ << kIndent << " }";
+ }
+ }
+
+ if (failures > 0)
+ *stream << "\n" << kIndent << "]";
+ *stream << "\n" << Indent(8) << "}";
+}
+
+// Prints an JSON representation of a TestSuite object
+void JsonUnitTestResultPrinter::PrintJsonTestSuite(
+ std::ostream* stream, const TestSuite& test_suite) {
+ const std::string kTestsuite = "testsuite";
+ const std::string kIndent = Indent(6);
+
+ *stream << Indent(4) << "{\n";
+ OutputJsonKey(stream, kTestsuite, "name", test_suite.name(), kIndent);
+ OutputJsonKey(stream, kTestsuite, "tests", test_suite.reportable_test_count(),
+ kIndent);
+ if (!GTEST_FLAG(list_tests)) {
+ OutputJsonKey(stream, kTestsuite, "failures",
+ test_suite.failed_test_count(), kIndent);
+ OutputJsonKey(stream, kTestsuite, "disabled",
+ test_suite.reportable_disabled_test_count(), kIndent);
+ OutputJsonKey(stream, kTestsuite, "errors", 0, kIndent);
+ OutputJsonKey(
+ stream, kTestsuite, "timestamp",
+ FormatEpochTimeInMillisAsRFC3339(test_suite.start_timestamp()),
+ kIndent);
+ OutputJsonKey(stream, kTestsuite, "time",
+ FormatTimeInMillisAsDuration(test_suite.elapsed_time()),
+ kIndent, false);
+ *stream << TestPropertiesAsJson(test_suite.ad_hoc_test_result(), kIndent)
+ << ",\n";
+ }
+
+ *stream << kIndent << "\"" << kTestsuite << "\": [\n";
+
+ bool comma = false;
+ for (int i = 0; i < test_suite.total_test_count(); ++i) {
+ if (test_suite.GetTestInfo(i)->is_reportable()) {
+ if (comma) {
+ *stream << ",\n";
+ } else {
+ comma = true;
+ }
+ OutputJsonTestInfo(stream, test_suite.name(), *test_suite.GetTestInfo(i));
+ }
+ }
+ *stream << "\n" << kIndent << "]\n" << Indent(4) << "}";
+}
+
+// Prints a JSON summary of unit_test to output stream out.
+void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
+ const UnitTest& unit_test) {
+ const std::string kTestsuites = "testsuites";
+ const std::string kIndent = Indent(2);
+ *stream << "{\n";
+
+ OutputJsonKey(stream, kTestsuites, "tests", unit_test.reportable_test_count(),
+ kIndent);
+ OutputJsonKey(stream, kTestsuites, "failures", unit_test.failed_test_count(),
+ kIndent);
+ OutputJsonKey(stream, kTestsuites, "disabled",
+ unit_test.reportable_disabled_test_count(), kIndent);
+ OutputJsonKey(stream, kTestsuites, "errors", 0, kIndent);
+ if (GTEST_FLAG(shuffle)) {
+ OutputJsonKey(stream, kTestsuites, "random_seed", unit_test.random_seed(),
+ kIndent);
+ }
+ OutputJsonKey(stream, kTestsuites, "timestamp",
+ FormatEpochTimeInMillisAsRFC3339(unit_test.start_timestamp()),
+ kIndent);
+ OutputJsonKey(stream, kTestsuites, "time",
+ FormatTimeInMillisAsDuration(unit_test.elapsed_time()), kIndent,
+ false);
+
+ *stream << TestPropertiesAsJson(unit_test.ad_hoc_test_result(), kIndent)
+ << ",\n";
+
+ OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
+ *stream << kIndent << "\"" << kTestsuites << "\": [\n";
+
+ bool comma = false;
+ for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
+ if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) {
+ if (comma) {
+ *stream << ",\n";
+ } else {
+ comma = true;
+ }
+ PrintJsonTestSuite(stream, *unit_test.GetTestSuite(i));
+ }
+ }
+
+ *stream << "\n" << kIndent << "]\n" << "}\n";
+}
+
+void JsonUnitTestResultPrinter::PrintJsonTestList(
+ std::ostream* stream, const std::vector<TestSuite*>& test_suites) {
+ const std::string kTestsuites = "testsuites";
+ const std::string kIndent = Indent(2);
+ *stream << "{\n";
+ int total_tests = 0;
+ for (auto test_suite : test_suites) {
+ total_tests += test_suite->total_test_count();
+ }
+ OutputJsonKey(stream, kTestsuites, "tests", total_tests, kIndent);
+
+ OutputJsonKey(stream, kTestsuites, "name", "AllTests", kIndent);
+ *stream << kIndent << "\"" << kTestsuites << "\": [\n";
+
+ for (size_t i = 0; i < test_suites.size(); ++i) {
+ if (i != 0) {
+ *stream << ",\n";
+ }
+ PrintJsonTestSuite(stream, *test_suites[i]);
+ }
+
+ *stream << "\n"
+ << kIndent << "]\n"
+ << "}\n";
+}
+// Produces a string representing the test properties in a result as
+// a JSON dictionary.
+std::string JsonUnitTestResultPrinter::TestPropertiesAsJson(
+ const TestResult& result, const std::string& indent) {
+ Message attributes;
+ for (int i = 0; i < result.test_property_count(); ++i) {
+ const TestProperty& property = result.GetTestProperty(i);
+ attributes << ",\n" << indent << "\"" << property.key() << "\": "
+ << "\"" << EscapeJson(property.value()) << "\"";
+ }
+ return attributes.GetString();
+}
+
+// End JsonUnitTestResultPrinter
+
#if GTEST_CAN_STREAM_RESULTS_
// Checks if str contains '=', '&', '%' or '\n' characters. If yes,
@@ -3758,8 +4359,8 @@
// example, replaces "=" with "%3D". This algorithm is O(strlen(str))
// in both time and space -- important as the input str may contain an
// arbitrarily long test failure message and stack trace.
-string StreamingListener::UrlEncode(const char* str) {
- string result;
+std::string StreamingListener::UrlEncode(const char* str) {
+ std::string result;
result.reserve(strlen(str) + 1);
for (char ch = *str; ch != '\0'; ch = *++str) {
switch (ch) {
@@ -3785,7 +4386,7 @@
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses.
hints.ai_socktype = SOCK_STREAM;
- addrinfo* servinfo = NULL;
+ addrinfo* servinfo = nullptr;
// Use the getaddrinfo() to get a linked list of IP addresses for
// the given host name.
@@ -3797,7 +4398,7 @@
}
// Loop through all the results and connect to the first we can.
- for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL;
+ for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != nullptr;
cur_addr = cur_addr->ai_next) {
sockfd_ = socket(
cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol);
@@ -3821,47 +4422,82 @@
// End of class Streaming Listener
#endif // GTEST_CAN_STREAM_RESULTS__
-// Class ScopedTrace
-
-// Pushes the given source file location and message onto a per-thread
-// trace stack maintained by Google Test.
-ScopedTrace::ScopedTrace(const char* file, int line, const Message& message)
- GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
- TraceInfo trace;
- trace.file = file;
- trace.line = line;
- trace.message = message.GetString();
-
- UnitTest::GetInstance()->PushGTestTrace(trace);
-}
-
-// Pops the info pushed by the c'tor.
-ScopedTrace::~ScopedTrace()
- GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
- UnitTest::GetInstance()->PopGTestTrace();
-}
-
-
// class OsStackTraceGetter
const char* const OsStackTraceGetterInterface::kElidedFramesMarker =
"... " GTEST_NAME_ " internal frames ...";
-string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/,
- int /*skip_count*/) {
+std::string OsStackTraceGetter::CurrentStackTrace(int max_depth, int skip_count)
+ GTEST_LOCK_EXCLUDED_(mutex_) {
+#if GTEST_HAS_ABSL
+ std::string result;
+
+ if (max_depth <= 0) {
+ return result;
+ }
+
+ max_depth = std::min(max_depth, kMaxStackTraceDepth);
+
+ std::vector<void*> raw_stack(max_depth);
+ // Skips the frames requested by the caller, plus this function.
+ const int raw_stack_size =
+ absl::GetStackTrace(&raw_stack[0], max_depth, skip_count + 1);
+
+ void* caller_frame = nullptr;
+ {
+ MutexLock lock(&mutex_);
+ caller_frame = caller_frame_;
+ }
+
+ for (int i = 0; i < raw_stack_size; ++i) {
+ if (raw_stack[i] == caller_frame &&
+ !GTEST_FLAG(show_internal_stack_frames)) {
+ // Add a marker to the trace and stop adding frames.
+ absl::StrAppend(&result, kElidedFramesMarker, "\n");
+ break;
+ }
+
+ char tmp[1024];
+ const char* symbol = "(unknown)";
+ if (absl::Symbolize(raw_stack[i], tmp, sizeof(tmp))) {
+ symbol = tmp;
+ }
+
+ char line[1024];
+ snprintf(line, sizeof(line), " %p: %s\n", raw_stack[i], symbol);
+ result += line;
+ }
+
+ return result;
+
+#else // !GTEST_HAS_ABSL
+ static_cast<void>(max_depth);
+ static_cast<void>(skip_count);
return "";
+#endif // GTEST_HAS_ABSL
}
-void OsStackTraceGetter::UponLeavingGTest() {}
+void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) {
+#if GTEST_HAS_ABSL
+ void* caller_frame = nullptr;
+ if (absl::GetStackTrace(&caller_frame, 1, 3) <= 0) {
+ caller_frame = nullptr;
+ }
+
+ MutexLock lock(&mutex_);
+ caller_frame_ = caller_frame;
+#endif // GTEST_HAS_ABSL
+}
// A helper class that creates the premature-exit file in its
// constructor and deletes the file in its destructor.
class ScopedPrematureExitFile {
public:
explicit ScopedPrematureExitFile(const char* premature_exit_filepath)
- : premature_exit_filepath_(premature_exit_filepath) {
+ : premature_exit_filepath_(premature_exit_filepath ?
+ premature_exit_filepath : "") {
// If a path to the premature-exit file is specified...
- if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') {
+ if (!premature_exit_filepath_.empty()) {
// create the file with a single "0" character in it. I/O
// errors are ignored as there's nothing better we can do and we
// don't want to fail the test because of this.
@@ -3872,13 +4508,18 @@
}
~ScopedPrematureExitFile() {
- if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') {
- remove(premature_exit_filepath_);
+ if (!premature_exit_filepath_.empty()) {
+ int retval = remove(premature_exit_filepath_.c_str());
+ if (retval) {
+ GTEST_LOG_(ERROR) << "Failed to remove premature exit filepath \""
+ << premature_exit_filepath_ << "\" with error "
+ << retval;
+ }
}
}
private:
- const char* const premature_exit_filepath_;
+ const std::string premature_exit_filepath_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile);
};
@@ -3889,9 +4530,8 @@
TestEventListeners::TestEventListeners()
: repeater_(new internal::TestEventRepeater()),
- default_result_printer_(NULL),
- default_xml_generator_(NULL) {
-}
+ default_result_printer_(nullptr),
+ default_xml_generator_(nullptr) {}
TestEventListeners::~TestEventListeners() { delete repeater_; }
@@ -3908,9 +4548,9 @@
// NULL if the listener is not found in the list.
TestEventListener* TestEventListeners::Release(TestEventListener* listener) {
if (listener == default_result_printer_)
- default_result_printer_ = NULL;
+ default_result_printer_ = nullptr;
else if (listener == default_xml_generator_)
- default_xml_generator_ = NULL;
+ default_xml_generator_ = nullptr;
return repeater_->Release(listener);
}
@@ -3929,8 +4569,7 @@
// list.
delete Release(default_result_printer_);
default_result_printer_ = listener;
- if (listener != NULL)
- Append(listener);
+ if (listener != nullptr) Append(listener);
}
}
@@ -3945,8 +4584,7 @@
// list.
delete Release(default_xml_generator_);
default_xml_generator_ = listener;
- if (listener != NULL)
- Append(listener);
+ if (listener != nullptr) Append(listener);
}
}
@@ -3970,52 +4608,66 @@
// call this before main() starts, from which point on the return
// value will never change.
UnitTest* UnitTest::GetInstance() {
- // When compiled with MSVC 7.1 in optimized mode, destroying the
- // UnitTest object upon exiting the program messes up the exit code,
- // causing successful tests to appear failed. We have to use a
- // different implementation in this case to bypass the compiler bug.
- // This implementation makes the compiler happy, at the cost of
- // leaking the UnitTest object.
-
// CodeGear C++Builder insists on a public destructor for the
// default implementation. Use this implementation to keep good OO
// design with private destructor.
-#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+#if defined(__BORLANDC__)
static UnitTest* const instance = new UnitTest;
return instance;
#else
static UnitTest instance;
return &instance;
-#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__)
+#endif // defined(__BORLANDC__)
}
-// Gets the number of successful test cases.
-int UnitTest::successful_test_case_count() const {
- return impl()->successful_test_case_count();
+// Gets the number of successful test suites.
+int UnitTest::successful_test_suite_count() const {
+ return impl()->successful_test_suite_count();
}
-// Gets the number of failed test cases.
-int UnitTest::failed_test_case_count() const {
- return impl()->failed_test_case_count();
+// Gets the number of failed test suites.
+int UnitTest::failed_test_suite_count() const {
+ return impl()->failed_test_suite_count();
}
-// Gets the number of all test cases.
-int UnitTest::total_test_case_count() const {
- return impl()->total_test_case_count();
+// Gets the number of all test suites.
+int UnitTest::total_test_suite_count() const {
+ return impl()->total_test_suite_count();
}
-// Gets the number of all test cases that contain at least one test
+// Gets the number of all test suites that contain at least one test
// that should run.
-int UnitTest::test_case_to_run_count() const {
- return impl()->test_case_to_run_count();
+int UnitTest::test_suite_to_run_count() const {
+ return impl()->test_suite_to_run_count();
}
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+int UnitTest::successful_test_case_count() const {
+ return impl()->successful_test_suite_count();
+}
+int UnitTest::failed_test_case_count() const {
+ return impl()->failed_test_suite_count();
+}
+int UnitTest::total_test_case_count() const {
+ return impl()->total_test_suite_count();
+}
+int UnitTest::test_case_to_run_count() const {
+ return impl()->test_suite_to_run_count();
+}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
+
// Gets the number of successful tests.
int UnitTest::successful_test_count() const {
return impl()->successful_test_count();
}
+// Gets the number of skipped tests.
+int UnitTest::skipped_test_count() const {
+ return impl()->skipped_test_count();
+}
+
// Gets the number of failed tests.
int UnitTest::failed_test_count() const { return impl()->failed_test_count(); }
@@ -4051,29 +4703,37 @@
return impl()->elapsed_time();
}
-// Returns true iff the unit test passed (i.e. all test cases passed).
+// Returns true if and only if the unit test passed (i.e. all test suites
+// passed).
bool UnitTest::Passed() const { return impl()->Passed(); }
-// Returns true iff the unit test failed (i.e. some test case failed
-// or something outside of all tests failed).
+// Returns true if and only if the unit test failed (i.e. some test suite
+// failed or something outside of all tests failed).
bool UnitTest::Failed() const { return impl()->Failed(); }
-// Gets the i-th test case among all the test cases. i can range from 0 to
-// total_test_case_count() - 1. If i is not in that range, returns NULL.
+// Gets the i-th test suite among all the test suites. i can range from 0 to
+// total_test_suite_count() - 1. If i is not in that range, returns NULL.
+const TestSuite* UnitTest::GetTestSuite(int i) const {
+ return impl()->GetTestSuite(i);
+}
+
+// Legacy API is deprecated but still available
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
const TestCase* UnitTest::GetTestCase(int i) const {
return impl()->GetTestCase(i);
}
+#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
// Returns the TestResult containing information on test failures and
-// properties logged outside of individual test cases.
+// properties logged outside of individual test suites.
const TestResult& UnitTest::ad_hoc_test_result() const {
return *impl()->ad_hoc_test_result();
}
-// Gets the i-th test case among all the test cases. i can range from 0 to
-// total_test_case_count() - 1. If i is not in that range, returns NULL.
-TestCase* UnitTest::GetMutableTestCase(int i) {
- return impl()->GetMutableTestCase(i);
+// Gets the i-th test suite among all the test suites. i can range from 0 to
+// total_test_suite_count() - 1. If i is not in that range, returns NULL.
+TestSuite* UnitTest::GetMutableTestSuite(int i) {
+ return impl()->GetMutableSuiteCase(i);
}
// Returns the list of event listeners that can be used to track events
@@ -4093,8 +4753,8 @@
// We don't protect this under mutex_, as we only support calling it
// from the main thread.
Environment* UnitTest::AddEnvironment(Environment* env) {
- if (env == NULL) {
- return NULL;
+ if (env == nullptr) {
+ return nullptr;
}
impl_->environments().push_back(env);
@@ -4118,25 +4778,24 @@
if (impl_->gtest_trace_stack().size() > 0) {
msg << "\n" << GTEST_NAME_ << " trace:";
- for (int i = static_cast<int>(impl_->gtest_trace_stack().size());
- i > 0; --i) {
+ for (size_t i = impl_->gtest_trace_stack().size(); i > 0; --i) {
const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1];
msg << "\n" << internal::FormatFileLocation(trace.file, trace.line)
<< " " << trace.message;
}
}
- if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) {
+ if (os_stack_trace.c_str() != nullptr && !os_stack_trace.empty()) {
msg << internal::kStackTraceMarker << os_stack_trace;
}
- const TestPartResult result =
- TestPartResult(result_type, file_name, line_number,
- msg.GetString().c_str());
+ const TestPartResult result = TestPartResult(
+ result_type, file_name, line_number, msg.GetString().c_str());
impl_->GetTestPartResultReporterForCurrentThread()->
ReportTestPartResult(result);
- if (result_type != TestPartResult::kSuccess) {
+ if (result_type != TestPartResult::kSuccess &&
+ result_type != TestPartResult::kSkip) {
// gtest_break_on_failure takes precedence over
// gtest_throw_on_failure. This allows a user to set the latter
// in the code (perhaps in order to use Google Test assertions
@@ -4148,12 +4807,16 @@
// when a failure happens and both the --gtest_break_on_failure and
// the --gtest_catch_exceptions flags are specified.
DebugBreak();
+#elif (!defined(__native_client__)) && \
+ ((defined(__clang__) || defined(__GNUC__)) && \
+ (defined(__x86_64__) || defined(__i386__)))
+ // with clang/gcc we can achieve the same effect on x86 by invoking int3
+ asm("int3");
#else
- // Dereference NULL through a volatile pointer to prevent the compiler
+ // Dereference nullptr through a volatile pointer to prevent the compiler
// from removing. We use this rather than abort() or __builtin_trap() for
- // portability: Symbian doesn't implement abort() well, and some debuggers
- // don't correctly trap abort().
- *static_cast<volatile int*>(NULL) = 1;
+ // portability: some debuggers don't correctly trap abort().
+ *static_cast<volatile int*>(nullptr) = 1;
#endif // GTEST_OS_WINDOWS
} else if (GTEST_FLAG(throw_on_failure)) {
#if GTEST_HAS_EXCEPTIONS
@@ -4168,8 +4831,8 @@
}
// Adds a TestProperty to the current TestResult object when invoked from
-// inside a test, to current TestCase's ad_hoc_test_result_ when invoked
-// from SetUpTestCase or TearDownTestCase, or to the global property set
+// inside a test, to current TestSuite's ad_hoc_test_result_ when invoked
+// from SetUpTestSuite or TearDownTestSuite, or to the global property set
// when invoked elsewhere. If the result already contains a property with
// the same key, the value will be updated.
void UnitTest::RecordProperty(const std::string& key,
@@ -4208,14 +4871,15 @@
// that understands the premature-exit-file protocol to report the
// test as having failed.
const internal::ScopedPrematureExitFile premature_exit_file(
- in_death_test_child_process ?
- NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
+ in_death_test_child_process
+ ? nullptr
+ : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE"));
// Captures the value of GTEST_FLAG(catch_exceptions). This value will be
// used for the duration of the program.
impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions));
-#if GTEST_HAS_SEH
+#if GTEST_OS_WINDOWS
// Either the user wants Google Test to catch exceptions thrown by the
// tests or this is executing in the context of death test child
// process. In either case the user does not want to see pop-up dialogs
@@ -4234,25 +4898,29 @@
_set_error_mode(_OUT_TO_STDERR);
# endif
-# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE
+# if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE
// In the debug version, Visual Studio pops up a separate dialog
// offering a choice to debug the aborted program. We need to suppress
// this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement
// executed. Google Test will notify the user of any unexpected
// failure via stderr.
- //
- // VC++ doesn't define _set_abort_behavior() prior to the version 8.0.
- // Users of prior VC versions shall suffer the agony and pain of
- // clicking through the countless debug dialogs.
- // TODO([email protected]): find a way to suppress the abort dialog() in the
- // debug mode when compiled with VC 7.1 or lower.
if (!GTEST_FLAG(break_on_failure))
_set_abort_behavior(
0x0, // Clear the following flags:
_WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump.
# endif
+
+ // In debug mode, the Windows CRT can crash with an assertion over invalid
+ // input (e.g. passing an invalid file descriptor). The default handling
+ // for these assertions is to pop up a dialog and wait for user input.
+ // Instead ask the CRT to dump such assertions to stderr non-interactively.
+ if (!IsDebuggerPresent()) {
+ (void)_CrtSetReportMode(_CRT_ASSERT,
+ _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
+ (void)_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
+ }
}
-#endif // GTEST_HAS_SEH
+#endif // GTEST_OS_WINDOWS
return internal::HandleExceptionsInMethodIfSupported(
impl(),
@@ -4266,13 +4934,22 @@
return impl_->original_working_dir_.c_str();
}
-// Returns the TestCase object for the test that's currently running,
+// Returns the TestSuite object for the test that's currently running,
// or NULL if no test is running.
+const TestSuite* UnitTest::current_test_suite() const
+ GTEST_LOCK_EXCLUDED_(mutex_) {
+ internal::MutexLock lock(&mutex_);
+ return impl_->current_test_suite();
+}
+
+// Legacy API is still available but deprecated
+#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
const TestCase* UnitTest::current_test_case() const
GTEST_LOCK_EXCLUDED_(mutex_) {
internal::MutexLock lock(&mutex_);
- return impl_->current_test_case();
+ return impl_->current_test_suite();
}
+#endif
// Returns the TestInfo object for the test that's currently running,
// or NULL if no test is running.
@@ -4285,15 +4962,12 @@
// Returns the random seed used at the start of the current test run.
int UnitTest::random_seed() const { return impl_->random_seed(); }
-#if GTEST_HAS_PARAM_TEST
-// Returns ParameterizedTestCaseRegistry object used to keep track of
+// Returns ParameterizedTestSuiteRegistry object used to keep track of
// value-parameterized tests and instantiate and register them.
-internal::ParameterizedTestCaseRegistry&
- UnitTest::parameterized_test_registry()
- GTEST_LOCK_EXCLUDED_(mutex_) {
+internal::ParameterizedTestSuiteRegistry&
+UnitTest::parameterized_test_registry() GTEST_LOCK_EXCLUDED_(mutex_) {
return impl_->parameterized_test_registry();
}
-#endif // GTEST_HAS_PARAM_TEST
// Creates an empty UnitTest.
UnitTest::UnitTest() {
@@ -4325,25 +4999,22 @@
UnitTestImpl::UnitTestImpl(UnitTest* parent)
: parent_(parent),
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */)
- default_global_test_part_result_reporter_(this),
+ default_global_test_part_result_reporter_(this),
default_per_thread_test_part_result_reporter_(this),
- GTEST_DISABLE_MSC_WARNINGS_POP_()
- global_test_part_result_repoter_(
+ GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_(
&default_global_test_part_result_reporter_),
per_thread_test_part_result_reporter_(
&default_per_thread_test_part_result_reporter_),
-#if GTEST_HAS_PARAM_TEST
parameterized_test_registry_(),
parameterized_tests_registered_(false),
-#endif // GTEST_HAS_PARAM_TEST
- last_death_test_case_(-1),
- current_test_case_(NULL),
- current_test_info_(NULL),
+ last_death_test_suite_(-1),
+ current_test_suite_(nullptr),
+ current_test_info_(nullptr),
ad_hoc_test_result_(),
- os_stack_trace_getter_(NULL),
+ os_stack_trace_getter_(nullptr),
post_flag_parse_init_performed_(false),
random_seed_(0), // Will be overridden by the flag before first use.
- random_(0), // Will be reseeded before first use.
+ random_(0), // Will be reseeded before first use.
start_timestamp_(0),
elapsed_time_(0),
#if GTEST_HAS_DEATH_TEST
@@ -4355,8 +5026,8 @@
}
UnitTestImpl::~UnitTestImpl() {
- // Deletes every TestCase.
- ForEach(test_cases_, internal::Delete<TestCase>);
+ // Deletes every TestSuite.
+ ForEach(test_suites_, internal::Delete<TestSuite>);
// Deletes every Environment.
ForEach(environments_, internal::Delete<Environment>);
@@ -4365,20 +5036,20 @@
}
// Adds a TestProperty to the current TestResult object when invoked in a
-// context of a test, to current test case's ad_hoc_test_result when invoke
-// from SetUpTestCase/TearDownTestCase, or to the global property set
+// context of a test, to current test suite's ad_hoc_test_result when invoke
+// from SetUpTestSuite/TearDownTestSuite, or to the global property set
// otherwise. If the result already contains a property with the same key,
// the value will be updated.
void UnitTestImpl::RecordProperty(const TestProperty& test_property) {
std::string xml_element;
TestResult* test_result; // TestResult appropriate for property recording.
- if (current_test_info_ != NULL) {
+ if (current_test_info_ != nullptr) {
xml_element = "testcase";
test_result = &(current_test_info_->result_);
- } else if (current_test_case_ != NULL) {
+ } else if (current_test_suite_ != nullptr) {
xml_element = "testsuite";
- test_result = &(current_test_case_->ad_hoc_test_result_);
+ test_result = &(current_test_suite_->ad_hoc_test_result_);
} else {
xml_element = "testsuites";
test_result = &ad_hoc_test_result_;
@@ -4390,7 +5061,7 @@
// Disables event forwarding if the control is currently in a death test
// subprocess. Must not be called before InitGoogleTest.
void UnitTestImpl::SuppressTestEventsIfInSubprocess() {
- if (internal_run_death_test_flag_.get() != NULL)
+ if (internal_run_death_test_flag_.get() != nullptr)
listeners()->SuppressEventForwarding();
}
#endif // GTEST_HAS_DEATH_TEST
@@ -4402,10 +5073,12 @@
if (output_format == "xml") {
listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
+ } else if (output_format == "json") {
+ listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
} else if (output_format != "") {
- printf("WARNING: unrecognized output format \"%s\" ignored.\n",
- output_format.c_str());
- fflush(stdout);
+ GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
+ << output_format << "\" ignored.";
}
}
@@ -4420,9 +5093,8 @@
listeners()->Append(new StreamingListener(target.substr(0, pos),
target.substr(pos+1)));
} else {
- printf("WARNING: unrecognized streaming target \"%s\" ignored.\n",
- target.c_str());
- fflush(stdout);
+ GTEST_LOG_(WARNING) << "unrecognized streaming target \"" << target
+ << "\" ignored.";
}
}
}
@@ -4461,77 +5133,83 @@
// Configures listeners for streaming test results to the specified server.
ConfigureStreamingOutput();
#endif // GTEST_CAN_STREAM_RESULTS_
+
+#if GTEST_HAS_ABSL
+ if (GTEST_FLAG(install_failure_signal_handler)) {
+ absl::FailureSignalHandlerOptions options;
+ absl::InstallFailureSignalHandler(options);
+ }
+#endif // GTEST_HAS_ABSL
}
}
-// A predicate that checks the name of a TestCase against a known
+// A predicate that checks the name of a TestSuite against a known
// value.
//
// This is used for implementation of the UnitTest class only. We put
// it in the anonymous namespace to prevent polluting the outer
// namespace.
//
-// TestCaseNameIs is copyable.
-class TestCaseNameIs {
+// TestSuiteNameIs is copyable.
+class TestSuiteNameIs {
public:
// Constructor.
- explicit TestCaseNameIs(const std::string& name)
- : name_(name) {}
+ explicit TestSuiteNameIs(const std::string& name) : name_(name) {}
- // Returns true iff the name of test_case matches name_.
- bool operator()(const TestCase* test_case) const {
- return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0;
+ // Returns true if and only if the name of test_suite matches name_.
+ bool operator()(const TestSuite* test_suite) const {
+ return test_suite != nullptr &&
+ strcmp(test_suite->name(), name_.c_str()) == 0;
}
private:
std::string name_;
};
-// Finds and returns a TestCase with the given name. If one doesn't
+// Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it. It's the CALLER'S
// RESPONSIBILITY to ensure that this function is only called WHEN THE
// TESTS ARE NOT SHUFFLED.
//
// Arguments:
//
-// test_case_name: name of the test case
-// type_param: the name of the test case's type parameter, or NULL if
-// this is not a typed or a type-parameterized test case.
-// set_up_tc: pointer to the function that sets up the test case
-// tear_down_tc: pointer to the function that tears down the test case
-TestCase* UnitTestImpl::GetTestCase(const char* test_case_name,
- const char* type_param,
- Test::SetUpTestCaseFunc set_up_tc,
- Test::TearDownTestCaseFunc tear_down_tc) {
- // Can we find a TestCase with the given name?
- const std::vector<TestCase*>::const_iterator test_case =
- std::find_if(test_cases_.begin(), test_cases_.end(),
- TestCaseNameIs(test_case_name));
+// test_suite_name: name of the test suite
+// type_param: the name of the test suite's type parameter, or NULL if
+// this is not a typed or a type-parameterized test suite.
+// set_up_tc: pointer to the function that sets up the test suite
+// tear_down_tc: pointer to the function that tears down the test suite
+TestSuite* UnitTestImpl::GetTestSuite(
+ const char* test_suite_name, const char* type_param,
+ internal::SetUpTestSuiteFunc set_up_tc,
+ internal::TearDownTestSuiteFunc tear_down_tc) {
+ // Can we find a TestSuite with the given name?
+ const auto test_suite =
+ std::find_if(test_suites_.rbegin(), test_suites_.rend(),
+ TestSuiteNameIs(test_suite_name));
- if (test_case != test_cases_.end())
- return *test_case;
+ if (test_suite != test_suites_.rend()) return *test_suite;
// No. Let's create one.
- TestCase* const new_test_case =
- new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc);
+ auto* const new_test_suite =
+ new TestSuite(test_suite_name, type_param, set_up_tc, tear_down_tc);
- // Is this a death test case?
- if (internal::UnitTestOptions::MatchesFilter(test_case_name,
- kDeathTestCaseFilter)) {
- // Yes. Inserts the test case after the last death test case
- // defined so far. This only works when the test cases haven't
+ // Is this a death test suite?
+ if (internal::UnitTestOptions::MatchesFilter(test_suite_name,
+ kDeathTestSuiteFilter)) {
+ // Yes. Inserts the test suite after the last death test suite
+ // defined so far. This only works when the test suites haven't
// been shuffled. Otherwise we may end up running a death test
// after a non-death test.
- ++last_death_test_case_;
- test_cases_.insert(test_cases_.begin() + last_death_test_case_,
- new_test_case);
+ ++last_death_test_suite_;
+ test_suites_.insert(test_suites_.begin() + last_death_test_suite_,
+ new_test_suite);
} else {
// No. Appends to the end of the list.
- test_cases_.push_back(new_test_case);
+ test_suites_.push_back(new_test_suite);
}
- test_case_indices_.push_back(static_cast<int>(test_case_indices_.size()));
- return new_test_case;
+ test_suite_indices_.push_back(static_cast<int>(test_suite_indices_.size()));
+ return new_test_suite;
}
// Helpers for setting up / tearing down the given environment. They
@@ -4549,13 +5227,9 @@
// All other functions called from RunAllTests() may safely assume that
// parameterized tests are ready to be counted and run.
bool UnitTestImpl::RunAllTests() {
- // Makes sure InitGoogleTest() was called.
- if (!GTestIsInitialized()) {
- printf("%s",
- "\nThis test program did NOT call ::testing::InitGoogleTest "
- "before calling RUN_ALL_TESTS(). Please fix it.\n");
- return false;
- }
+ // True if and only if Google Test is initialized before RUN_ALL_TESTS() is
+ // called.
+ const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();
// Do not run any test if the --help flag was specified.
if (g_help_flag)
@@ -4570,12 +5244,13 @@
// protocol.
internal::WriteToShardStatusFileIfNeeded();
- // True iff we are in a subprocess for running a thread-safe-style
+ // True if and only if we are in a subprocess for running a thread-safe-style
// death test.
bool in_subprocess_for_death_test = false;
#if GTEST_HAS_DEATH_TEST
- in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL);
+ in_subprocess_for_death_test =
+ (internal_run_death_test_flag_.get() != nullptr);
# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_)
if (in_subprocess_for_death_test) {
GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_();
@@ -4602,7 +5277,7 @@
random_seed_ = GTEST_FLAG(shuffle) ?
GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0;
- // True iff at least one test has failed.
+ // True if and only if at least one test has failed.
bool failed = false;
TestEventListener* repeater = listeners()->repeater();
@@ -4614,17 +5289,17 @@
// when we are inside the subprocess of a death test.
const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat);
// Repeats forever if the repeat count is negative.
- const bool forever = repeat < 0;
- for (int i = 0; forever || i != repeat; i++) {
+ const bool gtest_repeat_forever = repeat < 0;
+ for (int i = 0; gtest_repeat_forever || i != repeat; i++) {
// We want to preserve failures generated by ad-hoc test
// assertions executed before RUN_ALL_TESTS().
ClearNonAdHocTestResult();
const TimeInMillis start = GetTimeInMillis();
- // Shuffles test cases and tests if requested.
+ // Shuffles test suites and tests if requested.
if (has_tests_to_run && GTEST_FLAG(shuffle)) {
- random()->Reseed(random_seed_);
+ random()->Reseed(static_cast<UInt32>(random_seed_));
// This should be done before calling OnTestIterationStart(),
// such that a test event listener can see the actual test order
// in the event.
@@ -4634,19 +5309,33 @@
// Tells the unit test event listeners that the tests are about to start.
repeater->OnTestIterationStart(*parent_, i);
- // Runs each test case if there is at least one test to run.
+ // Runs each test suite if there is at least one test to run.
if (has_tests_to_run) {
// Sets up all environments beforehand.
repeater->OnEnvironmentsSetUpStart(*parent_);
ForEach(environments_, SetUpEnvironment);
repeater->OnEnvironmentsSetUpEnd(*parent_);
- // Runs the tests only if there was no fatal failure during global
- // set-up.
- if (!Test::HasFatalFailure()) {
- for (int test_index = 0; test_index < total_test_case_count();
+ // Runs the tests only if there was no fatal failure or skip triggered
+ // during global set-up.
+ if (Test::IsSkipped()) {
+ // Emit diagnostics when global set-up calls skip, as it will not be
+ // emitted by default.
+ TestResult& test_result =
+ *internal::GetUnitTestImpl()->current_test_result();
+ for (int j = 0; j < test_result.total_part_count(); ++j) {
+ const TestPartResult& test_part_result =
+ test_result.GetTestPartResult(j);
+ if (test_part_result.type() == TestPartResult::kSkip) {
+ const std::string& result = test_part_result.message();
+ printf("%s\n", result.c_str());
+ }
+ }
+ fflush(stdout);
+ } else if (!Test::HasFatalFailure()) {
+ for (int test_index = 0; test_index < total_test_suite_count();
test_index++) {
- GetMutableTestCase(test_index)->Run();
+ GetMutableSuiteCase(test_index)->Run();
}
}
@@ -4683,6 +5372,20 @@
repeater->OnTestProgramEnd(*parent_);
+ if (!gtest_is_initialized_before_run_all_tests) {
+ ColoredPrintf(
+ COLOR_RED,
+ "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
+ "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
+ "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
+ " will start to enforce the valid usage. "
+ "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT
+#if GTEST_FOR_GOOGLE_
+ ColoredPrintf(COLOR_RED,
+ "For more details, see http://wiki/Main/ValidGUnitMain.\n");
+#endif // GTEST_FOR_GOOGLE_
+ }
+
return !failed;
}
@@ -4692,9 +5395,9 @@
// be created, prints an error and exits.
void WriteToShardStatusFileIfNeeded() {
const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile);
- if (test_shard_file != NULL) {
+ if (test_shard_file != nullptr) {
FILE* const file = posix::FOpen(test_shard_file, "w");
- if (file == NULL) {
+ if (file == nullptr) {
ColoredPrintf(COLOR_RED,
"Could not write to the test shard status file \"%s\" "
"specified by the %s environment variable.\n",
@@ -4729,7 +5432,7 @@
<< "Invalid environment variables: you have "
<< kTestShardIndex << " = " << shard_index
<< ", but have left " << kTestTotalShards << " unset.\n";
- ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+ ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) {
@@ -4737,7 +5440,7 @@
<< "Invalid environment variables: you have "
<< kTestTotalShards << " = " << total_shards
<< ", but have left " << kTestShardIndex << " unset.\n";
- ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+ ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) {
@@ -4746,7 +5449,7 @@
<< kTestShardIndex << " < " << kTestTotalShards
<< ", but you have " << kTestShardIndex << "=" << shard_index
<< ", " << kTestTotalShards << "=" << total_shards << ".\n";
- ColoredPrintf(COLOR_RED, msg.GetString().c_str());
+ ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
fflush(stdout);
exit(EXIT_FAILURE);
}
@@ -4759,7 +5462,7 @@
// and aborts.
Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) {
const char* str_val = posix::GetEnv(var);
- if (str_val == NULL) {
+ if (str_val == nullptr) {
return default_val;
}
@@ -4772,8 +5475,8 @@
}
// Given the total number of shards, the shard index, and the test id,
-// returns true iff the test should be run on this shard. The test id is
-// some arbitrary but unique non-negative integer assigned to each test
+// returns true if and only if the test should be run on this shard. The test id
+// is some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards.
bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) {
return (test_id % total_shards) == shard_index;
@@ -4781,11 +5484,11 @@
// Compares the name of each test with the user-specified filter to
// decide whether the test should be run, then records the result in
-// each TestCase and TestInfo object.
+// each TestSuite and TestInfo object.
// If shard_tests == true, further filters tests based on sharding
// variables in the environment - see
-// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide.
-// Returns the number of tests that should run.
+// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md
+// . Returns the number of tests that should run.
int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) {
const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ?
Int32FromEnvOrDie(kTestTotalShards, -1) : -1;
@@ -4798,42 +5501,40 @@
// this shard.
int num_runnable_tests = 0;
int num_selected_tests = 0;
- for (size_t i = 0; i < test_cases_.size(); i++) {
- TestCase* const test_case = test_cases_[i];
- const std::string &test_case_name = test_case->name();
- test_case->set_should_run(false);
+ for (auto* test_suite : test_suites_) {
+ const std::string& test_suite_name = test_suite->name();
+ test_suite->set_should_run(false);
- for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
- TestInfo* const test_info = test_case->test_info_list()[j];
+ for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
+ TestInfo* const test_info = test_suite->test_info_list()[j];
const std::string test_name(test_info->name());
- // A test is disabled if test case name or test name matches
+ // A test is disabled if test suite name or test name matches
// kDisableTestFilter.
- const bool is_disabled =
- internal::UnitTestOptions::MatchesFilter(test_case_name,
- kDisableTestFilter) ||
- internal::UnitTestOptions::MatchesFilter(test_name,
- kDisableTestFilter);
+ const bool is_disabled = internal::UnitTestOptions::MatchesFilter(
+ test_suite_name, kDisableTestFilter) ||
+ internal::UnitTestOptions::MatchesFilter(
+ test_name, kDisableTestFilter);
test_info->is_disabled_ = is_disabled;
- const bool matches_filter =
- internal::UnitTestOptions::FilterMatchesTest(test_case_name,
- test_name);
+ const bool matches_filter = internal::UnitTestOptions::FilterMatchesTest(
+ test_suite_name, test_name);
test_info->matches_filter_ = matches_filter;
const bool is_runnable =
(GTEST_FLAG(also_run_disabled_tests) || !is_disabled) &&
matches_filter;
- const bool is_selected = is_runnable &&
- (shard_tests == IGNORE_SHARDING_PROTOCOL ||
- ShouldRunTestOnShard(total_shards, shard_index,
- num_runnable_tests));
+ const bool is_in_another_shard =
+ shard_tests != IGNORE_SHARDING_PROTOCOL &&
+ !ShouldRunTestOnShard(total_shards, shard_index, num_runnable_tests);
+ test_info->is_in_another_shard_ = is_in_another_shard;
+ const bool is_selected = is_runnable && !is_in_another_shard;
num_runnable_tests += is_runnable;
num_selected_tests += is_selected;
test_info->should_run_ = is_selected;
- test_case->set_should_run(test_case->should_run() || is_selected);
+ test_suite->set_should_run(test_suite->should_run() || is_selected);
}
}
return num_selected_tests;
@@ -4844,7 +5545,7 @@
// max_length characters, only prints the first max_length characters
// and "...".
static void PrintOnOneLine(const char* str, int max_length) {
- if (str != NULL) {
+ if (str != nullptr) {
for (int i = 0; *str != '\0'; ++str) {
if (i >= max_length) {
printf("...");
@@ -4866,27 +5567,25 @@
// Print at most this many characters for each type/value parameter.
const int kMaxParamLength = 250;
- for (size_t i = 0; i < test_cases_.size(); i++) {
- const TestCase* const test_case = test_cases_[i];
- bool printed_test_case_name = false;
+ for (auto* test_suite : test_suites_) {
+ bool printed_test_suite_name = false;
- for (size_t j = 0; j < test_case->test_info_list().size(); j++) {
- const TestInfo* const test_info =
- test_case->test_info_list()[j];
+ for (size_t j = 0; j < test_suite->test_info_list().size(); j++) {
+ const TestInfo* const test_info = test_suite->test_info_list()[j];
if (test_info->matches_filter_) {
- if (!printed_test_case_name) {
- printed_test_case_name = true;
- printf("%s.", test_case->name());
- if (test_case->type_param() != NULL) {
+ if (!printed_test_suite_name) {
+ printed_test_suite_name = true;
+ printf("%s.", test_suite->name());
+ if (test_suite->type_param() != nullptr) {
printf(" # %s = ", kTypeParamLabel);
// We print the type parameter on a single line to make
// the output easy to parse by a program.
- PrintOnOneLine(test_case->type_param(), kMaxParamLength);
+ PrintOnOneLine(test_suite->type_param(), kMaxParamLength);
}
printf("\n");
}
printf(" %s", test_info->name());
- if (test_info->value_param() != NULL) {
+ if (test_info->value_param() != nullptr) {
printf(" # %s = ", kValueParamLabel);
// We print the value parameter on a single line to make the
// output easy to parse by a program.
@@ -4897,6 +5596,23 @@
}
}
fflush(stdout);
+ const std::string& output_format = UnitTestOptions::GetOutputFormat();
+ if (output_format == "xml" || output_format == "json") {
+ FILE* fileout = OpenFileForWriting(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str());
+ std::stringstream stream;
+ if (output_format == "xml") {
+ XmlUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str())
+ .PrintXmlTestsList(&stream, test_suites_);
+ } else if (output_format == "json") {
+ JsonUnitTestResultPrinter(
+ UnitTestOptions::GetAbsolutePathToOutputFile().c_str())
+ .PrintJsonTestList(&stream, test_suites_);
+ }
+ fprintf(fileout, "%s", StringStreamToString(&stream).c_str());
+ fclose(fileout);
+ }
}
// Sets the OS stack trace getter.
@@ -4916,7 +5632,7 @@
// otherwise, creates an OsStackTraceGetter, makes it the current
// getter, and returns it.
OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() {
- if (os_stack_trace_getter_ == NULL) {
+ if (os_stack_trace_getter_ == nullptr) {
#ifdef GTEST_OS_STACK_TRACE_GETTER_
os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_;
#else
@@ -4927,36 +5643,40 @@
return os_stack_trace_getter_;
}
-// Returns the TestResult for the test that's currently running, or
-// the TestResult for the ad hoc test if no test is running.
+// Returns the most specific TestResult currently running.
TestResult* UnitTestImpl::current_test_result() {
- return current_test_info_ ?
- &(current_test_info_->result_) : &ad_hoc_test_result_;
+ if (current_test_info_ != nullptr) {
+ return ¤t_test_info_->result_;
+ }
+ if (current_test_suite_ != nullptr) {
+ return ¤t_test_suite_->ad_hoc_test_result_;
+ }
+ return &ad_hoc_test_result_;
}
-// Shuffles all test cases, and the tests within each test case,
+// Shuffles all test suites, and the tests within each test suite,
// making sure that death tests are still run first.
void UnitTestImpl::ShuffleTests() {
- // Shuffles the death test cases.
- ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_);
+ // Shuffles the death test suites.
+ ShuffleRange(random(), 0, last_death_test_suite_ + 1, &test_suite_indices_);
- // Shuffles the non-death test cases.
- ShuffleRange(random(), last_death_test_case_ + 1,
- static_cast<int>(test_cases_.size()), &test_case_indices_);
+ // Shuffles the non-death test suites.
+ ShuffleRange(random(), last_death_test_suite_ + 1,
+ static_cast<int>(test_suites_.size()), &test_suite_indices_);
- // Shuffles the tests inside each test case.
- for (size_t i = 0; i < test_cases_.size(); i++) {
- test_cases_[i]->ShuffleTests(random());
+ // Shuffles the tests inside each test suite.
+ for (auto& test_suite : test_suites_) {
+ test_suite->ShuffleTests(random());
}
}
-// Restores the test cases and tests to their order before the first shuffle.
+// Restores the test suites and tests to their order before the first shuffle.
void UnitTestImpl::UnshuffleTests() {
- for (size_t i = 0; i < test_cases_.size(); i++) {
- // Unshuffles the tests in each test case.
- test_cases_[i]->UnshuffleTests();
- // Resets the index of each test case.
- test_case_indices_[i] = static_cast<int>(i);
+ for (size_t i = 0; i < test_suites_.size(); i++) {
+ // Unshuffles the tests in each test suite.
+ test_suites_[i]->UnshuffleTests();
+ // Resets the index of each test suite.
+ test_suite_indices_[i] = static_cast<int>(i);
}
}
@@ -5012,16 +5732,15 @@
// part can be omitted.
//
// Returns the value of the flag, or NULL if the parsing failed.
-const char* ParseFlagValue(const char* str,
- const char* flag,
- bool def_optional) {
+static const char* ParseFlagValue(const char* str, const char* flag,
+ bool def_optional) {
// str and flag must not be NULL.
- if (str == NULL || flag == NULL) return NULL;
+ if (str == nullptr || flag == nullptr) return nullptr;
// The flag must start with "--" followed by GTEST_FLAG_PREFIX_.
const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag;
const size_t flag_len = flag_str.length();
- if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL;
+ if (strncmp(str, flag_str.c_str(), flag_len) != 0) return nullptr;
// Skips the flag name.
const char* flag_end = str + flag_len;
@@ -5034,7 +5753,7 @@
// If def_optional is true and there are more characters after the
// flag name, or if def_optional is false, there must be a '=' after
// the flag name.
- if (flag_end[0] != '=') return NULL;
+ if (flag_end[0] != '=') return nullptr;
// Returns the string after "=".
return flag_end + 1;
@@ -5050,12 +5769,12 @@
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
-bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
+static bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseFlagValue(str, flag, true);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Converts the string value to a bool.
*value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F');
@@ -5072,7 +5791,7 @@
const char* const value_str = ParseFlagValue(str, flag, false);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
return ParseInt32(Message() << "The value of flag --" << flag,
@@ -5084,12 +5803,13 @@
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
-bool ParseStringFlag(const char* str, const char* flag, std::string* value) {
+template <typename String>
+static bool ParseStringFlag(const char* str, const char* flag, String* value) {
// Gets the value of the flag as a string.
const char* const value_str = ParseFlagValue(str, flag, false);
// Aborts if the parsing failed.
- if (value_str == NULL) return false;
+ if (value_str == nullptr) return false;
// Sets *value to the value of the flag.
*value = value_str;
@@ -5120,8 +5840,6 @@
// @Y changes the color to yellow.
// @D changes to the default terminal text color.
//
-// TODO([email protected]): Write tests for this once we add stdout
-// capturing to Google Test.
static void PrintColorEncoded(const char* str) {
GTestColor color = COLOR_DEFAULT; // The current color.
@@ -5131,7 +5849,7 @@
// next segment.
for (;;) {
const char* p = strchr(str, '@');
- if (p == NULL) {
+ if (p == nullptr) {
ColoredPrintf(color, "%s", str);
return;
}
@@ -5186,24 +5904,25 @@
" Enable/disable colored output. The default is @Gauto@D.\n"
" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n"
" Don't print the elapsed time of each test.\n"
-" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G"
+" @G--" GTEST_FLAG_PREFIX_ "output=@Y(@Gjson@Y|@Gxml@Y)[@G:@YDIRECTORY_PATH@G"
GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n"
-" Generate an XML report in the given directory or with the given file\n"
-" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n"
-#if GTEST_CAN_STREAM_RESULTS_
+" Generate a JSON or XML report in the given directory or with the given\n"
+" file name. @YFILE_PATH@D defaults to @Gtest_detail.xml@D.\n"
+# if GTEST_CAN_STREAM_RESULTS_
" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n"
" Stream test results to the given server.\n"
-#endif // GTEST_CAN_STREAM_RESULTS_
+# endif // GTEST_CAN_STREAM_RESULTS_
"\n"
"Assertion Behavior:\n"
-#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+# if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n"
" Set the default death test style.\n"
-#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
+# endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS
" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n"
" Turn assertion failures into debugger break-points.\n"
" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n"
-" Turn assertion failures into C++ exceptions.\n"
+" Turn assertion failures into C++ exceptions for use by an external\n"
+" test framework.\n"
" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n"
" Do not report exceptions as test failures. Instead, allow them\n"
" to crash the program or throw a pop-up (on Windows).\n"
@@ -5220,7 +5939,7 @@
"(not one in your own code or tests), please report it to\n"
"@G<" GTEST_DEV_EMAIL_ ">@D.\n";
-bool ParseGoogleTestFlag(const char* const arg) {
+static bool ParseGoogleTestFlag(const char* const arg) {
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
>EST_FLAG(also_run_disabled_tests)) ||
ParseBoolFlag(arg, kBreakOnFailureFlag,
@@ -5238,6 +5957,7 @@
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
+ ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) ||
ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) ||
@@ -5250,14 +5970,11 @@
}
#if GTEST_USE_OWN_FLAGFILE_FLAG_
-void LoadFlagsFromFile(const std::string& path) {
+static void LoadFlagsFromFile(const std::string& path) {
FILE* flagfile = posix::FOpen(path.c_str(), "r");
if (!flagfile) {
- fprintf(stderr,
- "Unable to open file \"%s\"\n",
- GTEST_FLAG(flagfile).c_str());
- fflush(stderr);
- exit(EXIT_FAILURE);
+ GTEST_LOG_(FATAL) << "Unable to open file \"" << GTEST_FLAG(flagfile)
+ << "\"";
}
std::string contents(ReadEntireFile(flagfile));
posix::FClose(flagfile);
@@ -5331,6 +6048,17 @@
// other parts of Google Test.
void ParseGoogleTestFlagsOnly(int* argc, char** argv) {
ParseGoogleTestFlagsOnlyImpl(argc, argv);
+
+ // Fix the value of *_NSGetArgc() on macOS, but if and only if
+ // *_NSGetArgv() == argv
+ // Only applicable to char** version of argv
+#if GTEST_OS_MAC
+#ifndef GTEST_OS_IOS
+ if (*_NSGetArgv() == argv) {
+ *_NSGetArgc() = *argc;
+ }
+#endif
+#endif
}
void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) {
ParseGoogleTestFlagsOnlyImpl(argc, argv);
@@ -5352,6 +6080,10 @@
g_argvs.push_back(StreamableToString(argv[i]));
}
+#if GTEST_HAS_ABSL
+ absl::InitializeSymbolizer(g_argvs[0].c_str());
+#endif // GTEST_HAS_ABSL
+
ParseGoogleTestFlagsOnly(argc, argv);
GetUnitTestImpl()->PostFlagParsingInit();
}
@@ -5385,4 +6117,61 @@
#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
}
+// This overloaded version can be used on Arduino/embedded platforms where
+// there is no argc/argv.
+void InitGoogleTest() {
+ // Since Arduino doesn't have a command line, fake out the argc/argv arguments
+ int argc = 1;
+ const auto arg0 = "dummy";
+ char* argv0 = const_cast<char*>(arg0);
+ char** argv = &argv0;
+
+#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
+ GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(&argc, argv);
+#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
+ internal::InitGoogleTestImpl(&argc, argv);
+#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
+}
+
+std::string TempDir() {
+#if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_)
+ return GTEST_CUSTOM_TEMPDIR_FUNCTION_();
+#endif
+
+#if GTEST_OS_WINDOWS_MOBILE
+ return "\\temp\\";
+#elif GTEST_OS_WINDOWS
+ const char* temp_dir = internal::posix::GetEnv("TEMP");
+ if (temp_dir == nullptr || temp_dir[0] == '\0')
+ return "\\temp\\";
+ else if (temp_dir[strlen(temp_dir) - 1] == '\\')
+ return temp_dir;
+ else
+ return std::string(temp_dir) + "\\";
+#elif GTEST_OS_LINUX_ANDROID
+ return "/sdcard/";
+#else
+ return "/tmp/";
+#endif // GTEST_OS_WINDOWS_MOBILE
+}
+
+// Class ScopedTrace
+
+// Pushes the given source file location and message onto a per-thread
+// trace stack maintained by Google Test.
+void ScopedTrace::PushTrace(const char* file, int line, std::string message) {
+ internal::TraceInfo trace;
+ trace.file = file;
+ trace.line = line;
+ trace.message.swap(message);
+
+ UnitTest::GetInstance()->PushGTestTrace(trace);
+}
+
+// Pops the info pushed by the c'tor.
+ScopedTrace::~ScopedTrace()
+ GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) {
+ UnitTest::GetInstance()->PopGTestTrace();
+}
+
} // namespace testing
diff --git a/src/llvm-project/llvm/utils/update_analyze_test_checks.py b/src/llvm-project/llvm/utils/update_analyze_test_checks.py
index 921a3bc..6c5bc52 100755
--- a/src/llvm-project/llvm/utils/update_analyze_test_checks.py
+++ b/src/llvm-project/llvm/utils/update_analyze_test_checks.py
@@ -113,8 +113,10 @@
flags = type('', (object,), {
'verbose': args.verbose,
'function_signature': False,
- 'check_attributes': False}),
- scrubber_args = [])
+ 'check_attributes': False,
+ 'replace_value_regex': []}),
+ scrubber_args = [],
+ path=test)
for prefixes, opt_args in prefix_list:
common.debug('Extracted opt cmd:', opt_basename, opt_args, file=sys.stderr)
diff --git a/src/llvm-project/llvm/utils/update_cc_test_checks.py b/src/llvm-project/llvm/utils/update_cc_test_checks.py
index e5ca915..74c601f 100755
--- a/src/llvm-project/llvm/utils/update_cc_test_checks.py
+++ b/src/llvm-project/llvm/utils/update_cc_test_checks.py
@@ -147,6 +147,8 @@
help='Keep function signature information around for the check line')
parser.add_argument('--check-attributes', action='store_true',
help='Check "Function Attributes" for functions')
+ parser.add_argument('--check-globals', action='store_true',
+ help='Check global entries (global variables, metadata, attribute sets, ...) for functions')
parser.add_argument('tests', nargs='+')
args = common.parse_commandline_args(parser)
infer_dependent_args(args)
@@ -176,7 +178,7 @@
return args, parser
-def get_function_body(builder, args, filename, clang_args, extra_commands,
+def get_function_body(builder, args, filename, clang_args, extra_commands,
prefixes):
# TODO Clean up duplication of asm/common build_function_body_dictionary
# Invoke external tool and extract function bodies.
@@ -203,6 +205,14 @@
'are discouraged in Clang testsuite.', file=sys.stderr)
sys.exit(1)
+def exec_run_line(exe):
+ popen = subprocess.Popen(exe, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
+ stdout, stderr = popen.communicate()
+ if popen.returncode != 0:
+ sys.stderr.write('Failed to run ' + ' '.join(exe) + '\n')
+ sys.stderr.write(stderr)
+ sys.stderr.write(stdout)
+ sys.exit(3)
def main():
initial_args, parser = config()
@@ -210,9 +220,16 @@
for ti in common.itertests(initial_args.tests, parser, 'utils/' + script_name,
comment_prefix='//', argparse_callback=infer_dependent_args):
- # Build a list of clang command lines and check prefixes from RUN lines.
+ # Build a list of filechecked and non-filechecked RUN lines.
run_list = []
line2spell_and_mangled_list = collections.defaultdict(list)
+
+ subs = {
+ '%s' : ti.path,
+ '%t' : tempfile.NamedTemporaryFile().name,
+ '%S' : os.getcwd(),
+ }
+
for l in ti.run_lines:
commands = [cmd.strip() for cmd in l.split('|')]
@@ -221,25 +238,32 @@
if m:
triple_in_cmd = m.groups()[0]
- # Apply %clang substitution rule, replace %s by `filename`, and append args.clang_args
- clang_args = shlex.split(commands[0])
- if clang_args[0] not in SUBST:
- print('WARNING: Skipping non-clang RUN line: ' + l, file=sys.stderr)
+ # Parse executable args.
+ exec_args = shlex.split(commands[0])
+ # Execute non-clang runline.
+ if exec_args[0] not in SUBST:
+ # Do lit-like substitutions.
+ for s in subs:
+ exec_args = [i.replace(s, subs[s]) if s in i else i for i in exec_args]
+ run_list.append((None, exec_args, None, None))
continue
+ # This is a clang runline, apply %clang substitution rule, do lit-like substitutions,
+ # and append args.clang_args
+ clang_args = exec_args
clang_args[0:1] = SUBST[clang_args[0]]
- clang_args = [ti.path if i == '%s' else i for i in clang_args] + ti.args.clang_args
-
- # Permit piping the output through opt
- if not (len(commands) == 2 or
- (len(commands) == 3 and commands[1].startswith('opt'))):
- print('WARNING: Skipping non-clang RUN line: ' + l, file=sys.stderr)
+ for s in subs:
+ clang_args = [i.replace(s, subs[s]) if s in i else i for i in clang_args]
+ clang_args += ti.args.clang_args
# Extract -check-prefix in FileCheck args
filecheck_cmd = commands[-1]
common.verify_filecheck_prefixes(filecheck_cmd)
if not filecheck_cmd.startswith('FileCheck '):
- print('WARNING: Skipping non-FileChecked RUN line: ' + l, file=sys.stderr)
+ # Execute non-filechecked clang runline.
+ exe = [ti.args.clang] + clang_args
+ run_list.append((None, exe, None, None))
continue
+
check_prefixes = [item for m in common.CHECK_PREFIX_RE.finditer(filecheck_cmd)
for item in m.group(1).split(',')]
if not check_prefixes:
@@ -248,16 +272,26 @@
# Execute clang, generate LLVM IR, and extract functions.
+ # Store only filechecked runlines.
+ filecheck_run_list = [i for i in run_list if i[0]]
builder = common.FunctionTestBuilder(
- run_list=run_list,
+ run_list=filecheck_run_list,
flags=ti.args,
- scrubber_args=[])
+ scrubber_args=[],
+ path=ti.path)
- for prefixes, clang_args, extra_commands, triple_in_cmd in run_list:
+ for prefixes, args, extra_commands, triple_in_cmd in run_list:
+ # Execute non-filechecked runline.
+ if not prefixes:
+ print('NOTE: Executing non-FileChecked RUN line: ' + ' '.join(args), file=sys.stderr)
+ exec_run_line(args)
+ continue
+
+ clang_args = args
common.debug('Extracted clang cmd: clang {}'.format(clang_args))
common.debug('Extracted FileCheck prefixes: {}'.format(prefixes))
- get_function_body(builder, ti.args, ti.path, clang_args, extra_commands,
+ get_function_body(builder, ti.args, ti.path, clang_args, extra_commands,
prefixes)
# Invoke clang -Xclang -ast-dump=json to get mapping from start lines to
@@ -267,8 +301,9 @@
func_dict = builder.finish_and_get_func_dict()
global_vars_seen_dict = {}
- prefix_set = set([prefix for p in run_list for prefix in p[0]])
+ prefix_set = set([prefix for p in filecheck_run_list for prefix in p[0]])
output_lines = []
+ has_checked_pre_function_globals = False
include_generated_funcs = common.find_arg_in_test(ti,
lambda args: ti.args.include_generated_funcs,
@@ -301,7 +336,11 @@
prefixes,
func_dict, func)
- common.add_checks_at_end(output_lines, run_list, builder.func_order(),
+ if ti.args.check_globals:
+ common.add_global_checks(builder.global_var_dict(), '//', run_list,
+ output_lines, global_vars_seen_dict, True,
+ True)
+ common.add_checks_at_end(output_lines, filecheck_run_list, builder.func_order(),
'//', lambda my_output_lines, prefixes, func:
check_generator(my_output_lines,
prefixes, func))
@@ -315,6 +354,9 @@
m = common.CHECK_RE.match(line)
if m and m.group(1) in prefix_set:
continue # Don't append the existing CHECK lines
+ # Skip special separator comments added by commmon.add_global_checks.
+ if line.strip() == '//' + common.SEPARATOR:
+ continue
if idx in line2spell_and_mangled_list:
added = set()
for spell, mangled in line2spell_and_mangled_list[idx]:
@@ -332,10 +374,15 @@
# line as part of common.add_ir_checks()
output_lines.pop()
last_line = output_lines[-1].strip()
+ if ti.args.check_globals and not has_checked_pre_function_globals:
+ common.add_global_checks(builder.global_var_dict(), '//',
+ run_list, output_lines,
+ global_vars_seen_dict, True, True)
+ has_checked_pre_function_globals = True
if added:
output_lines.append('//')
added.add(mangled)
- common.add_ir_checks(output_lines, '//', run_list, func_dict, mangled,
+ common.add_ir_checks(output_lines, '//', filecheck_run_list, func_dict, mangled,
False, args.function_signature, global_vars_seen_dict)
if line.rstrip('\n') == '//':
include_line = False
@@ -343,6 +390,9 @@
if include_line:
output_lines.append(line.rstrip('\n'))
+ if ti.args.check_globals:
+ common.add_global_checks(builder.global_var_dict(), '//', run_list,
+ output_lines, global_vars_seen_dict, True, False)
common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))
with open(ti.path, 'wb') as f:
f.writelines(['{}\n'.format(l).encode('utf-8') for l in output_lines])
diff --git a/src/llvm-project/llvm/utils/update_llc_test_checks.py b/src/llvm-project/llvm/utils/update_llc_test_checks.py
index 7cfe85c..7e20a58 100755
--- a/src/llvm-project/llvm/utils/update_llc_test_checks.py
+++ b/src/llvm-project/llvm/utils/update_llc_test_checks.py
@@ -33,7 +33,7 @@
parser.add_argument(
'--no_x86_scrub_sp', action='store_false', dest='x86_scrub_sp')
parser.add_argument(
- '--x86_scrub_rip', action='store_true', default=True,
+ '--x86_scrub_rip', action='store_true', default=False,
help='Use more regex for x86 rip matching to reduce diffs between various subtargets')
parser.add_argument(
'--no_x86_scrub_rip', action='store_false', dest='x86_scrub_rip')
@@ -60,8 +60,13 @@
common.warn('Skipping unparseable RUN line: ' + l)
continue
- commands = [cmd.strip() for cmd in l.split('|', 1)]
- llc_cmd = commands[0]
+ commands = [cmd.strip() for cmd in l.split('|')]
+ assert len(commands) >= 2
+ preprocess_cmd = None
+ if len(commands) > 2:
+ preprocess_cmd = " | ".join(commands[:-2])
+ llc_cmd = commands[-2]
+ filecheck_cmd = commands[-1]
llc_tool = llc_cmd.split(' ')[0]
triple_in_cmd = None
@@ -74,9 +79,6 @@
if m:
march_in_cmd = m.groups()[0]
- filecheck_cmd = ''
- if len(commands) > 1:
- filecheck_cmd = commands[1]
common.verify_filecheck_prefixes(filecheck_cmd)
if llc_tool not in LLC_LIKE_TOOLS:
common.warn('Skipping non-llc RUN line: ' + l)
@@ -97,7 +99,8 @@
# FIXME: We should use multiple check prefixes to common check lines. For
# now, we just ignore all but the last.
- run_list.append((check_prefixes, llc_cmd_args, triple_in_cmd, march_in_cmd))
+ run_list.append((check_prefixes, llc_tool, llc_cmd_args, preprocess_cmd,
+ triple_in_cmd, march_in_cmd))
if ti.path.endswith('.mir'):
check_indent = ' '
@@ -105,19 +108,22 @@
check_indent = ''
builder = common.FunctionTestBuilder(
- run_list=run_list,
+ run_list=run_list,
flags=type('', (object,), {
'verbose': ti.args.verbose,
'function_signature': False,
- 'check_attributes': False}),
- scrubber_args=[ti.args])
+ 'check_attributes': False,
+ 'replace_value_regex': []}),
+ scrubber_args=[ti.args],
+ path=ti.path)
- for prefixes, llc_args, triple_in_cmd, march_in_cmd in run_list:
+ for prefixes, llc_tool, llc_args, preprocess_cmd, triple_in_cmd, march_in_cmd in run_list:
common.debug('Extracted LLC cmd:', llc_tool, llc_args)
common.debug('Extracted FileCheck prefixes:', str(prefixes))
raw_tool_output = common.invoke_tool(ti.args.llc_binary or llc_tool,
- llc_args, ti.path)
+ llc_args, ti.path, preprocess_cmd,
+ verbose=ti.args.verbose)
triple = triple_in_cmd or triple_in_ir
if not triple:
triple = asm.get_triple_from_march(march_in_cmd)
diff --git a/src/llvm-project/llvm/utils/update_test_checks.py b/src/llvm-project/llvm/utils/update_test_checks.py
index 457b61d..9ac95cc 100755
--- a/src/llvm-project/llvm/utils/update_test_checks.py
+++ b/src/llvm-project/llvm/utils/update_test_checks.py
@@ -54,6 +54,8 @@
help='Remove attribute annotations (#0) from the end of check line')
parser.add_argument('--check-attributes', action='store_true',
help='Check "Function Attributes" for functions')
+ parser.add_argument('--check-globals', action='store_true',
+ help='Check global entries (global variables, metadata, attribute sets, ...) for functions')
parser.add_argument('tests', nargs='+')
initial_args = common.parse_commandline_args(parser)
@@ -78,7 +80,13 @@
common.warn('Skipping unparseable RUN line: ' + l)
continue
- (tool_cmd, filecheck_cmd) = tuple([cmd.strip() for cmd in l.split('|', 1)])
+ commands = [cmd.strip() for cmd in l.split('|')]
+ assert len(commands) >= 2
+ preprocess_cmd = None
+ if len(commands) > 2:
+ preprocess_cmd = " | ".join(commands[:-2])
+ tool_cmd = commands[-2]
+ filecheck_cmd = commands[-1]
common.verify_filecheck_prefixes(filecheck_cmd)
if not tool_cmd.startswith(opt_basename + ' '):
common.warn('Skipping non-%s RUN line: %s' % (opt_basename, l))
@@ -99,27 +107,30 @@
# FIXME: We should use multiple check prefixes to common check lines. For
# now, we just ignore all but the last.
- prefix_list.append((check_prefixes, tool_cmd_args))
+ prefix_list.append((check_prefixes, tool_cmd_args, preprocess_cmd))
global_vars_seen_dict = {}
builder = common.FunctionTestBuilder(
run_list=prefix_list,
flags=ti.args,
- scrubber_args=[])
+ scrubber_args=[],
+ path=ti.path)
- for prefixes, opt_args in prefix_list:
+ for prefixes, opt_args, preprocess_cmd in prefix_list:
common.debug('Extracted opt cmd: ' + opt_basename + ' ' + opt_args)
common.debug('Extracted FileCheck prefixes: ' + str(prefixes))
- raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args,
- ti.path)
+ raw_tool_output = common.invoke_tool(ti.args.opt_binary, opt_args,
+ ti.path, preprocess_cmd=preprocess_cmd,
+ verbose=ti.args.verbose)
builder.process_run_line(common.OPT_FUNCTION_RE, common.scrub_body,
raw_tool_output, prefixes)
func_dict = builder.finish_and_get_func_dict()
is_in_function = False
is_in_function_start = False
- prefix_set = set([prefix for prefixes, _ in prefix_list for prefix in prefixes])
+ has_checked_pre_function_globals = False
+ prefix_set = set([prefix for prefixes, _, _ in prefix_list for prefix in prefixes])
common.debug('Rewriting FileCheck prefixes:', str(prefix_set))
output_lines = []
@@ -138,13 +149,17 @@
# out all the source lines.
common.dump_input_lines(output_lines, ti, prefix_set, ';')
+ args = ti.args
+ if args.check_globals:
+ common.add_global_checks(builder.global_var_dict(), ';', prefix_list, output_lines, global_vars_seen_dict, args.preserve_names, True)
+
# Now generate all the checks.
common.add_checks_at_end(output_lines, prefix_list, builder.func_order(),
';', lambda my_output_lines, prefixes, func:
common.add_ir_checks(my_output_lines, ';',
prefixes,
func_dict, func, False,
- ti.args.function_signature,
+ args.function_signature,
global_vars_seen_dict))
else:
# "Normal" mode.
@@ -166,20 +181,23 @@
global_vars_seen_dict)
is_in_function_start = False
- if is_in_function:
- if common.should_add_line_to_output(input_line, prefix_set):
+ m = common.IR_FUNCTION_RE.match(input_line)
+ if m and not has_checked_pre_function_globals:
+ if args.check_globals:
+ common.add_global_checks(builder.global_var_dict(), ';', prefix_list, output_lines, global_vars_seen_dict, args.preserve_names, True)
+ has_checked_pre_function_globals = True
+
+ if common.should_add_line_to_output(input_line, prefix_set, not is_in_function):
# This input line of the function body will go as-is into the output.
# Except make leading whitespace uniform: 2 spaces.
input_line = common.SCRUB_LEADING_WHITESPACE_RE.sub(r' ', input_line)
output_lines.append(input_line)
- else:
- continue
- if input_line.strip() == '}':
- is_in_function = False
- continue
+ if input_line.strip() == '}':
+ is_in_function = False
+ continue
- # If it's outside a function, it just gets copied to the output.
- output_lines.append(input_line)
+ if is_in_function:
+ continue
m = common.IR_FUNCTION_RE.match(input_line)
if not m:
@@ -190,6 +208,8 @@
continue
is_in_function = is_in_function_start = True
+ if args.check_globals:
+ common.add_global_checks(builder.global_var_dict(), ';', prefix_list, output_lines, global_vars_seen_dict, args.preserve_names, False)
common.debug('Writing %d lines to %s...' % (len(output_lines), ti.path))
with open(ti.path, 'wb') as f:
diff --git a/src/llvm-project/llvm/utils/vim/ftdetect/mir.vim b/src/llvm-project/llvm/utils/vim/ftdetect/mir.vim
new file mode 100644
index 0000000..15d5a63
--- /dev/null
+++ b/src/llvm-project/llvm/utils/vim/ftdetect/mir.vim
@@ -0,0 +1 @@
+au BufRead,BufNewFile *.mir set filetype=mir
diff --git a/src/llvm-project/llvm/utils/vim/ftplugin/mir.vim b/src/llvm-project/llvm/utils/vim/ftplugin/mir.vim
new file mode 100644
index 0000000..3779c86
--- /dev/null
+++ b/src/llvm-project/llvm/utils/vim/ftplugin/mir.vim
@@ -0,0 +1,13 @@
+" Vim filetype plugin file
+" Language: LLVM Machine IR
+" Maintainer: The LLVM team, http://llvm.org/
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+setlocal softtabstop=2 shiftwidth=2
+setlocal expandtab
+setlocal comments+=:;
+
diff --git a/src/llvm-project/llvm/utils/vim/syntax/llvm.vim b/src/llvm-project/llvm/utils/vim/syntax/llvm.vim
index 0914f6d..c41b414 100644
--- a/src/llvm-project/llvm/utils/vim/syntax/llvm.vim
+++ b/src/llvm-project/llvm/utils/vim/syntax/llvm.vim
@@ -15,8 +15,8 @@
" Types also include struct, array, vector, etc. but these don't
" benefit as much from having dedicated highlighting rules.
syn keyword llvmType void half bfloat float double x86_fp80 fp128 ppc_fp128
-syn keyword llvmType label metadata x86_mmx
-syn keyword llvmType type label opaque token
+syn keyword llvmType label metadata x86_mmx x86_amx
+syn keyword llvmType type label opaque token ptr
syn match llvmType /\<i\d\+\>/
" Instructions.
@@ -25,16 +25,16 @@
syn keyword llvmStatement add addrspacecast alloca and arcp ashr atomicrmw
syn keyword llvmStatement bitcast br catchpad catchswitch catchret call callbr
syn keyword llvmStatement cleanuppad cleanupret cmpxchg eq exact extractelement
-syn keyword llvmStatement extractvalue fadd fast fcmp fdiv fence fmul fpext
-syn keyword llvmStatement fptosi fptoui fptrunc free frem fsub fneg getelementptr
-syn keyword llvmStatement icmp inbounds indirectbr insertelement insertvalue
-syn keyword llvmStatement inttoptr invoke landingpad load lshr malloc max min
-syn keyword llvmStatement mul nand ne ninf nnan nsw nsz nuw oeq oge ogt ole
-syn keyword llvmStatement olt one or ord phi ptrtoint resume ret sdiv select
-syn keyword llvmStatement sext sge sgt shl shufflevector sitofp sle slt srem
-syn keyword llvmStatement store sub switch trunc udiv ueq uge ugt uitofp ule ult
-syn keyword llvmStatement umax umin une uno unreachable unwind urem va_arg
-syn keyword llvmStatement xchg xor zext
+syn keyword llvmStatement extractvalue fadd fast fcmp fdiv fence fmul fneg fpext
+syn keyword llvmStatement fptosi fptoui fptrunc free freeze frem fsub
+syn keyword llvmStatement getelementptr icmp inbounds indirectbr insertelement
+syn keyword llvmStatement insertvalue inttoptr invoke landingpad load lshr
+syn keyword llvmStatement malloc max min mul nand ne ninf nnan nsw nsz nuw oeq
+syn keyword llvmStatement oge ogt ole olt one or ord phi ptrtoint resume ret
+syn keyword llvmStatement sdiv select sext sge sgt shl shufflevector sitofp
+syn keyword llvmStatement sle slt srem store sub switch trunc udiv ueq uge ugt
+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
@@ -44,11 +44,12 @@
\ alias
\ align
\ alignstack
+ \ allocsize
\ alwaysinline
\ appending
\ argmemonly
- \ arm_aapcscc
\ arm_aapcs_vfpcc
+ \ arm_aapcscc
\ arm_apcscc
\ asm
\ atomic
@@ -58,51 +59,58 @@
\ byref
\ byval
\ c
- \ catch
\ caller
+ \ catch
\ cc
\ ccc
\ cleanup
+ \ cold
\ coldcc
\ comdat
\ common
\ constant
+ \ convergent
\ datalayout
\ declare
\ default
\ define
\ deplibs
\ dereferenceable
+ \ dereferenceable_or_null
\ distinct
\ dllexport
\ dllimport
\ dso_local
\ dso_preemptable
\ except
+ \ extern_weak
\ external
\ externally_initialized
- \ extern_weak
\ fastcc
- \ tailcc
\ filter
\ from
\ gc
\ global
- \ hhvmcc
\ hhvm_ccc
+ \ hhvmcc
\ hidden
+ \ hot
\ immarg
+ \ inaccessiblemem_or_argmemonly
+ \ inaccessiblememonly
+ \ inalloca
\ initialexec
\ inlinehint
\ inreg
- \ inteldialect
\ intel_ocl_bicc
+ \ inteldialect
\ internal
+ \ jumptable
\ linkonce
\ linkonce_odr
+ \ local_unnamed_addr
\ localdynamic
\ localexec
- \ local_unnamed_addr
\ minsize
\ module
\ monotonic
@@ -113,19 +121,30 @@
\ nest
\ noalias
\ nobuiltin
+ \ nocallback
\ nocapture
+ \ nocf_check
+ \ noduplicate
+ \ nofree
\ noimplicitfloat
\ noinline
+ \ nomerge
\ nonlazybind
\ nonnull
+ \ noprofile
\ norecurse
\ noredzone
\ noreturn
+ \ nosync
\ noundef
\ nounwind
+ \ nosanitize_coverage
+ \ null_pointer_is_valid
+ \ optforfuzzing
\ optnone
\ optsize
\ personality
+ \ preallocated
\ private
\ protected
\ ptx_device
@@ -135,16 +154,20 @@
\ release
\ returned
\ returns_twice
+ \ safestack
\ sanitize_address
+ \ sanitize_hwaddress
\ sanitize_memory
+ \ sanitize_memtag
\ sanitize_thread
\ section
\ seq_cst
+ \ shadowcallstack
\ sideeffect
\ signext
- \ syncscope
\ source_filename
\ speculatable
+ \ speculative_load_hardening
\ spir_func
\ spir_kernel
\ sret
@@ -153,8 +176,12 @@
\ sspstrong
\ strictfp
\ swiftcc
+ \ swifterror
+ \ swifttailcc
\ swiftself
+ \ syncscope
\ tail
+ \ tailcc
\ target
\ thread_local
\ to
@@ -167,10 +194,11 @@
\ volatile
\ weak
\ weak_odr
+ \ willreturn
+ \ win64cc
\ within
\ writeonly
\ x86_64_sysvcc
- \ win64cc
\ x86_fastcallcc
\ x86_stdcallcc
\ x86_thiscallcc
@@ -185,7 +213,7 @@
syn match llvmFloat /-\?\<\d\+\.\d*\(e[+-]\d\+\)\?\>/
syn match llvmFloat /\<0x\x\+\>/
syn keyword llvmBoolean true false
-syn keyword llvmConstant zeroinitializer undef null none
+syn keyword llvmConstant zeroinitializer undef null none poison vscale
syn match llvmComment /;.*$/
syn region llvmString start=/"/ skip=/\\"/ end=/"/
syn match llvmLabel /[-a-zA-Z$._][-a-zA-Z$._0-9]*:/
@@ -208,7 +236,8 @@
syn match llvmSpecialComment /;\s*RUN:.*$/
syn match llvmSpecialComment /;\s*ALLOW_RETRIES:.*$/
syn match llvmSpecialComment /;\s*CHECK:.*$/
-syn match llvmSpecialComment "\v;\s*CHECK-(NEXT|NOT|DAG|SAME|LABEL):.*$"
+syn match llvmSpecialComment /;\s*CHECK-EMPTY:\s*$/
+syn match llvmSpecialComment /\v;\s*CHECK-(NEXT|NOT|DAG|SAME|LABEL|COUNT-\d+):.*$/
syn match llvmSpecialComment /;\s*XFAIL:.*$/
if version >= 508 || !exists("did_c_syn_inits")
diff --git a/src/llvm-project/llvm/utils/vim/syntax/machine-ir.vim b/src/llvm-project/llvm/utils/vim/syntax/machine-ir.vim
new file mode 100644
index 0000000..814b31b
--- /dev/null
+++ b/src/llvm-project/llvm/utils/vim/syntax/machine-ir.vim
@@ -0,0 +1,38 @@
+" Vim syntax file
+" Language: mir
+" Maintainer: The LLVM team, http://llvm.org/
+" Version: $Revision$
+
+syn case match
+
+" FIXME: MIR doesn't actually match LLVM IR. Stop including it all as a
+" fallback once enough is implemented.
+" See the MIR LangRef: https://llvm.org/docs/MIRLangRef.html
+unlet b:current_syntax " Unlet so that the LLVM syntax will load
+runtime! syntax/llvm.vim
+unlet b:current_syntax
+
+syn match mirType /\<[sp]\d\+\>/
+
+" Opcodes. Matching instead of listing them because individual targets can add
+" these. FIXME: Maybe use some more context to make this more accurate?
+syn match mirStatement /\<[A-Z][A-Za-z0-9_]*\>/
+
+syn match mirPReg /$[-a-zA-Z$._][-a-zA-Z$._0-9]*/
+
+if version >= 508 || !exists("did_c_syn_inits")
+ if version < 508
+ let did_c_syn_inits = 1
+ command -nargs=+ HiLink hi link <args>
+ else
+ command -nargs=+ HiLink hi def link <args>
+ endif
+
+ HiLink mirType Type
+ HiLink mirStatement Statement
+ HiLink mirPReg Identifier
+
+ delcommand HiLink
+endif
+
+let b:current_syntax = "mir"
diff --git a/src/llvm-project/llvm/utils/vim/syntax/mir.vim b/src/llvm-project/llvm/utils/vim/syntax/mir.vim
new file mode 100644
index 0000000..51ac498
--- /dev/null
+++ b/src/llvm-project/llvm/utils/vim/syntax/mir.vim
@@ -0,0 +1,48 @@
+" Vim syntax file
+" Language: mir
+" Maintainer: The LLVM team, http://llvm.org/
+" Version: $Revision$
+
+if version < 600
+ syntax clear
+elseif exists("b:current_syntax")
+ finish
+endif
+
+syn case match
+
+" MIR is embedded in a yaml container, so we load all of the yaml syntax.
+runtime! syntax/yaml.vim
+unlet b:current_syntax
+
+" The first document of a file is allowed to contain an LLVM IR module inside
+" a top-level yaml block string.
+syntax include @LLVM syntax/llvm.vim
+" FIXME: This should only be allowed for the first document of the file
+syntax region llvm start=/\(^---\s*|\)\@<=/ end=/\(^\.\.\.\)\@=/ contains=@LLVM
+
+" The `body:` field of a document contains the MIR dump of the function
+syntax include @MIR syntax/machine-ir.vim
+syntax region mir start=/\(^body:\s*|\)\@<=/ end=/\(^[^[:space:]]\)\@=/ contains=@MIR
+
+" Syntax-highlight lit test commands and bug numbers.
+syn match mirSpecialComment /#\s*PR\d*\s*$/
+syn match mirSpecialComment /#\s*REQUIRES:.*$/
+syn match mirSpecialComment /#\s*RUN:.*$/
+syn match mirSpecialComment /#\s*ALLOW_RETRIES:.*$/
+syn match mirSpecialComment /#\s*CHECK:.*$/
+syn match mirSpecialComment "\v#\s*CHECK-(NEXT|NOT|DAG|SAME|LABEL):.*$"
+syn match mirSpecialComment /#\s*XFAIL:.*$/
+
+if version >= 508 || !exists("did_c_syn_inits")
+ if version < 508
+ let did_c_syn_inits = 1
+ command -nargs=+ HiLink hi link <args>
+ else
+ command -nargs=+ HiLink hi def link <args>
+ endif
+
+ HiLink mirSpecialComment SpecialComment
+endif
+
+let b:current_syntax = "mir"
diff --git a/src/llvm-project/llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml b/src/llvm-project/llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml
index 49c2dac..127f5d9 100644
--- a/src/llvm-project/llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml
+++ b/src/llvm-project/llvm/utils/vscode/llvm/syntaxes/ll.tmLanguage.yaml
@@ -14,6 +14,7 @@
patterns:
- match: "\\bvoid\\b|\
\\bhalf\\b|\
+ \\bbfloat\\b|\
\\bfloat\\b|\
\\bdouble\\b|\
\\bx86_fp80\\b|\
@@ -22,6 +23,7 @@
\\blabel\\b|\
\\bmetadata\\b|\
\\bx86_mmx\\b|\
+ \\bx86_amx\\b|\
\\btype\\b|\
\\blabel\\b|\
\\bopaque\\b|\
@@ -65,6 +67,7 @@
\\bfptrunc\\b|\
\\bfree\\b|\
\\bfrem\\b|\
+ \\bfreeze\\b|\
\\bfsub\\b|\
\\bfneg\\b|\
\\bgetelementptr\\b|\
@@ -141,11 +144,12 @@
\\balias\\b|\
\\balign\\b|\
\\balignstack\\b|\
+ \\ballocsize\\b|\
\\balwaysinline\\b|\
\\bappending\\b|\
\\bargmemonly\\b|\
- \\barm_aapcscc\\b|\
\\barm_aapcs_vfpcc\\b|\
+ \\barm_aapcscc\\b|\
\\barm_apcscc\\b|\
\\basm\\b|\
\\batomic\\b|\
@@ -155,51 +159,58 @@
\\bbyref\\b|\
\\bbyval\\b|\
\\bc\\b|\
- \\bcatch\\b|\
\\bcaller\\b|\
+ \\bcatch\\b|\
\\bcc\\b|\
\\bccc\\b|\
\\bcleanup\\b|\
+ \\bcold\\b|\
\\bcoldcc\\b|\
\\bcomdat\\b|\
\\bcommon\\b|\
\\bconstant\\b|\
+ \\bconvergent\\b|\
\\bdatalayout\\b|\
\\bdeclare\\b|\
\\bdefault\\b|\
\\bdefine\\b|\
\\bdeplibs\\b|\
\\bdereferenceable\\b|\
+ \\bdereferenceable_or_null\\b|\
\\bdistinct\\b|\
\\bdllexport\\b|\
\\bdllimport\\b|\
\\bdso_local\\b|\
\\bdso_preemptable\\b|\
\\bexcept\\b|\
+ \\bextern_weak\\b|\
\\bexternal\\b|\
\\bexternally_initialized\\b|\
- \\bextern_weak\\b|\
\\bfastcc\\b|\
- \\btailcc\\b|\
\\bfilter\\b|\
\\bfrom\\b|\
\\bgc\\b|\
\\bglobal\\b|\
- \\bhhvmcc\\b|\
\\bhhvm_ccc\\b|\
+ \\bhhvmcc\\b|\
\\bhidden\\b|\
+ \\bhot\\b|\
\\bimmarg\\b|\
+ \\binaccessiblemem_or_argmemonly\\b|\
+ \\binaccessiblememonly\\b|\
+ \\binalloc\\b|\
\\binitialexec\\b|\
\\binlinehint\\b|\
\\binreg\\b|\
- \\binteldialect\\b|\
\\bintel_ocl_bicc\\b|\
+ \\binteldialect\\b|\
\\binternal\\b|\
+ \\bjumptable\\b|\
\\blinkonce\\b|\
\\blinkonce_odr\\b|\
+ \\blocal_unnamed_addr\\b|\
\\blocaldynamic\\b|\
\\blocalexec\\b|\
- \\blocal_unnamed_addr\\b|\
\\bminsize\\b|\
\\bmodule\\b|\
\\bmonotonic\\b|\
@@ -210,19 +221,30 @@
\\bnest\\b|\
\\bnoalias\\b|\
\\bnobuiltin\\b|\
+ \\bnocallback\\b|\
\\bnocapture\\b|\
+ \\bnocf_check\\b|\
+ \\bnoduplicate\\b|\
+ \\bnofree\\b|\
\\bnoimplicitfloat\\b|\
\\bnoinline\\b|\
+ \\bnomerge\\b|\
\\bnonlazybind\\b|\
\\bnonnull\\b|\
+ \\bnoprofile\\b|\
\\bnorecurse\\b|\
\\bnoredzone\\b|\
\\bnoreturn\\b|\
+ \\bnosync\\b|\
\\bnoundef\\b|\
\\bnounwind\\b|\
+ \\bnosanitize_coverage\\b|\
+ \\bnull_pointer_is_valid\\b|\
+ \\boptforfuzzing\\b|\
\\boptnone\\b|\
\\boptsize\\b|\
\\bpersonality\\b|\
+ \\bpreallocated\\b|\
\\bprivate\\b|\
\\bprotected\\b|\
\\bptx_device\\b|\
@@ -232,16 +254,20 @@
\\brelease\\b|\
\\breturned\\b|\
\\breturns_twice\\b|\
+ \\bsafestack\\b|\
\\bsanitize_address\\b|\
+ \\bsanitize_hwaddress\\b|\
\\bsanitize_memory\\b|\
+ \\bsanitize_memtag\\b|\
\\bsanitize_thread\\b|\
\\bsection\\b|\
\\bseq_cst\\b|\
+ \\bshadowcallstack\\b|\
\\bsideeffect\\b|\
\\bsignext\\b|\
- \\bsyncscope\\b|\
\\bsource_filename\\b|\
\\bspeculatable\\b|\
+ \\bspeculative_load_hardening\\b|\
\\bspir_func\\b|\
\\bspir_kernel\\b|\
\\bsret\\b|\
@@ -250,8 +276,11 @@
\\bsspstrong\\b|\
\\bstrictfp\\b|\
\\bswiftcc\\b|\
+ \\bswifterror\\b|\
\\bswiftself\\b|\
+ \\bsyncscope\\b|\
\\btail\\b|\
+ \\btailcc\\b|\
\\btarget\\b|\
\\bthread_local\\b|\
\\bto\\b|\
@@ -264,10 +293,11 @@
\\bvolatile\\b|\
\\bweak\\b|\
\\bweak_odr\\b|\
+ \\bwillreturn\\b|\
+ \\bwin64cc\\b|\
\\bwithin\\b|\
\\bwriteonly\\b|\
\\bx86_64_sysvcc\\b|\
- \\bwin64cc\\b|\
\\bx86_fastcallcc\\b|\
\\bx86_stdcallcc\\b|\
\\bx86_thiscallcc\\b|\
@@ -306,6 +336,7 @@
\\bnull\\b|\
\\bzeroinitializer\\b|\
\\bundef\\b|\
+ \\bpoison\\b|\
\\bnull\\b|\
\\bnone\\b"
name: constant.language
diff --git a/src/llvm-project/llvm/utils/wciia.py b/src/llvm-project/llvm/utils/wciia.py
index 4269db2..666bd63 100755
--- a/src/llvm-project/llvm/utils/wciia.py
+++ b/src/llvm-project/llvm/utils/wciia.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-
"""
wciia - Whose Code Is It Anyway
@@ -25,90 +24,95 @@
code_owners = {}
+
def process_files_and_folders(owner):
- filesfolders = owner['filesfolders']
- # paths must be in ( ... ) so strip them
- lpar = filesfolders.find('(')
- rpar = filesfolders.rfind(')')
- if rpar <= lpar:
- # give up
- return
- paths = filesfolders[lpar+1:rpar]
- # split paths
- owner['paths'] = []
- for path in paths.split():
- owner['paths'].append(path)
-
+ filesfolders = owner['filesfolders']
+ # paths must be in ( ... ) so strip them
+ lpar = filesfolders.find('(')
+ rpar = filesfolders.rfind(')')
+ if rpar <= lpar:
+ # give up
+ return
+ paths = filesfolders[lpar + 1:rpar]
+ # split paths
+ owner['paths'] = []
+ for path in paths.split():
+ owner['paths'].append(path)
+
+
def process_code_owner(owner):
- if 'filesfolders' in owner:
- filesfolders = owner['filesfolders']
- else:
-# print "F: field missing, using D: field"
- owner['filesfolders'] = owner['description']
- process_files_and_folders(owner)
- code_owners[owner['name']] = owner
-
+ if 'filesfolders' in owner:
+ filesfolders = owner['filesfolders']
+ else:
+ # print "F: field missing, using D: field"
+ owner['filesfolders'] = owner['description']
+ process_files_and_folders(owner)
+ code_owners[owner['name']] = owner
+
+
# process CODE_OWNERS.TXT first
code_owners_file = open("CODE_OWNERS.TXT", "r").readlines()
code_owner = {}
for line in code_owners_file:
for word in line.split():
- if word == "N:":
- name = line[2:].strip()
- if code_owner:
- process_code_owner(code_owner)
- code_owner = {}
- # reset the values
- code_owner['name'] = name
- if word == "E:":
- email = line[2:].strip()
- code_owner['email'] = email
- if word == "D:":
- description = line[2:].strip()
- code_owner['description'] = description
- if word == "F:":
- filesfolders = line[2:].strip()
- code_owner['filesfolders'].append(filesfolders)
-
+ if word == "N:":
+ name = line[2:].strip()
+ if code_owner:
+ process_code_owner(code_owner)
+ code_owner = {}
+ # reset the values
+ code_owner['name'] = name
+ if word == "E:":
+ email = line[2:].strip()
+ code_owner['email'] = email
+ if word == "D:":
+ description = line[2:].strip()
+ code_owner['description'] = description
+ if word == "F:":
+ filesfolders = line[2:].strip()
+ code_owner['filesfolders'].append(filesfolders)
+
+
def find_owners(fpath):
- onames = []
- lmatch = -1
- # very simplistic way of findning the best match
- for name in code_owners:
- owner = code_owners[name]
- if 'paths' in owner:
- for path in owner['paths']:
-# print "searching (" + path + ")"
- # try exact match
- if fpath == path:
- return name
- # see if path ends with a *
- rstar = path.rfind('*')
- if rstar>0:
- # try the longest match,
- rpos = -1
- if len(fpath) < len(path):
- rpos = path.find(fpath)
- if rpos == 0:
- onames.append(name)
- onames.append('Chris Lattner')
- return onames
-
+ onames = []
+ lmatch = -1
+ # very simplistic way of findning the best match
+ for name in code_owners:
+ owner = code_owners[name]
+ if 'paths' in owner:
+ for path in owner['paths']:
+ # print "searching (" + path + ")"
+ # try exact match
+ if fpath == path:
+ return name
+ # see if path ends with a *
+ rstar = path.rfind('*')
+ if rstar > 0:
+ # try the longest match,
+ rpos = -1
+ if len(fpath) < len(path):
+ rpos = path.find(fpath)
+ if rpos == 0:
+ onames.append(name)
+ onames.append('Chris Lattner')
+ return onames
+
+
# now lest try to find the owner of the file or folder
import sys
if len(sys.argv) < 2:
- print("usage " + sys.argv[0] + " file_or_folder")
- exit(-1)
-
+ print("usage " + sys.argv[0] + " file_or_folder")
+ exit(-1)
+
# the path we are checking
path = str(sys.argv[1])
# check if this is real path
if not os.path.exists(path):
- print("path (" + path + ") does not exist")
- exit(-1)
-
+ print("path (" + path + ") does not exist")
+ exit(-1)
+
owners_name = find_owners(path)
# be grammatically correct
@@ -117,10 +121,10 @@
exit(0)
# bottom up walk of the current .
-# not yet used
+# not yet used
root = "."
-for dir,subdirList,fileList in os.walk( root , topdown=False ) :
- print("dir :" , dir)
- for fname in fileList :
- print("-" , fname)
- print()
+for dir, subdirList, fileList in os.walk(root, topdown=False):
+ print("dir :", dir)
+ for fname in fileList:
+ print("-", fname)
+ print()