src/ClazyContext.cpp (94 lines of code) (raw):
/*
SPDX-FileCopyrightText: 2017 Sergio Martins <smartins@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "ClazyContext.h"
#include "AccessSpecifierManager.h"
#include "FixItExporter.h"
#include "PreProcessorVisitor.h"
#include "checkmanager.h"
#include <clang/AST/ParentMap.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Lex/PreprocessorOptions.h>
#include <clang/Rewrite/Frontend/FixItRewriter.h>
#include <llvm/Support/Regex.h>
#include <stdlib.h>
using namespace clang;
ClazyContext::ClazyContext(const clang::CompilerInstance &compiler,
const std::string &headerFilter,
const std::string &ignoreDirs,
std::string exportFixesFilename,
const std::vector<std::string> &translationUnitPaths,
ClazyOptions opts)
: ci(compiler)
, astContext(ci.getASTContext())
, sm(ci.getSourceManager())
, m_noWerror(getenv("CLAZY_NO_WERROR") != nullptr) // Allows user to make clazy ignore -Werror
, m_checksPromotedToErrors(CheckManager::instance()->checksAsErrors())
, options(opts)
, extraOptions(clazy::splitString(getenv("CLAZY_EXTRA_OPTIONS"), ','))
, m_translationUnitPaths(translationUnitPaths)
{
if (!headerFilter.empty()) {
headerFilterRegex = std::unique_ptr<llvm::Regex>(new llvm::Regex(headerFilter));
}
if (!ignoreDirs.empty()) {
ignoreDirsRegex = std::unique_ptr<llvm::Regex>(new llvm::Regex(ignoreDirs));
}
if (exportFixesEnabled()) {
if (exportFixesFilename.empty()) {
// Only clazy-standalone sets the filename by argument.
// clazy plugin sets it automatically here:
const auto fileEntry = sm.getFileEntryRefForID(sm.getMainFileID());
exportFixesFilename = fileEntry->getName().str() + ".clazy.yaml";
}
const bool isClazyStandalone = !translationUnitPaths.empty();
exporter = new FixItExporter(ci.getDiagnostics(), sm, ci.getLangOpts(), exportFixesFilename, isClazyStandalone);
}
if (options & ClazyOption_CLionMode)
clion::setCLionMode(true);
}
ClazyContext::~ClazyContext()
{
// delete preprocessorVisitor; // we don't own it
delete accessSpecifierManager;
delete parentMap;
static unsigned long count = 0;
count++;
if (exporter) {
// With clazy-standalone we use the same YAML file for all translation-units, so only
// write out the last one. With clazy-plugin there's a YAML file per translation unit.
const bool isClazyPlugin = m_translationUnitPaths.empty();
const bool isLast = count == m_translationUnitPaths.size();
if (isLast || isClazyPlugin) {
exporter->Export();
}
delete exporter;
}
preprocessorVisitor = nullptr;
accessSpecifierManager = nullptr;
parentMap = nullptr;
}
void ClazyContext::enableAccessSpecifierManager()
{
if (!accessSpecifierManager && !usingPreCompiledHeaders()) {
accessSpecifierManager = new AccessSpecifierManager(this);
}
}
void ClazyContext::enablePreprocessorVisitor()
{
if (!preprocessorVisitor && !usingPreCompiledHeaders()) {
preprocessorVisitor = new PreProcessorVisitor(ci);
}
}
void ClazyContext::enableVisitallTypeDefs()
{
// By default we only process decls from the .cpp file we're processing, not stuff included (for performance)
/// But we might need to process all typedefs, not only the ones in our current .cpp files
m_visitsAllTypeDefs = true;
}
bool ClazyContext::visitsAllTypedefs() const
{
return m_visitsAllTypeDefs;
}
bool ClazyContext::isQt() const
{
static const bool s_isQt = [this] {
for (const auto &s : ci.getPreprocessorOpts().Macros) {
if (s.first == "QT_CORE_LIB") {
return true;
}
}
return false;
}();
return s_isQt;
}