Commit d3544d02 authored by Brad King's avatar Brad King Committed by Kitware Robot
Browse files

Merge topic 'compiler-features'

7647f6af Add CM_OVERRIDE to some functions
5286110d cxx features: add check for override
09aa2c94 Use <unordered_set> where available
ea5477e4 Make C++ feature checks extensible
parents 4adab709 7647f6af
......@@ -67,7 +67,7 @@ if(NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMake_NO_CXX_STANDARD)
endif()
endif()
if(NOT CMake_TEST_EXTERNAL_CMAKE)
include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx11_unordered_map.cmake)
include(${CMake_SOURCE_DIR}/Source/Checks/cm_cxx_features.cmake)
endif()
# option to set the internal encoding of CMake to UTF-8
......
......@@ -177,7 +177,7 @@ public:
bool patched;
protected:
virtual void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
xout.StartElement(name);
StartFragment(atts);
......@@ -192,7 +192,7 @@ protected:
}
}
virtual void EndElement(const std::string& name)
void EndElement(const std::string& name) CM_OVERRIDE
{
if (name == "Updates" && !patched) {
repository->WriteRepositoryUpdates(xout);
......@@ -208,7 +208,7 @@ protected:
}
}
virtual void CharacterDataHandler(const char* data, int length)
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
{
std::string content(data, data + length);
if (content == "" || content == " " || content == " " ||
......
......@@ -101,7 +101,7 @@ private:
bool CheckOutFound;
cmsys::RegularExpression RegexCheckOut;
cmsys::RegularExpression RegexParent;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexCheckOut.find(this->Line)) {
this->BZR->URL = this->RegexCheckOut.match(1);
......@@ -126,7 +126,7 @@ public:
private:
std::string& Rev;
cmsys::RegularExpression RegexRevno;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexRevno.find(this->Line)) {
this->Rev = this->RegexRevno.match(1);
......@@ -185,7 +185,7 @@ public:
}
~LogParser() { this->CleanupParser(); }
virtual int InitializeParser()
int InitializeParser() CM_OVERRIDE
{
int res = cmXMLParser::InitializeParser();
if (res) {
......@@ -207,14 +207,14 @@ private:
cmsys::RegularExpression EmailRegex;
virtual bool ProcessChunk(const char* data, int length)
bool ProcessChunk(const char* data, int length) CM_OVERRIDE
{
this->OutputLogger::ProcessChunk(data, length);
this->ParseChunk(data, length);
return true;
}
virtual void StartElement(const std::string& name, const char**)
void StartElement(const std::string& name, const char**) CM_OVERRIDE
{
this->CData.clear();
if (name == "log") {
......@@ -239,12 +239,12 @@ private:
}
}
virtual void CharacterDataHandler(const char* data, int length)
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
{
this->CData.insert(this->CData.end(), data, data + length);
}
virtual void EndElement(const std::string& name)
void EndElement(const std::string& name) CM_OVERRIDE
{
if (name == "log") {
this->BZR->DoRevision(this->Rev, this->Changes);
......@@ -274,7 +274,7 @@ private:
this->CData.clear();
}
virtual void ReportError(int, int, const char* msg)
void ReportError(int, int, const char* msg) CM_OVERRIDE
{
this->BZR->Log << "Error parsing bzr log xml: " << msg << "\n";
}
......@@ -294,7 +294,7 @@ private:
cmCTestBZR* BZR;
cmsys::RegularExpression RegexUpdate;
virtual bool ProcessChunk(const char* first, int length)
bool ProcessChunk(const char* first, int length) CM_OVERRIDE
{
bool last_is_new_line = (*first == '\r' || *first == '\n');
......@@ -325,7 +325,7 @@ private:
return true;
}
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexUpdate.find(this->Line)) {
this->DoPath(this->RegexUpdate.match(1)[0],
......@@ -431,7 +431,7 @@ public:
private:
cmCTestBZR* BZR;
cmsys::RegularExpression RegexStatus;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexStatus.find(this->Line)) {
this->DoPath(this->RegexStatus.match(1)[0],
......
......@@ -53,7 +53,7 @@ private:
cmsys::RegularExpression RegexFileRemoved1;
cmsys::RegularExpression RegexFileRemoved2;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexFileUpdated.find(this->Line)) {
this->DoFile(PathUpdated, this->RegexFileUpdated.match(2));
......@@ -140,7 +140,7 @@ private:
SectionType Section;
Revision Rev;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->Line == ("======================================="
"======================================")) {
......
......@@ -52,7 +52,7 @@ public:
private:
std::string& Line1;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
// Only the first line is of interest.
this->Line1 = this->Line;
......@@ -355,7 +355,7 @@ protected:
this->Changes.clear();
}
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->Line[0] == ':') {
this->DiffField = DiffFieldChange;
......@@ -513,7 +513,7 @@ private:
person.TimeZone = strtol(c, (char**)&c, 10);
}
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->Line.empty()) {
if (this->Section == SectionBody && this->LineEnd == '\0') {
......
......@@ -41,7 +41,7 @@ private:
std::string& Rev;
cmsys::RegularExpression RegexIdentify;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexIdentify.find(this->Line)) {
this->Rev = this->RegexIdentify.match(1);
......@@ -65,7 +65,7 @@ private:
cmCTestHG* HG;
cmsys::RegularExpression RegexStatus;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexStatus.find(this->Line)) {
this->DoPath(this->RegexStatus.match(1)[0], this->RegexStatus.match(2));
......@@ -182,14 +182,14 @@ private:
Change CurChange;
std::vector<char> CData;
virtual bool ProcessChunk(const char* data, int length)
bool ProcessChunk(const char* data, int length) CM_OVERRIDE
{
this->OutputLogger::ProcessChunk(data, length);
this->ParseChunk(data, length);
return true;
}
virtual void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
this->CData.clear();
if (name == "logentry") {
......@@ -201,12 +201,12 @@ private:
}
}
virtual void CharacterDataHandler(const char* data, int length)
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
{
this->CData.insert(this->CData.end(), data, data + length);
}
virtual void EndElement(const std::string& name)
void EndElement(const std::string& name) CM_OVERRIDE
{
if (name == "logentry") {
this->HG->DoRevision(this->Rev, this->Changes);
......@@ -261,7 +261,7 @@ private:
return output;
}
virtual void ReportError(int, int, const char* msg)
void ReportError(int, int, const char* msg) CM_OVERRIDE
{
this->HG->Log << "Error parsing hg log xml: " << msg << "\n";
}
......
......@@ -61,7 +61,7 @@ public:
this->CTest = c;
this->SetErrorCallback(xmlReportError, (void*)c);
}
void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
if (name == "MemoryLeak" || name == "ResourceLeak") {
this->Errors.push_back(cmCTestMemCheckHandler::MLK);
......@@ -78,7 +78,7 @@ public:
ostr << "\n";
this->Log += ostr.str();
}
void EndElement(const std::string&) {}
void EndElement(const std::string&) CM_OVERRIDE {}
const char* GetAttribute(const char* name, const char** atts)
{
......
......@@ -45,7 +45,7 @@ private:
std::string& Rev;
cmsys::RegularExpression RegexIdentify;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexIdentify.find(this->Line)) {
this->Rev = this->RegexIdentify.match(1);
......@@ -69,7 +69,7 @@ private:
cmsys::RegularExpression RegexIdentify;
cmCTestP4* P4;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexIdentify.find(this->Line)) {
P4->ChangeLists.push_back(this->RegexIdentify.match(1));
......@@ -92,7 +92,7 @@ private:
cmsys::RegularExpression RegexUser;
cmCTestP4* P4;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexUser.find(this->Line)) {
User NewUser;
......@@ -135,7 +135,7 @@ private:
std::string CurrentPath;
cmsys::RegularExpression RegexDiff;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (!this->Line.empty() && this->Line[0] == '=' &&
this->RegexDiff.find(this->Line)) {
......@@ -225,7 +225,7 @@ private:
SectionType Section;
Revision Rev;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->Line.empty()) {
this->NextSection();
......
......@@ -62,7 +62,7 @@ private:
cmsys::RegularExpression RegexRev;
cmsys::RegularExpression RegexURL;
cmsys::RegularExpression RegexRoot;
virtual bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexRev.find(this->Line)) {
this->Rev = this->RegexRev.match(1);
......@@ -206,7 +206,7 @@ private:
cmCTestSVN* SVN;
cmsys::RegularExpression RegexUpdate;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexUpdate.find(this->Line)) {
this->DoPath(this->RegexUpdate.match(1)[0],
......@@ -323,14 +323,14 @@ private:
Change CurChange;
std::vector<char> CData;
virtual bool ProcessChunk(const char* data, int length)
bool ProcessChunk(const char* data, int length) CM_OVERRIDE
{
this->OutputLogger::ProcessChunk(data, length);
this->ParseChunk(data, length);
return true;
}
virtual void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
this->CData.clear();
if (name == "logentry") {
......@@ -348,12 +348,12 @@ private:
}
}
virtual void CharacterDataHandler(const char* data, int length)
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
{
this->CData.insert(this->CData.end(), data, data + length);
}
virtual void EndElement(const std::string& name)
void EndElement(const std::string& name) CM_OVERRIDE
{
if (name == "logentry") {
this->SVN->DoRevisionSVN(this->Rev, this->Changes);
......@@ -372,7 +372,7 @@ private:
this->CData.clear();
}
virtual void ReportError(int, int, const char* msg)
void ReportError(int, int, const char* msg) CM_OVERRIDE
{
this->SVN->Log << "Error parsing svn log xml: " << msg << "\n";
}
......@@ -441,7 +441,7 @@ public:
private:
cmCTestSVN* SVN;
cmsys::RegularExpression RegexStatus;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexStatus.find(this->Line)) {
this->DoPath(this->RegexStatus.match(1)[0],
......@@ -506,7 +506,7 @@ public:
private:
cmCTestSVN* SVN;
cmsys::RegularExpression RegexExternal;
bool ProcessLine()
bool ProcessLine() CM_OVERRIDE
{
if (this->RegexExternal.find(this->Line)) {
this->DoPath(this->RegexExternal.match(1));
......
......@@ -60,8 +60,8 @@ class cmCTestScriptFunctionBlocker : public cmFunctionBlocker
public:
cmCTestScriptFunctionBlocker() {}
virtual ~cmCTestScriptFunctionBlocker() {}
virtual bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
cmExecutionStatus&);
bool IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile& mf,
cmExecutionStatus&) CM_OVERRIDE;
// virtual bool ShouldRemove(const cmListFileFunction& lff, cmMakefile &mf);
// virtual void ScopeEnded(cmMakefile &mf);
......
......@@ -69,7 +69,7 @@ private:
return val;
}
virtual void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
this->CurrentValue.clear();
if (name == "cdash") {
......@@ -77,12 +77,12 @@ private:
}
}
virtual void CharacterDataHandler(const char* data, int length)
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
{
this->CurrentValue.insert(this->CurrentValue.end(), data, data + length);
}
virtual void EndElement(const std::string& name)
void EndElement(const std::string& name) CM_OVERRIDE
{
if (name == "status") {
std::string status = cmSystemTools::UpperCase(this->GetCurrentValue());
......
......@@ -42,7 +42,7 @@ public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
cmCommand* Clone() CM_OVERRIDE
{
cmCTestSubdirCommand* c = new cmCTestSubdirCommand;
c->TestHandler = this->TestHandler;
......@@ -53,13 +53,13 @@ public:
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&);
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&) CM_OVERRIDE;
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual std::string GetName() const { return "subdirs"; }
std::string GetName() const CM_OVERRIDE { return "subdirs"; }
cmTypeMacro(cmCTestSubdirCommand, cmCommand);
......@@ -123,7 +123,7 @@ public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
cmCommand* Clone() CM_OVERRIDE
{
cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand;
c->TestHandler = this->TestHandler;
......@@ -134,13 +134,13 @@ public:
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&);
bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus&) CM_OVERRIDE;
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual std::string GetName() const { return "add_subdirectory"; }
std::string GetName() const CM_OVERRIDE { return "add_subdirectory"; }
cmTypeMacro(cmCTestAddSubdirectoryCommand, cmCommand);
......@@ -197,7 +197,7 @@ public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
cmCommand* Clone() CM_OVERRIDE
{
cmCTestAddTestCommand* c = new cmCTestAddTestCommand;
c->TestHandler = this->TestHandler;
......@@ -208,13 +208,13 @@ public:
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const&,
cmExecutionStatus&);
bool InitialPass(std::vector<std::string> const&,
cmExecutionStatus&) CM_OVERRIDE;
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual std::string GetName() const { return "add_test"; }
std::string GetName() const CM_OVERRIDE { return "add_test"; }
cmTypeMacro(cmCTestAddTestCommand, cmCommand);
......@@ -237,7 +237,7 @@ public:
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
cmCommand* Clone() CM_OVERRIDE
{
cmCTestSetTestsPropertiesCommand* c = new cmCTestSetTestsPropertiesCommand;
c->TestHandler = this->TestHandler;
......@@ -248,13 +248,13 @@ public:
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const&,
cmExecutionStatus&);
bool InitialPass(std::vector<std::string> const&,
cmExecutionStatus&) CM_OVERRIDE;
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual std::string GetName() const { return "set_tests_properties"; }
std::string GetName() const CM_OVERRIDE { return "set_tests_properties"; }
cmTypeMacro(cmCTestSetTestsPropertiesCommand, cmCommand);
......
......@@ -23,7 +23,7 @@ public:
virtual ~XMLParser() {}
protected:
virtual void EndElement(const std::string& name)
void EndElement(const std::string& name) CM_OVERRIDE
{
if (name == "source") {
this->InSource = false;
......@@ -34,7 +34,7 @@ protected:
}
}
virtual void CharacterDataHandler(const char* data, int length)
void CharacterDataHandler(const char* data, int length) CM_OVERRIDE
{
std::string tmp;
tmp.insert(0, data, length);
......@@ -46,7 +46,7 @@ protected:
}
}
virtual void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
std::string FoundSource;
std::string finalpath = "";
......
......@@ -23,9 +23,9 @@ public:
virtual ~XMLParser() {}
protected:
virtual void EndElement(const std::string&) {}
void EndElement(const std::string&) CM_OVERRIDE {}
virtual void StartElement(const std::string& name, const char** atts)
void StartElement(const std::string& name, const char** atts) CM_OVERRIDE
{
if (name == "package") {
this->PackageName = atts[1];
......
if(CMAKE_CXX_STANDARD AND NOT DEFINED CMake_HAVE_CXX11_UNORDERED_MAP)
message(STATUS "Checking if compiler supports C++11 unordered_map")
try_compile(CMake_HAVE_CXX11_UNORDERED_MAP
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx11_unordered_map.cpp
CMAKE_FLAGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
OUTPUT_VARIABLE OUTPUT
)
if(CMake_HAVE_CXX11_UNORDERED_MAP)
message(STATUS "Checking if compiler supports C++11 unordered_map - yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C++11 unordered_map passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
message(STATUS "Checking if compiler supports C++11 unordered_map - no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C++11 unordered_map failed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
endif()
endif()
function(cm_check_cxx_feature name)
string(TOUPPER ${name} FEATURE)
if(NOT DEFINED CMake_HAVE_CXX_${FEATURE})
message(STATUS "Checking if compiler supports C++ ${name}")
try_compile(CMake_HAVE_CXX_${FEATURE}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_LIST_DIR}/cm_cxx_${name}.cxx
CMAKE_FLAGS -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
OUTPUT_VARIABLE OUTPUT
)
# If using the feature causes warnings, treat it as broken/unavailable.
if(OUTPUT MATCHES "warning")
set(CMake_HAVE_CXX_${FEATURE} OFF CACHE INTERNAL "TRY_COMPILE" FORCE)
endif()
if(CMake_HAVE_CXX_${FEATURE})
message(STATUS "Checking if compiler supports C++ ${name} - yes")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Determining if compiler supports C++ ${name} passed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
else()
message(STATUS "Checking if compiler supports C++ ${name} - no")
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Determining if compiler supports C++ ${name} failed with the following output:\n"
"${OUTPUT}\n"
"\n"
)
endif()