Skip to content

Commit

Permalink
Support Xcode 15 on ARM64 Mac
Browse files Browse the repository at this point in the history
  • Loading branch information
lianghuajian committed Aug 4, 2024
1 parent 6dcb3a9 commit c21efa2
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 41 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,10 @@ It looks for potential problems that aren't visible to compilers, for example:
* ...

For more information, visit https://oclint.org

Clone the repository branch that supports Xcode 15 on arm64 Mac
```
git clone -b support_xcode15 https://github.com/Lianghuajian/oclint.git oclint
cd oclint/oclint-scripts && ./make && cd ..
```
12 changes: 8 additions & 4 deletions oclint-core/cmake/OCLintConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ SET(CMAKE_BUILD_TYPE None)
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_FLAGS "-fcolor-diagnostics")
ENDIF()
SET(CMAKE_CXX_FLAGS "-std=c++14 ${CMAKE_CXX_LINKER_FLAGS} -fno-rtti -fPIC ${CMAKE_CXX_FLAGS}")
SET(CMAKE_CXX_FLAGS "-std=c++17 ${CMAKE_CXX_LINKER_FLAGS} -fno-rtti -fPIC ${CMAKE_CXX_FLAGS}")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINKER_FLAGS} -fno-rtti")

IF(APPLE)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden -mmacosx-version-min=12.5")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=12.5")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility-inlines-hidden")
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
ENDIF()

IF(OCLINT_BUILD_TYPE STREQUAL "Release")
Expand All @@ -22,6 +22,8 @@ ELSE()
SET(CMAKE_SHARED_LINKER_FLAGS "-g ${CMAKE_SHARED_LINKER_FLAGS}")
ENDIF()

find_package(Zstd REQUIRED)

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

SET(OCLINT_VERSION_RELEASE "24.0")
Expand Down Expand Up @@ -50,7 +52,8 @@ STRING(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" LLVM_VERSION_RELEASE ${LLVM_PAC

MESSAGE(STATUS "Found LLVM LLVM_PACKAGE_VERSION: ${LLVM_PACKAGE_VERSION} - LLVM_VERSION_RELEASE: ${LLVM_VERSION_RELEASE}")
MESSAGE(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
LLVM_MAP_COMPONENTS_TO_LIBNAMES(REQ_LLVM_LIBRARIES asmparser bitreader instrumentation mcparser option support frontendopenmp)

LLVM_MAP_COMPONENTS_TO_LIBNAMES(REQ_LLVM_LIBRARIES asmparser bitreader instrumentation mcparser option support frontendopenmp WindowsDriver)

SET(CLANG_LIBRARIES
clangToolingCore
Expand All @@ -59,6 +62,7 @@ SET(CLANG_LIBRARIES
clangDriver
clangSerialization
clangParse
clangSupport
clangSema
clangAnalysis
clangEdit
Expand Down
18 changes: 9 additions & 9 deletions oclint-driver/include/oclint/ConfigFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <vector>

#include <llvm/ADT/Optional.h>
// #include <llvm/ADT/Optional.h>
#include <llvm/Support/YAMLTraits.h>
#include <llvm/Support/MemoryBuffer.h>

Expand Down Expand Up @@ -52,14 +52,14 @@ class ConfigFile
const std::vector<llvm::StringRef> &disableRules() const;
const std::vector<llvm::StringRef> &rulePaths() const;
const std::vector<RuleConfigurationPair> &ruleConfigurations() const;
llvm::Optional<std::string> output() const;
llvm::Optional<std::string> reportType() const;
llvm::Optional<int> maxP1() const;
llvm::Optional<int> maxP2() const;
llvm::Optional<int> maxP3() const;
llvm::Optional<bool> clangChecker() const;
llvm::Optional<bool> allowDuplicatedViolations() const;
llvm::Optional<bool> enableGlobalAnalysis() const;
std::optional<std::string> output() const;
std::optional<std::string> reportType() const;
std::optional<int> maxP1() const;
std::optional<int> maxP2() const;
std::optional<int> maxP3() const;
std::optional<bool> clangChecker() const;
std::optional<bool> allowDuplicatedViolations() const;
std::optional<bool> enableGlobalAnalysis() const;

void mapping(llvm::yaml::IO& io);
};
Expand Down
3 changes: 2 additions & 1 deletion oclint-driver/lib/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ static clang::FrontendAction *getFrontendAction() {
}

void CompilerInstance::setupTarget() {
if ((getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) &&
// getLangOpts().OpenMPIsDevice is deparecated
if ((getLangOpts().CUDA) &&
!getFrontendOpts().AuxTriple.empty())
{
auto targetOptions = std::make_shared<clang::TargetOptions>();
Expand Down
32 changes: 16 additions & 16 deletions oclint-driver/lib/ConfigFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,66 +131,66 @@ const std::vector<RuleConfigurationPair> &oclint::option::ConfigFile::ruleConfig
return _ruleConfigurations;
}

static llvm::Optional<std::string> createOptionalString(const llvm::StringRef &value)
static std::optional<std::string> createOptionalString(const llvm::StringRef &value)
{
const std::string &string = value.str();
return string.size() ? llvm::Optional<std::string>(string) : llvm::Optional<std::string>();
return string.size() ? std::optional<std::string>(string) : std::optional<std::string>();
}

llvm::Optional<std::string> oclint::option::ConfigFile::output() const
std::optional<std::string> oclint::option::ConfigFile::output() const
{
return createOptionalString(_output);
}

llvm::Optional<std::string> oclint::option::ConfigFile::reportType() const
std::optional<std::string> oclint::option::ConfigFile::reportType() const
{
return createOptionalString(_reportType);
}

static llvm::Optional<int> createOptionalInt(int value)
static std::optional<int> createOptionalInt(int value)
{
return value == INT_MIN ? llvm::Optional<int>() : llvm::Optional<int>(value);
return value == INT_MIN ? std::optional<int>() : std::optional<int>(value);
}

llvm::Optional<int> oclint::option::ConfigFile::maxP1() const
std::optional<int> oclint::option::ConfigFile::maxP1() const
{
return createOptionalInt(_maxP1);
}

llvm::Optional<int> oclint::option::ConfigFile::maxP2() const
std::optional<int> oclint::option::ConfigFile::maxP2() const
{
return createOptionalInt(_maxP2);
}

llvm::Optional<int> oclint::option::ConfigFile::maxP3() const
std::optional<int> oclint::option::ConfigFile::maxP3() const
{
return createOptionalInt(_maxP3);
}

static llvm::Optional<bool> createOptionalBool(const TriState value)
static std::optional<bool> createOptionalBool(const TriState value)
{
switch (value)
{
case FALSE:
return llvm::Optional<bool>(false);
return std::optional<bool>(false);
case TRUE:
return llvm::Optional<bool>(true);
return std::optional<bool>(true);
case UNDEFINED:
return llvm::Optional<bool>();
return std::optional<bool>();
}
}

llvm::Optional<bool> oclint::option::ConfigFile::clangChecker() const
std::optional<bool> oclint::option::ConfigFile::clangChecker() const
{
return createOptionalBool(_clangChecker);
}

llvm::Optional<bool> oclint::option::ConfigFile::allowDuplicatedViolations() const
std::optional<bool> oclint::option::ConfigFile::allowDuplicatedViolations() const
{
return createOptionalBool(_allowDuplicatedViolations);
}

llvm::Optional<bool> oclint::option::ConfigFile::enableGlobalAnalysis() const
std::optional<bool> oclint::option::ConfigFile::enableGlobalAnalysis() const
{
return createOptionalBool(_enableGlobalAnalysis);
}
Expand Down
52 changes: 44 additions & 8 deletions oclint-driver/lib/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@

#include <unistd.h>

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>

#include <sstream>

#include <llvm/ADT/IntrusiveRefCntPtr.h>
Expand Down Expand Up @@ -135,8 +140,9 @@ static const llvm::opt::ArgStringList *getCC1Arguments(clang::driver::Compilatio

if (jobSize == 0)
{
LOG_VERBOSE("Error: compilation contains no job");
throw oclint::GenericException("compilation contains no job:\n" +
compilationJobsToString(jobList) + "\n");
compilationJobsToString(jobList) + "\n");
}

bool offloadCompilation = false;
Expand All @@ -155,24 +161,48 @@ static const llvm::opt::ArgStringList *getCC1Arguments(clang::driver::Compilatio
}
if (jobSize > 1 && !offloadCompilation)
{
LOG_VERBOSE("Error: compilation contains multiple jobs");
throw oclint::GenericException("compilation contains multiple jobs:\n" +
compilationJobsToString(jobList) + "\n");
compilationJobsToString(jobList) + "\n");
}

if (!clang::isa<clang::driver::Command>(*jobList.begin()))
{
LOG_VERBOSE("Error: compilation job does not contain correct command");
throw oclint::GenericException("compilation job does not contain correct command:\n" +
compilationJobsToString(jobList) + "\n");
compilationJobsToString(jobList) + "\n");
}

const clang::driver::Command &cmd = clang::cast<clang::driver::Command>(*jobList.begin());
if (llvm::StringRef(cmd.getCreator().getName()) != "clang")
{
LOG_VERBOSE("Error: expected a command for clang compiler");
throw oclint::GenericException("expected a command for clang compiler");
}

return &cmd.getArguments();
}
// Filter out arguments like -ivfsstatcache <path> to prevent "compilation contains multiple jobs" error.
// See issue https://github.com/facebook/infer/issues/1749
static void filterCommandLine(std::vector<std::string>& commandLine)
{
for (auto it = commandLine.begin(); it != commandLine.end();)
{
if (it->find("-ivfsstatcache") != std::string::npos)
{
it = commandLine.erase(it); // 删除 -ivfsstatcache
if (it != commandLine.end())
{
it = commandLine.erase(it); // 删除紧随其后的路径参数
}
}
else
{
++it; // 移动到下一个元素
}
}

}

static clang::CompilerInvocation *newCompilerInvocation(
std::string &mainExecutable,
Expand All @@ -181,6 +211,9 @@ static clang::CompilerInvocation *newCompilerInvocation(
{
assert(!commandLine.empty() && "Command line must not be empty!");
commandLine[0] = mainExecutable;
// Filter out arguments like -ivfsstatcache <path> to prevent "compilation contains multiple jobs" error.
// See issue https://github.com/facebook/infer/issues/1749
filterCommandLine(commandLine);

std::vector<const char*> argv;
int start = 0, end = commandLine.size();
Expand All @@ -201,37 +234,40 @@ static clang::CompilerInvocation *newCompilerInvocation(
argv.push_back("-D__OCLINT__");

// create diagnostic engine
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts =
new clang::DiagnosticOptions();
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts = new clang::DiagnosticOptions();
clang::DiagnosticsEngine diagnosticsEngine(
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs>(new clang::DiagnosticIDs()),
&*diagOpts,
new clang::DiagnosticConsumer());

// create driver
const char *const mainBinaryPath = argv[0];
const std::unique_ptr<clang::driver::Driver> driver(
newDriver(&diagnosticsEngine, mainBinaryPath));
const std::unique_ptr<clang::driver::Driver> driver(newDriver(&diagnosticsEngine, mainBinaryPath));
driver->setCheckInputsExist(false);

// create compilation invocation
const std::unique_ptr<clang::driver::Compilation> compilation(
driver->BuildCompilation(llvm::makeArrayRef(argv)));
auto cc1Args = getCC1Arguments(compilation.get());

return newInvocation(&diagnosticsEngine, *cc1Args);
}

static oclint::CompilerInstance *newCompilerInstance(clang::CompilerInvocation *compilerInvocation,
bool runClangChecker = false)
bool runClangChecker = false)
{

auto compilerInstance = new oclint::CompilerInstance();
auto invocation = std::make_shared<clang::CompilerInvocation>(*compilerInvocation);
compilerInstance->setInvocation(std::move(invocation));
compilerInstance->createDiagnostics(new DiagnosticDispatcher(runClangChecker));

if (!compilerInstance->hasDiagnostics())
{
LOG_VERBOSE("Error: cannot create compiler diagnostics");
throw oclint::GenericException("cannot create compiler diagnostics");
}

return compilerInstance;
}

Expand Down
6 changes: 3 additions & 3 deletions oclint-driver/lib/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ static std::string absoluteWorkingPath("");
static std::string executablePath("");

template <typename T>
void updateArgIfSet(llvm::cl::opt<T> &argValue, const llvm::Optional<T> &configValue)
void updateArgIfSet(llvm::cl::opt<T> &argValue, const std::optional<T> &configValue)
{
if (configValue.hasValue() && argValue.getNumOccurrences() == 0)
if (configValue.has_value() && argValue.getNumOccurrences() == 0)
{
argValue.setValue(configValue.getValue());
argValue.setValue(configValue.value());
}
}

Expand Down

0 comments on commit c21efa2

Please sign in to comment.