Skip to content

Clang tidy support for cpp #3722

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
WarningsAsErrors: "*"
UseColor: true
HeaderFilterRegex: '.*'
ExtraArgsBefore:
- '-Wno-unknown-warning-option'
Checks: >
-*,
performance*
58 changes: 58 additions & 0 deletions .github/workflows/clang-tidy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: clang-tidy

on:
schedule:
# daily at 1am
- cron: "0 1 * * *"
pull_request:
branches:
- main
push:
branches:
- "**"
tags:
- "v*"
merge_group:
branches:
- main
workflow_dispatch:

jobs:
clang-tidy:
runs-on: ubuntu-latest
container: "ghcr.io/fenics/test-env:current-openmpi"
env:
PETSC_ARCH: linux-gnu-real64-32
OMPI_ALLOW_RUN_AS_ROOT: 1
OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1
PRTE_MCA_rmaps_default_mapping_policy: :oversubscribe
steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
apt-get update
apt-get install -y clang-tidy

- name: Load environment variables
run: cat .github/workflows/fenicsx-refs.env >> $GITHUB_ENV

- name: Install FEniCS Python components (default branches/tags)
if: github.event_name != 'workflow_dispatch'
run: |
pip install git+https://github.com/FEniCS/ufl.git@${{ env.ufl_ref }}
pip install git+https://github.com/FEniCS/basix.git@${{ env.basix_ref }}
pip install git+https://github.com/FEniCS/ffcx.git@${{ env.ffcx_ref }}

- name: Install FEniCS Python components
if: github.event_name == 'workflow_dispatch'
run: |
pip install git+https://github.com/FEniCS/ufl.git@${{ env.ufl_ref }}
pip install git+https://github.com/FEniCS/basix.git@${{ env.basix_ref }}
pip install git+https://github.com/FEniCS/ffcx.git@${{ env.ffcx_ref }}

- name: Configure, build and install C++ library
run: |
cmake -G Ninja -DCMAKE_BUILD_TYPE=Developer -DDOLFINX_ENABLE_ADIOS2=true -DDOLFINX_ENABLE_KAHIP=true -DDOLFINX_ENABLE_PARMETIS=false -DDOLFINX_ENABLE_PETSC=true -DDOLFINX_ENABLE_SCOTCH=true -DDOLFINX_ENABLE_SLEPC=true -DENABLE_CLANG_TIDY=ON -B build -S cpp/
cmake --build build
cmake --install build
4 changes: 4 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ add_feature_info(
"Ask Python FFCx module where to find ufcx.h header using MODULE mode. Otherwise use CONFIG mode."
)

# clang-tidy
option(ENABLE_CLANG_TIDY "Run clang-tidy while building" OFF)
add_feature_info(ENABLE_CLANG_TIDY ENABLE_CLANG_TIDY "Run clang-tidy while building")

# ------------------------------------------------------------------------------
# Enable or disable optional packages

Expand Down
5 changes: 5 additions & 0 deletions cpp/dolfinx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ set_target_properties(
SOVERSION ${DOLFINX_VERSION_MAJOR}.${DOLFINX_VERSION_MINOR}
)

if(ENABLE_CLANG_TIDY)
find_program(CLANG_TIDY NAMES clang-tidy REQUIRED)
set_target_properties(dolfinx PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY};--config-file=${CMAKE_CURRENT_SOURCE_DIR}/../../.clang-tidy")
endif()

# Add git revision flag to the one affected file
set_source_files_properties(
common/defines.cpp
Expand Down
1 change: 1 addition & 0 deletions cpp/dolfinx/common/IndexMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,7 @@ graph::AdjacencyList<int> IndexMap::index_to_dest_ranks(int tag) const
// Build list of (ghost index, ghost position) pairs for indices
// ghosted by this rank, and sort
std::vector<std::pair<std::int64_t, std::int32_t>> idx_to_pos;
idx_to_pos.reserve(2 * _ghosts.size());
for (auto idx : _ghosts)
idx_to_pos.push_back({idx, idx_to_pos.size()});
std::ranges::sort(idx_to_pos);
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/common/MPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void dolfinx::MPI::check_error(MPI_Comm comm, int code)
std::string error_string(MPI_MAX_ERROR_STRING, ' ');
MPI_Error_string(code, error_string.data(), &len);
error_string.resize(len);
std::cerr << error_string << std::endl;
std::cerr << error_string << '\n';
MPI_Abort(comm, code);
std::abort();
}
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/common/MPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
namespace dolfinx::MPI
{
/// MPI communication tags
enum class tag : int
enum class tag : std::uint16_t
{
consensus_pcx = 1200,
consensus_pex = 1201,
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/common/Scatterer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Scatterer
using allocator_type = Allocator;

/// Types of MPI communication pattern used by the Scatterer.
enum class type
enum class type : std::uint8_t
{
neighbor, // use MPI neighborhood collectives
p2p // use MPI Isend/Irecv for communication
Expand Down
10 changes: 5 additions & 5 deletions cpp/dolfinx/common/Table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ using namespace dolfinx;

//-----------------------------------------------------------------------------
Table::Table(std::string title, bool right_justify)
: name(title), _right_justify(right_justify)
: name(std::move(title)), _right_justify(right_justify)
{
// Do nothing
}
//-----------------------------------------------------------------------------
void Table::set(std::string row, std::string col,
void Table::set(const std::string& row, const std::string& col,
std::variant<std::string, int, double> value)
{
// Add row
Expand All @@ -49,11 +49,11 @@ void Table::set(std::string row, std::string col,

// Store value
std::pair<std::string, std::string> key(row, col);
_values[key] = value;
_values[key] = std::move(value);
}
//-----------------------------------------------------------------------------
std::variant<std::string, int, double> Table::get(std::string row,
std::string col) const
std::variant<std::string, int, double> Table::get(const std::string& row,
const std::string& col) const
{
std::pair<std::string, std::string> key(row, col);
auto it = _values.find(key);
Expand Down
9 changes: 5 additions & 4 deletions cpp/dolfinx/common/Table.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#pragma once

#include <cstdint>
#include <map>
#include <mpi.h>
#include <string>
Expand All @@ -29,7 +30,7 @@ class Table
public:
/// Types of MPI reduction available for Table, to get the max, min or
/// average values over an MPI_Comm
enum class Reduction
enum class Reduction : std::uint8_t
{
average,
max,
Expand Down Expand Up @@ -58,15 +59,15 @@ class Table
/// @param[in] row Row name
/// @param[in] col Column name
/// @param[in] value The value to set
void set(std::string row, std::string col,
void set(const std::string& row, const std::string& col,
std::variant<std::string, int, double> value);

/// Get value of table entry
/// @param[in] row Row name
/// @param[in] col Column name
/// @returns Returns the entry for requested row and columns
std::variant<std::string, int, double> get(std::string row,
std::string col) const;
std::variant<std::string, int, double> get(const std::string& row,
const std::string& col) const;

/// Do MPI reduction on Table
/// @param[in] comm MPI communicator
Expand Down
6 changes: 3 additions & 3 deletions cpp/dolfinx/common/TimeLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ TimeLogger& TimeLogger::instance()

//-----------------------------------------------------------------------------
void TimeLogger::register_timing(
std::string task, std::chrono::duration<double, std::ratio<1>> time)
const std::string& task, std::chrono::duration<double, std::ratio<1>> time)
{
// Print a message
std::string line
Expand All @@ -47,7 +47,7 @@ void TimeLogger::list_timings(MPI_Comm comm, Table::Reduction reduction) const

// Print just on rank 0
if (dolfinx::MPI::rank(comm) == 0)
std::cout << str << std::endl;
std::cout << str << '\n';
}
//-----------------------------------------------------------------------------
Table TimeLogger::timing_table() const
Expand All @@ -67,7 +67,7 @@ Table TimeLogger::timing_table() const
}
//-----------------------------------------------------------------------------
std::pair<int, std::chrono::duration<double, std::ratio<1>>>
TimeLogger::timing(std::string task) const
TimeLogger::timing(const std::string& task) const
{
// Find timing
auto it = _timings.find(task);
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/common/TimeLogger.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class TimeLogger
static TimeLogger& instance();

/// Register timing (for later summary)
void register_timing(std::string task,
void register_timing(const std::string& task,
std::chrono::duration<double, std::ratio<1>> wall);

/// Return a summary of timings and tasks in a Table
Expand All @@ -44,7 +44,7 @@ class TimeLogger
/// @param[in] task The task name to retrieve the timing for
/// @return Values (count, total wall time) for given task.
std::pair<int, std::chrono::duration<double, std::ratio<1>>>
timing(std::string task) const;
timing(const std::string& task) const;

/// @brief Logged elapsed times.
/// @return Elapsed [task id: (count, total wall time)].
Expand Down
4 changes: 3 additions & 1 deletion cpp/dolfinx/common/Timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class Timer
/// @param[in] task Name used to registered the elapsed time in the
/// logger. If no name is set, the elapsed time is not registered in
/// the logger.
Timer(std::optional<std::string> task = std::nullopt) : _task(task) {}
Timer(std::optional<std::string> task = std::nullopt) : _task(std::move(task))
{
}

/// If timer is still running, it is stopped. Elapsed time is
/// registered in the logger.
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/common/timing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ void dolfinx::list_timings(MPI_Comm comm, Table::Reduction reduction)
}
//-----------------------------------------------------------------------------
std::pair<int, std::chrono::duration<double, std::ratio<1>>>
dolfinx::timing(std::string task)
dolfinx::timing(const std::string& task)
{
return dolfinx::common::TimeLogger::instance().timing(task);
}
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/common/timing.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void list_timings(MPI_Comm comm,
/// @param[in] task Name of a task
/// @return The (count, total wall time) for the task.
std::pair<int, std::chrono::duration<double, std::ratio<1>>>
timing(std::string task);
timing(const std::string& task);

/// @brief Logged elapsed times.
/// @return Elapsed [task id: (count, total wall time)].
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/fem/CoordinateElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using namespace dolfinx::fem;
template <std::floating_point T>
CoordinateElement<T>::CoordinateElement(
std::shared_ptr<const basix::FiniteElement<T>> element)
: _element(element)
: _element(std::move(element))
{
int degree = _element->degree();
mesh::CellType cell = this->cell_shape();
Expand Down
3 changes: 3 additions & 0 deletions cpp/dolfinx/fem/DirichletBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ get_remote_dofs(MPI_Comm comm, const common::IndexMap& map, int bs_map,
// NOTE: Should we use map here or just one vector with ghosts and
// std::distance?
std::vector<std::pair<std::int64_t, std::int32_t>> global_local_ghosts;
global_local_ghosts.reserve(ghosts.size());
const std::int32_t local_size = range[1] - range[0];
for (std::size_t i = 0; i < ghosts.size(); ++i)
global_local_ghosts.emplace_back(ghosts[i], i + local_size);
Expand Down Expand Up @@ -194,6 +195,7 @@ std::vector<std::int32_t> fem::locate_dofs_topological(
// entity_dim
const int num_cell_entities = mesh::cell_num_entities(cell_type, dim);
std::vector<std::vector<int>> entity_dofs;
entity_dofs.reserve(num_cell_entities);
for (int i = 0; i < num_cell_entities; ++i)
{
entity_dofs.push_back(
Expand Down Expand Up @@ -310,6 +312,7 @@ std::array<std::vector<std::int32_t>, 2> fem::locate_dofs_topological(
// Build vector of local dofs for each cell entity
const int num_cell_entities = mesh::cell_num_entities(cell_type, dim);
std::vector<std::vector<int>> entity_dofs;
entity_dofs.reserve(num_cell_entities);
for (int i = 0; i < num_cell_entities; ++i)
{
entity_dofs.push_back(
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/fem/DofMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class DofMap
std::vector<std::int32_t>>
DofMap(E&& element, std::shared_ptr<const common::IndexMap> index_map,
int index_map_bs, U&& dofmap, int bs)
: index_map(index_map), _index_map_bs(index_map_bs),
: index_map(std::move(index_map)), _index_map_bs(index_map_bs),
_element_dof_layout(std::forward<E>(element)),
_dofmap(std::forward<U>(dofmap)), _bs(bs),
_shape1(_element_dof_layout.num_dofs()
Expand Down
3 changes: 2 additions & 1 deletion cpp/dolfinx/fem/ElementDofLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
#pragma once

#include <array>
#include <cstdint>
#include <span>
#include <vector>

namespace dolfinx::mesh
{
enum class CellType;
enum class CellType : std::int8_t;
}

namespace dolfinx::fem
Expand Down
6 changes: 3 additions & 3 deletions cpp/dolfinx/fem/FiniteElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _build_element_list(std::vector<BasixElementData<T>> elements)
{
std::vector<std::shared_ptr<const FiniteElement<T>>> _e;
std::ranges::transform(elements, std::back_inserter(_e),
[](auto data)
[](const auto& data)
{
auto& [e, bs, symm] = data;
return std::make_shared<fem::FiniteElement<T>>(e, bs,
Expand Down Expand Up @@ -110,7 +110,7 @@ int _compute_block_size(std::optional<std::vector<std::size_t>> value_shape,
template <std::floating_point T>
FiniteElement<T>::FiniteElement(
const basix::FiniteElement<T>& element,
std::optional<std::vector<std::size_t>> value_shape, bool symmetric)
const std::optional<std::vector<std::size_t>>& value_shape, bool symmetric)
: _value_shape(value_shape.value_or(element.value_shape())),
_bs(_compute_block_size(value_shape, symmetric)),
_cell_type(mesh::cell_type_from_basix_type(element.cell_type())),
Expand Down Expand Up @@ -161,7 +161,7 @@ FiniteElement<T>::FiniteElement(
//-----------------------------------------------------------------------------
template <std::floating_point T>
FiniteElement<T>::FiniteElement(std::vector<BasixElementData<T>> elements)
: FiniteElement(_build_element_list(elements))
: FiniteElement(_build_element_list(std::move(elements)))
{
}
//-----------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/fem/FiniteElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
namespace dolfinx::fem
{
/// DOF transformation type
enum class doftransform
enum class doftransform : std::uint8_t
{
standard = 0, ///< Standard
transpose = 1, ///< Transpose
Expand Down Expand Up @@ -68,7 +68,7 @@ class FiniteElement
/// @param[in] symmetric Is the element a symmetric tensor? Should
/// only set for 2nd-order tensor blocked elements.
FiniteElement(const basix::FiniteElement<geometry_type>& element,
std::optional<std::vector<std::size_t>> value_shape
const std::optional<std::vector<std::size_t>>& value_shape
= std::nullopt,
bool symmetric = false);

Expand Down
6 changes: 3 additions & 3 deletions cpp/dolfinx/fem/FunctionSpace.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FunctionSpace
FunctionSpace(std::shared_ptr<const mesh::Mesh<geometry_type>> mesh,
std::shared_ptr<const FiniteElement<geometry_type>> element,
std::shared_ptr<const DofMap> dofmap)
: _mesh(mesh), _elements{element}, _dofmaps{dofmap},
: _mesh(mesh), _elements{element}, _dofmaps{std::move(dofmap)},
_id(boost::uuids::random_generator()()), _root_space_id(_id)
{
// Do nothing
Expand All @@ -62,7 +62,7 @@ class FunctionSpace
std::shared_ptr<const mesh::Mesh<geometry_type>> mesh,
std::vector<std::shared_ptr<const FiniteElement<geometry_type>>> elements,
std::vector<std::shared_ptr<const DofMap>> dofmaps)
: _mesh(mesh), _elements(elements), _dofmaps(dofmaps),
: _mesh(mesh), _elements(elements), _dofmaps(std::move(dofmaps)),
_id(boost::uuids::random_generator()()), _root_space_id(_id)
{
std::vector<mesh::CellType> cell_types = mesh->topology()->cell_types();
Expand All @@ -72,7 +72,7 @@ class FunctionSpace
throw std::runtime_error(
"Number of elements must match number of cell types");
}
if (dofmaps.size() != num_cell_types)
if (_dofmaps.size() != num_cell_types)
{
throw std::runtime_error(
"Number of dofmaps must match number of cell types");
Expand Down
Loading
Loading