2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/mpi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyMPIModule
add_clang_library(clangTidyMPIModule STATIC
BufferDerefCheck.cpp
MPITidyModule.cpp
TypeMismatchCheck.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/objc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyObjCModule
add_clang_library(clangTidyObjCModule STATIC
AssertEquals.cpp
AvoidNSErrorInitCheck.cpp
DeallocInCategoryCheck.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/openmp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyOpenMPModule
add_clang_library(clangTidyOpenMPModule STATIC
ExceptionEscapeCheck.cpp
OpenMPTidyModule.cpp
UseDefaultNoneCheck.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/performance/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyPerformanceModule
add_clang_library(clangTidyPerformanceModule STATIC
AvoidEndlCheck.cpp
EnumSizeCheck.cpp
FasterStringFindCheck.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/plugin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
add_clang_library(clangTidyPlugin
add_clang_library(clangTidyPlugin STATIC
ClangTidyPlugin.cpp

LINK_LIBS
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/portability/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(LLVM_LINK_COMPONENTS
TargetParser
)

add_clang_library(clangTidyPortabilityModule
add_clang_library(clangTidyPortabilityModule STATIC
PortabilityTidyModule.cpp
RestrictSystemIncludesCheck.cpp
SIMDIntrinsicsCheck.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/readability/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyReadabilityModule
add_clang_library(clangTidyReadabilityModule STATIC
AvoidConstParamsInDecls.cpp
AvoidNestedConditionalOperatorCheck.cpp
AvoidReturnWithVoidValueCheck.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/tool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ set(LLVM_LINK_COMPONENTS
# Needed by LLVM's CMake checks because this file defines multiple targets.
set(LLVM_OPTIONAL_SOURCES ClangTidyMain.cpp ClangTidyToolMain.cpp)

add_clang_library(clangTidyMain
add_clang_library(clangTidyMain STATIC
ClangTidyMain.cpp

LINK_LIBS
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/utils/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyUtils
add_clang_library(clangTidyUtils STATIC
Aliasing.cpp
ASTUtils.cpp
BracesAroundStatement.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-tidy/zircon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS
Support
)

add_clang_library(clangTidyZirconModule
add_clang_library(clangTidyZirconModule STATIC
TemporaryObjectsCheck.cpp
ZirconTidyModule.cpp

Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ endif()
include_directories(BEFORE "${CMAKE_CURRENT_BINARY_DIR}/../clang-tidy")
include_directories(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/../include-cleaner/include")

add_clang_library(clangDaemon
add_clang_library(clangDaemon STATIC
AST.cpp
ASTSignals.cpp
ClangdLSPServer.cpp
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/ClangdServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,

CodeCompleteOpts.MainFileSignals = IP->Signals;
CodeCompleteOpts.AllScopes = Config::current().Completion.AllScopes;
CodeCompleteOpts.ArgumentLists = Config::current().Completion.ArgumentLists;
// FIXME(ibiryukov): even if Preamble is non-null, we may want to check
// both the old and the new version in case only one of them matches.
CodeCompleteResult Result = clangd::codeComplete(
Expand Down
26 changes: 18 additions & 8 deletions clang-tools-extra/clangd/CodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "AST.h"
#include "CodeCompletionStrings.h"
#include "Compiler.h"
#include "Config.h"
#include "ExpectedTypes.h"
#include "Feature.h"
#include "FileDistance.h"
Expand Down Expand Up @@ -350,8 +351,7 @@ struct CodeCompletionBuilder {
CodeCompletionContext::Kind ContextKind,
const CodeCompleteOptions &Opts,
bool IsUsingDeclaration, tok::TokenKind NextTokenKind)
: ASTCtx(ASTCtx),
EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets),
: ASTCtx(ASTCtx), ArgumentLists(Opts.ArgumentLists),
IsUsingDeclaration(IsUsingDeclaration), NextTokenKind(NextTokenKind) {
Completion.Deprecated = true; // cleared by any non-deprecated overload.
add(C, SemaCCS, ContextKind);
Expand Down Expand Up @@ -561,14 +561,23 @@ struct CodeCompletionBuilder {
}

std::string summarizeSnippet() const {
/// localize ArgumentLists tests for better readability
const bool None = ArgumentLists == Config::ArgumentListsPolicy::None;
const bool Open =
ArgumentLists == Config::ArgumentListsPolicy::OpenDelimiter;
const bool Delim = ArgumentLists == Config::ArgumentListsPolicy::Delimiters;
const bool Full =
ArgumentLists == Config::ArgumentListsPolicy::FullPlaceholders ||
(!None && !Open && !Delim); // <-- failsafe: Full is default

if (IsUsingDeclaration)
return "";
auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
if (!Snippet)
// All bundles are function calls.
// FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
// we need to complete 'forward<$1>($0)'.
return "($0)";
return None ? "" : (Open ? "(" : "($0)");

if (Snippet->empty())
return "";
Expand Down Expand Up @@ -607,7 +616,7 @@ struct CodeCompletionBuilder {
return "";
}
}
if (EnableFunctionArgSnippets)
if (Full)
return *Snippet;

// Replace argument snippets with a simplified pattern.
Expand All @@ -622,9 +631,9 @@ struct CodeCompletionBuilder {

bool EmptyArgs = llvm::StringRef(*Snippet).ends_with("()");
if (Snippet->front() == '<')
return EmptyArgs ? "<$1>()$0" : "<$1>($0)";
return None ? "" : (Open ? "<" : (EmptyArgs ? "<$1>()$0" : "<$1>($0)"));
if (Snippet->front() == '(')
return EmptyArgs ? "()" : "($0)";
return None ? "" : (Open ? "(" : (EmptyArgs ? "()" : "($0)"));
return *Snippet; // Not an arg snippet?
}
// 'CompletionItemKind::Interface' matches template type aliases.
Expand All @@ -638,7 +647,7 @@ struct CodeCompletionBuilder {
// e.g. Foo<${1:class}>.
if (llvm::StringRef(*Snippet).ends_with("<>"))
return "<>"; // can happen with defaulted template arguments.
return "<$0>";
return None ? "" : (Open ? "<" : "<$0>");
}
return *Snippet;
}
Expand All @@ -654,7 +663,8 @@ struct CodeCompletionBuilder {
ASTContext *ASTCtx;
CodeCompletion Completion;
llvm::SmallVector<BundledEntry, 1> Bundled;
bool EnableFunctionArgSnippets;
/// the way argument lists are handled.
Config::ArgumentListsPolicy ArgumentLists;
// No snippets will be generated for using declarations and when the function
// arguments are already present.
bool IsUsingDeclaration;
Expand Down
9 changes: 5 additions & 4 deletions clang-tools-extra/clangd/CodeComplete.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "ASTSignals.h"
#include "Compiler.h"
#include "Config.h"
#include "Protocol.h"
#include "Quality.h"
#include "index/Index.h"
Expand Down Expand Up @@ -101,17 +102,17 @@ struct CodeCompleteOptions {
/// '->' on member access etc.
bool IncludeFixIts = false;

/// Whether to generate snippets for function arguments on code-completion.
/// Needs snippets to be enabled as well.
bool EnableFunctionArgSnippets = true;

/// Whether to include index symbols that are not defined in the scopes
/// visible from the code completion point. This applies in contexts without
/// explicit scope qualifiers.
///
/// Such completions can insert scope qualifiers.
bool AllScopes = false;

/// The way argument list on calls '()' and generics '<>' are handled.
Config::ArgumentListsPolicy ArgumentLists =
Config::ArgumentListsPolicy::FullPlaceholders;

/// Whether to use the clang parser, or fallback to text-based completion
/// (using identifiers in the current file and symbol indexes).
enum CodeCompletionParse {
Expand Down
14 changes: 14 additions & 0 deletions clang-tools-extra/clangd/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,25 @@ struct Config {
std::vector<std::string> FullyQualifiedNamespaces;
} Style;

/// controls the completion options for argument lists.
enum class ArgumentListsPolicy {
/// nothing, no argument list and also NO Delimiters "()" or "<>".
None,
/// open, only opening delimiter "(" or "<".
OpenDelimiter,
/// empty pair of delimiters "()" or "<>".
Delimiters,
/// full name of both type and variable.
FullPlaceholders,
};

/// Configures code completion feature.
struct {
/// Whether code completion includes results that are not visible in current
/// scopes.
bool AllScopes = true;
/// controls the completion options for argument lists.
ArgumentListsPolicy ArgumentLists = ArgumentListsPolicy::FullPlaceholders;
} Completion;

/// Configures hover feature.
Expand Down
15 changes: 15 additions & 0 deletions clang-tools-extra/clangd/ConfigCompile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,21 @@ struct FragmentCompiler {
C.Completion.AllScopes = AllScopes;
});
}
if (F.ArgumentLists) {
if (auto Val =
compileEnum<Config::ArgumentListsPolicy>("ArgumentLists",
*F.ArgumentLists)
.map("None", Config::ArgumentListsPolicy::None)
.map("OpenDelimiter",
Config::ArgumentListsPolicy::OpenDelimiter)
.map("Delimiters", Config::ArgumentListsPolicy::Delimiters)
.map("FullPlaceholders",
Config::ArgumentListsPolicy::FullPlaceholders)
.value())
Out.Apply.push_back([Val](const Params &, Config &C) {
C.Completion.ArgumentLists = *Val;
});
}
}

void compile(Fragment::HoverBlock &&F) {
Expand Down
8 changes: 8 additions & 0 deletions clang-tools-extra/clangd/ConfigFragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIGFRAGMENT_H

#include "Config.h"
#include "ConfigProvider.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
Expand Down Expand Up @@ -308,6 +309,13 @@ struct Fragment {
/// Whether code completion should include suggestions from scopes that are
/// not visible. The required scope prefix will be inserted.
std::optional<Located<bool>> AllScopes;
/// How to present the argument list between '()' and '<>':
/// valid values are enum Config::ArgumentListsPolicy values:
/// None: Nothing at all
/// OpenDelimiter: only opening delimiter "(" or "<"
/// Delimiters: empty pair of delimiters "()" or "<>"
/// FullPlaceholders: full name of both type and parameter
std::optional<Located<std::string>> ArgumentLists;
};
CompletionBlock Completion;

Expand Down
4 changes: 4 additions & 0 deletions clang-tools-extra/clangd/ConfigYAML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ class Parser {
if (auto AllScopes = boolValue(N, "AllScopes"))
F.AllScopes = *AllScopes;
});
Dict.handle("ArgumentLists", [&](Node &N) {
if (auto ArgumentLists = scalarValue(N, "ArgumentLists"))
F.ArgumentLists = *ArgumentLists;
});
Dict.parse(N);
}

Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/FindSymbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
*Req.Limit *= 5;
}
TopN<ScoredSymbolInfo, ScoredSymbolGreater> Top(
Req.Limit ? *Req.Limit : std::numeric_limits<size_t>::max());
Req.Limit.value_or(std::numeric_limits<size_t>::max()));
FuzzyMatcher Filter(Req.Query);

Index->fuzzyFind(Req, [HintPath, &Top, &Filter, AnyScope = Req.AnyScope,
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/index/MemIndex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ bool MemIndex::fuzzyFind(
trace::Span Tracer("MemIndex fuzzyFind");

TopN<std::pair<float, const Symbol *>> Top(
Req.Limit ? *Req.Limit : std::numeric_limits<size_t>::max());
Req.Limit.value_or(std::numeric_limits<size_t>::max()));
FuzzyMatcher Filter(Req.Query);
bool More = false;
for (const auto &Pair : Index) {
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/index/dex/Dex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ bool Dex::fuzzyFind(const FuzzyFindRequest &Req,
return LHS.second > RHS.second;
};
TopN<IDAndScore, decltype(Compare)> Top(
Req.Limit ? *Req.Limit : std::numeric_limits<size_t>::max(), Compare);
Req.Limit.value_or(std::numeric_limits<size_t>::max()), Compare);
for (const auto &IDAndScore : IDAndScores) {
const DocID SymbolDocID = IDAndScore.first;
const auto *Sym = Symbols[SymbolDocID];
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/index/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ if (CLANGD_ENABLE_REMOTE)
# target-local?
add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1)

add_clang_library(clangdRemoteIndex
add_clang_library(clangdRemoteIndex STATIC
Client.cpp

LINK_LIBS
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
add_clang_library(clangdRemoteMarshalling
add_clang_library(clangdRemoteMarshalling STATIC
Marshalling.cpp

LINK_LIBS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
# When compiled without Remote Index support, the real implementation index
# client is not present. Users will get a notification about this when trying
# to connect to remote index server instance.
add_clang_library(clangdRemoteIndex
add_clang_library(clangdRemoteIndex STATIC
UnimplementedClient.cpp

LINK_LIBS
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/refactor/tweaks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_clang_library(clangDaemonTweaks OBJECT
RemoveUsingNamespace.cpp
ScopifyEnum.cpp
SpecialMembers.cpp
SwapBinaryOperands.cpp
SwapIfBranches.cpp

LINK_LIBS
Expand Down
217 changes: 217 additions & 0 deletions clang-tools-extra/clangd/refactor/tweaks/SwapBinaryOperands.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
//===--- SwapBinaryOperands.cpp ----------------------------------*- C++-*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "ParsedAST.h"
#include "Protocol.h"
#include "Selection.h"
#include "SourceCode.h"
#include "refactor/Tweak.h"
#include "support/Logger.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Tooling/Core/Replacement.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FormatVariadic.h"
#include <string>
#include <utility>

namespace clang {
namespace clangd {
namespace {
/// Check whether it makes logical sense to swap operands to an operator.
/// Assignment or member access operators are rarely swappable
/// while keeping the meaning intact, whereas comparison operators, mathematical
/// operators, etc. are often desired to be swappable for readability, avoiding
/// bugs by assigning to nullptr when comparison was desired, etc.
bool isOpSwappable(const BinaryOperatorKind Opcode) {
switch (Opcode) {
case BinaryOperatorKind::BO_Mul:
case BinaryOperatorKind::BO_Add:
case BinaryOperatorKind::BO_LT:
case BinaryOperatorKind::BO_GT:
case BinaryOperatorKind::BO_LE:
case BinaryOperatorKind::BO_GE:
case BinaryOperatorKind::BO_EQ:
case BinaryOperatorKind::BO_NE:
case BinaryOperatorKind::BO_And:
case BinaryOperatorKind::BO_Xor:
case BinaryOperatorKind::BO_Or:
case BinaryOperatorKind::BO_LAnd:
case BinaryOperatorKind::BO_LOr:
case BinaryOperatorKind::BO_Comma:
return true;
// Noncommutative operators:
case BinaryOperatorKind::BO_Div:
case BinaryOperatorKind::BO_Sub:
case BinaryOperatorKind::BO_Shl:
case BinaryOperatorKind::BO_Shr:
case BinaryOperatorKind::BO_Rem:
// <=> is noncommutative
case BinaryOperatorKind::BO_Cmp:
// Member access:
case BinaryOperatorKind::BO_PtrMemD:
case BinaryOperatorKind::BO_PtrMemI:
// Assignment:
case BinaryOperatorKind::BO_Assign:
case BinaryOperatorKind::BO_MulAssign:
case BinaryOperatorKind::BO_DivAssign:
case BinaryOperatorKind::BO_RemAssign:
case BinaryOperatorKind::BO_AddAssign:
case BinaryOperatorKind::BO_SubAssign:
case BinaryOperatorKind::BO_ShlAssign:
case BinaryOperatorKind::BO_ShrAssign:
case BinaryOperatorKind::BO_AndAssign:
case BinaryOperatorKind::BO_XorAssign:
case BinaryOperatorKind::BO_OrAssign:
return false;
}
return false;
}

/// Some operators are asymmetric and need to be flipped when swapping their
/// operands
/// @param[out] Opcode the opcode to potentially swap
/// If the opcode does not need to be swapped or is not swappable, does nothing
BinaryOperatorKind swapOperator(const BinaryOperatorKind Opcode) {
switch (Opcode) {
case BinaryOperatorKind::BO_LT:
return BinaryOperatorKind::BO_GT;

case BinaryOperatorKind::BO_GT:
return BinaryOperatorKind::BO_LT;

case BinaryOperatorKind::BO_LE:
return BinaryOperatorKind::BO_GE;

case BinaryOperatorKind::BO_GE:
return BinaryOperatorKind::BO_LE;

case BinaryOperatorKind::BO_Mul:
case BinaryOperatorKind::BO_Add:
case BinaryOperatorKind::BO_Cmp:
case BinaryOperatorKind::BO_EQ:
case BinaryOperatorKind::BO_NE:
case BinaryOperatorKind::BO_And:
case BinaryOperatorKind::BO_Xor:
case BinaryOperatorKind::BO_Or:
case BinaryOperatorKind::BO_LAnd:
case BinaryOperatorKind::BO_LOr:
case BinaryOperatorKind::BO_Comma:
case BinaryOperatorKind::BO_Div:
case BinaryOperatorKind::BO_Sub:
case BinaryOperatorKind::BO_Shl:
case BinaryOperatorKind::BO_Shr:
case BinaryOperatorKind::BO_Rem:
case BinaryOperatorKind::BO_PtrMemD:
case BinaryOperatorKind::BO_PtrMemI:
case BinaryOperatorKind::BO_Assign:
case BinaryOperatorKind::BO_MulAssign:
case BinaryOperatorKind::BO_DivAssign:
case BinaryOperatorKind::BO_RemAssign:
case BinaryOperatorKind::BO_AddAssign:
case BinaryOperatorKind::BO_SubAssign:
case BinaryOperatorKind::BO_ShlAssign:
case BinaryOperatorKind::BO_ShrAssign:
case BinaryOperatorKind::BO_AndAssign:
case BinaryOperatorKind::BO_XorAssign:
case BinaryOperatorKind::BO_OrAssign:
return Opcode;
}
llvm_unreachable("Unknown BinaryOperatorKind enum");
}

/// Swaps the operands to a binary operator
/// Before:
/// x != nullptr
/// ^ ^^^^^^^
/// After:
/// nullptr != x
class SwapBinaryOperands : public Tweak {
public:
const char *id() const final;

bool prepare(const Selection &Inputs) override;
Expected<Effect> apply(const Selection &Inputs) override;
std::string title() const override {
return llvm::formatv("Swap operands to {0}",
Op ? Op->getOpcodeStr() : "binary operator");
}
llvm::StringLiteral kind() const override {
return CodeAction::REFACTOR_KIND;
}
bool hidden() const override { return false; }

private:
const BinaryOperator *Op;
};

REGISTER_TWEAK(SwapBinaryOperands)

bool SwapBinaryOperands::prepare(const Selection &Inputs) {
for (const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor();
N && !Op; N = N->Parent) {
// Stop once we hit a block, e.g. a lambda in one of the operands.
// This makes sure that the selection point is in the 'scope' of the binary
// operator, not from somewhere inside a lambda for example
// (5 < [](){ ^return 1; })
if (llvm::isa_and_nonnull<CompoundStmt>(N->ASTNode.get<Stmt>()))
return false;
Op = dyn_cast_or_null<BinaryOperator>(N->ASTNode.get<Stmt>());
// If we hit upon a nonswappable binary operator, ignore and keep going
if (Op && !isOpSwappable(Op->getOpcode())) {
Op = nullptr;
}
}
return Op != nullptr;
}

Expected<Tweak::Effect> SwapBinaryOperands::apply(const Selection &Inputs) {
const auto &Ctx = Inputs.AST->getASTContext();
const auto &SrcMgr = Inputs.AST->getSourceManager();

const auto LHSRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(),
Op->getLHS()->getSourceRange());
if (!LHSRng)
return error(
"Could not obtain range of the 'lhs' of the operator. Macros?");
const auto RHSRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(),
Op->getRHS()->getSourceRange());
if (!RHSRng)
return error(
"Could not obtain range of the 'rhs' of the operator. Macros?");
const auto OpRng =
toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(), Op->getOperatorLoc());
if (!OpRng)
return error("Could not obtain range of the operator itself. Macros?");

const auto LHSCode = toSourceCode(SrcMgr, *LHSRng);
const auto RHSCode = toSourceCode(SrcMgr, *RHSRng);
const auto OperatorCode = toSourceCode(SrcMgr, *OpRng);

tooling::Replacements Result;
if (auto Err = Result.add(tooling::Replacement(
Ctx.getSourceManager(), LHSRng->getBegin(), LHSCode.size(), RHSCode)))
return std::move(Err);
if (auto Err = Result.add(tooling::Replacement(
Ctx.getSourceManager(), RHSRng->getBegin(), RHSCode.size(), LHSCode)))
return std::move(Err);
const auto SwappedOperator = swapOperator(Op->getOpcode());
if (auto Err = Result.add(tooling::Replacement(
Ctx.getSourceManager(), OpRng->getBegin(), OperatorCode.size(),
Op->getOpcodeStr(SwappedOperator))))
return std::move(Err);
return Effect::mainFileEdit(SrcMgr, std::move(Result));
}

} // namespace
} // namespace clangd
} // namespace clang
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB OR NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB)
list(APPEND CLANGD_ATOMIC_LIB "atomic")
endif()

add_clang_library(clangdSupport
add_clang_library(clangdSupport STATIC
Bracket.cpp
Cancellation.cpp
Context.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/tool/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Needed by LLVM's CMake checks because this file defines multiple targets.
set(LLVM_OPTIONAL_SOURCES ClangdToolMain.cpp)

add_clang_library(clangdMain
add_clang_library(clangdMain STATIC
ClangdMain.cpp
Check.cpp
)
Expand Down
18 changes: 13 additions & 5 deletions clang-tools-extra/clangd/tool/ClangdMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,13 @@ opt<std::string> FallbackStyle{
init(clang::format::DefaultFallbackStyle),
};

opt<bool> EnableFunctionArgSnippets{
opt<int> EnableFunctionArgSnippets{
"function-arg-placeholders",
cat(Features),
desc("When disabled, completions contain only parentheses for "
"function calls. When enabled, completions also contain "
desc("When disabled (0), completions contain only parentheses for "
"function calls. When enabled (1), completions also contain "
"placeholders for method parameters"),
init(CodeCompleteOptions().EnableFunctionArgSnippets),
init(-1),
};

opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
Expand Down Expand Up @@ -650,6 +650,7 @@ class FlagsConfigProvider : public config::Provider {
std::optional<Config::CDBSearchSpec> CDBSearch;
std::optional<Config::ExternalIndexSpec> IndexSpec;
std::optional<Config::BackgroundPolicy> BGPolicy;
std::optional<Config::ArgumentListsPolicy> ArgumentLists;

// If --compile-commands-dir arg was invoked, check value and override
// default path.
Expand Down Expand Up @@ -694,13 +695,21 @@ class FlagsConfigProvider : public config::Provider {
BGPolicy = Config::BackgroundPolicy::Skip;
}

if (EnableFunctionArgSnippets >= 0) {
ArgumentLists = EnableFunctionArgSnippets
? Config::ArgumentListsPolicy::FullPlaceholders
: Config::ArgumentListsPolicy::Delimiters;
}

Frag = [=](const config::Params &, Config &C) {
if (CDBSearch)
C.CompileFlags.CDBSearch = *CDBSearch;
if (IndexSpec)
C.Index.External = *IndexSpec;
if (BGPolicy)
C.Index.Background = *BGPolicy;
if (ArgumentLists)
C.Completion.ArgumentLists = *ArgumentLists;
if (AllScopesCompletion.getNumOccurrences())
C.Completion.AllScopes = AllScopesCompletion;

Expand Down Expand Up @@ -916,7 +925,6 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
Opts.CodeComplete.IncludeIndicator.Insert.clear();
Opts.CodeComplete.IncludeIndicator.NoInsert.clear();
}
Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
Opts.CodeComplete.RunParser = CodeCompletionParse;
Opts.CodeComplete.RankingModel = RankingModel;
// FIXME: If we're using C++20 modules, force the lookup process to load
Expand Down
1 change: 1 addition & 0 deletions clang-tools-extra/clangd/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ add_unittest(ClangdUnitTests ClangdTests
tweaks/ScopifyEnumTests.cpp
tweaks/ShowSelectionTreeTests.cpp
tweaks/SpecialMembersTests.cpp
tweaks/SwapBinaryOperandsTests.cpp
tweaks/SwapIfBranchesTests.cpp
tweaks/TweakTesting.cpp
tweaks/TweakTests.cpp
Expand Down
16 changes: 16 additions & 0 deletions clang-tools-extra/clangd/unittests/ClangdLSPServerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,22 @@ TEST_F(LSPTest, ClangTidyRename) {
EXPECT_EQ(Params, std::vector{llvm::json::Value(std::move(ExpectedEdit))});
}

TEST_F(LSPTest, ClangTidyCrash_Issue109367) {
// This test requires clang-tidy checks to be linked in.
if (!CLANGD_TIDY_CHECKS)
return;
Opts.ClangTidyProvider = [](tidy::ClangTidyOptions &ClangTidyOpts,
llvm::StringRef) {
ClangTidyOpts.Checks = {"-*,boost-use-ranges"};
};
// Check that registering the boost-use-ranges checker's matchers
// on two different threads does not cause a crash.
auto &Client = start();
Client.didOpen("a.cpp", "");
Client.didOpen("b.cpp", "");
Client.sync();
}

TEST_F(LSPTest, IncomingCalls) {
Annotations Code(R"cpp(
void calle^e(int);
Expand Down
25 changes: 23 additions & 2 deletions clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ClangdServer.h"
#include "CodeComplete.h"
#include "Compiler.h"
#include "Config.h"
#include "Feature.h"
#include "Matchers.h"
#include "Protocol.h"
Expand Down Expand Up @@ -2595,10 +2596,10 @@ TEST(SignatureHelpTest, DynamicIndexDocumentation) {
ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc"))));
}

TEST(CompletionTest, CompletionFunctionArgsDisabled) {
TEST(CompletionTest, ArgumentListsPolicy) {
CodeCompleteOptions Opts;
Opts.EnableSnippets = true;
Opts.EnableFunctionArgSnippets = false;
Opts.ArgumentLists = Config::ArgumentListsPolicy::Delimiters;

{
auto Results = completions(
Expand Down Expand Up @@ -2670,6 +2671,26 @@ TEST(CompletionTest, CompletionFunctionArgsDisabled) {
EXPECT_THAT(Results.Completions, UnorderedElementsAre(AllOf(
named("FOO"), snippetSuffix("($0)"))));
}
{
Opts.ArgumentLists = Config::ArgumentListsPolicy::None;
auto Results = completions(
R"cpp(
void xfoo(int x, int y);
void f() { xfo^ })cpp",
{}, Opts);
EXPECT_THAT(Results.Completions,
UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix(""))));
}
{
Opts.ArgumentLists = Config::ArgumentListsPolicy::OpenDelimiter;
auto Results = completions(
R"cpp(
void xfoo(int x, int y);
void f() { xfo^ })cpp",
{}, Opts);
EXPECT_THAT(Results.Completions,
UnorderedElementsAre(AllOf(named("xfoo"), snippetSuffix("("))));
}
}

TEST(CompletionTest, SuggestOverrides) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//===-- SwapBinaryOperandsTests.cpp -----------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "TweakTesting.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace clang {
namespace clangd {
namespace {

TWEAK_TEST(SwapBinaryOperands);

TEST_F(SwapBinaryOperandsTest, Test) {
Context = Function;
EXPECT_EQ(apply("int *p = nullptr; bool c = ^p == nullptr;"),
"int *p = nullptr; bool c = nullptr == p;");
EXPECT_EQ(apply("int *p = nullptr; bool c = p ^== nullptr;"),
"int *p = nullptr; bool c = nullptr == p;");
EXPECT_EQ(apply("int x = 3; bool c = ^x >= 5;"),
"int x = 3; bool c = 5 <= x;");
EXPECT_EQ(apply("int x = 3; bool c = x >^= 5;"),
"int x = 3; bool c = 5 <= x;");
EXPECT_EQ(apply("int x = 3; bool c = x >=^ 5;"),
"int x = 3; bool c = 5 <= x;");
EXPECT_EQ(apply("int x = 3; bool c = x >=^ 5;"),
"int x = 3; bool c = 5 <= x;");
EXPECT_EQ(apply("int f(); int x = 3; bool c = x >=^ f();"),
"int f(); int x = 3; bool c = f() <= x;");
EXPECT_EQ(apply(R"cpp(
int f();
#define F f
int x = 3; bool c = x >=^ F();
)cpp"),
R"cpp(
int f();
#define F f
int x = 3; bool c = F() <= x;
)cpp");
EXPECT_EQ(apply(R"cpp(
int f();
#define F f()
int x = 3; bool c = x >=^ F;
)cpp"),
R"cpp(
int f();
#define F f()
int x = 3; bool c = F <= x;
)cpp");
EXPECT_EQ(apply(R"cpp(
int f(bool);
#define F(v) f(v)
int x = 0;
bool c = F(x^ < 5);
)cpp"),
R"cpp(
int f(bool);
#define F(v) f(v)
int x = 0;
bool c = F(5 > x);
)cpp");
ExtraArgs = {"-std=c++20"};
Context = CodeContext::File;
EXPECT_UNAVAILABLE(R"cpp(
namespace std {
struct strong_ordering {
int val;
static const strong_ordering less;
static const strong_ordering equivalent;
static const strong_ordering equal;
static const strong_ordering greater;
};
inline constexpr strong_ordering strong_ordering::less {-1};
inline constexpr strong_ordering strong_ordering::equivalent {0};
inline constexpr strong_ordering strong_ordering::equal {0};
inline constexpr strong_ordering strong_ordering::greater {1};
};
#define F(v) v
int x = 0;
auto c = F(5^ <=> x);
)cpp");
}

} // namespace
} // namespace clangd
} // namespace clang
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/xpc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ set(LLVM_LINK_COMPONENTS
# Needed by LLVM's CMake checks because this file defines multiple targets.
set(LLVM_OPTIONAL_SOURCES Conversion.cpp XPCTransport.cpp)

add_clang_library(clangdXpcJsonConversions
add_clang_library(clangdXpcJsonConversions STATIC
Conversion.cpp
LINK_LIBS clangDaemon clangdSupport
)

add_clang_library(clangdXpcTransport
add_clang_library(clangdXpcTransport STATIC
XPCTransport.cpp
LINK_LIBS clangDaemon clangdSupport clangdXpcJsonConversions
DEPENDS ClangDriverOptions
Expand Down
12 changes: 12 additions & 0 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ Code completion
Code actions
^^^^^^^^^^^^

- Added `Swap operands` tweak for certain binary operators.

Signature help
^^^^^^^^^^^^^^

Expand All @@ -97,12 +99,22 @@ The improvements are...
Improvements to clang-tidy
--------------------------

- Improved :program:`clang-tidy`'s `--verify-config` flag by adding support for
the configuration options of the `Clang Static Analyzer Checks
<https://clang.llvm.org/docs/analyzer/checkers.html>`_.

- Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
happening on certain platforms when interrupting the script.

New checks
^^^^^^^^^^

- New :doc:`bugprone-bitwise-pointer-cast
<clang-tidy/checks/bugprone/bitwise-pointer-cast>` check.

Warns about code that tries to cast between pointers by means of
``std::bit_cast`` or ``memcpy``.

- New :doc:`bugprone-tagged-union-member-count
<clang-tidy/checks/bugprone/tagged-union-member-count>` check.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
.. title:: clang-tidy - bugprone-bitwise-pointer-cast

bugprone-bitwise-pointer-cast
=============================

Warns about code that tries to cast between pointers by means of
``std::bit_cast`` or ``memcpy``.

The motivation is that ``std::bit_cast`` is advertised as the safe alternative
to type punning via ``reinterpret_cast`` in modern C++. However, one should not
blindly replace ``reinterpret_cast`` with ``std::bit_cast``, as follows:

.. code-block:: c++

int x{};
-float y = *reinterpret_cast<float*>(&x);
+float y = *std::bit_cast<float*>(&x);

The drop-in replacement behaves exactly the same as ``reinterpret_cast``, and
Undefined Behavior is still invoked. ``std::bit_cast`` is copying the bytes of
the input pointer, not the pointee, into an output pointer of a different type,
which may violate the strict aliasing rules. However, simply looking at the
code, it looks "safe", because it uses ``std::bit_cast`` which is advertised as
safe.

The solution to safe type punning is to apply ``std::bit_cast`` on value types,
not on pointer types:

.. code-block:: c++

int x{};
float y = std::bit_cast<float>(x);

This way, the bytes of the input object are copied into the output object, which
is much safer. Do note that Undefined Behavior can still occur, if there is no
value of type ``To`` corresponding to the value representation produced.
Compilers may be able to optimize this copy and generate identical assembly to
the original ``reinterpret_cast`` version.

Code before C++20 may backport ``std::bit_cast`` by means of ``memcpy``, or
simply call ``memcpy`` directly, which is equally problematic. This is also
detected by this check:

.. code-block:: c++

int* x{};
float* y{};
std::memcpy(&y, &x, sizeof(x));

Alternatively, if a cast between pointers is truly wanted, ``reinterpret_cast``
should be used, to clearly convey the intent and enable warnings from compilers
and linters, which should be addressed accordingly.
1 change: 1 addition & 0 deletions clang-tools-extra/docs/clang-tidy/checks/list.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Clang-Tidy Checks
:doc:`bugprone-assert-side-effect <bugprone/assert-side-effect>`,
:doc:`bugprone-assignment-in-if-condition <bugprone/assignment-in-if-condition>`,
:doc:`bugprone-bad-signal-to-kill-thread <bugprone/bad-signal-to-kill-thread>`,
:doc:`bugprone-bitwise-pointer-cast <bugprone/bitwise-pointer-cast>`,
:doc:`bugprone-bool-pointer-implicit-conversion <bugprone/bool-pointer-implicit-conversion>`, "Yes"
:doc:`bugprone-branch-clone <bugprone/branch-clone>`,
:doc:`bugprone-casting-through-void <bugprone/casting-through-void>`,
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/docs/clang-tidy/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ An overview of all the command-line options:
FormatStyle - Same as '--format-style'.
HeaderFileExtensions - File extensions to consider to determine if a
given diagnostic is located in a header file.
HeaderFilterRegex - Same as '--header-filter-regex'.
HeaderFilterRegex - Same as '--header-filter'.
ImplementationFileExtensions - File extensions to consider to determine if a
given diagnostic is located in an
implementation file.
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/include-cleaner/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
set(LLVM_LINK_COMPONENTS Support)

add_clang_library(clangIncludeCleaner
add_clang_library(clangIncludeCleaner STATIC
Analysis.cpp
IncludeSpeller.cpp
FindHeaders.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// RUN: %check_clang_tidy -std=c++20 %s bugprone-bitwise-pointer-cast %t

void memcpy(void* to, void* dst, unsigned long long size)
{
// Dummy implementation for the purpose of the test
}

namespace std
{
template <typename To, typename From>
To bit_cast(From from)
{
// Dummy implementation for the purpose of the test
To to{};
return to;
}

using ::memcpy;
}

void pointer2pointer()
{
int x{};
float bad = *std::bit_cast<float*>(&x); // UB, but looks safe due to std::bit_cast
// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use 'std::bit_cast' to cast between pointers [bugprone-bitwise-pointer-cast]
float good = std::bit_cast<float>(x); // Well-defined

using IntPtr = int*;
using FloatPtr = float*;
IntPtr x2{};
float bad2 = *std::bit_cast<FloatPtr>(x2);
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: do not use 'std::bit_cast' to cast between pointers [bugprone-bitwise-pointer-cast]
}

void pointer2pointer_memcpy()
{
int x{};
int* px{};
float y{};
float* py{};

memcpy(&py, &px, sizeof(px));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast]
std::memcpy(&py, &px, sizeof(px));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast]

std::memcpy(&y, &x, sizeof(x));
}

// Pointer-integer conversions are allowed by this check
void int2pointer()
{
unsigned long long addr{};
float* p = std::bit_cast<float*>(addr);
std::memcpy(&p, &addr, sizeof(addr));
}

void pointer2int()
{
float* p{};
auto addr = std::bit_cast<unsigned long long>(p);
std::memcpy(&addr, &p, sizeof(p));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// RUN: %check_clang_tidy %s bugprone-bitwise-pointer-cast %t

void memcpy(void* to, void* dst, unsigned long long size)
{
// Dummy implementation for the purpose of the test
}

namespace std
{
using ::memcpy;
}

void pointer2pointer()
{
int x{};
int* px{};
float y{};
float* py{};

memcpy(&py, &px, sizeof(px));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast]
std::memcpy(&py, &px, sizeof(px));
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use 'memcpy' to cast between pointers [bugprone-bitwise-pointer-cast]

std::memcpy(&y, &x, sizeof(x));
}

// Pointer-integer conversions are allowed by this check
void int2pointer()
{
unsigned long long addr{};
float* p{};
std::memcpy(&p, &addr, sizeof(addr));
}

void pointer2int()
{
unsigned long long addr{};
float* p{};
std::memcpy(&addr, &p, sizeof(p));
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@
// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: check glob 'bugprone-arguments-*' doesn't match any known check [-verify-config]
// CHECK-VERIFY-BLOCK-BAD: command-line option '-config': warning: unknown check 'bugprone-assert-side-effects'; did you mean 'bugprone-assert-side-effect' [-verify-config]

// RUN: echo -e 'Checks: "-*,clang-analyzer-optin.cplusplus.UninitializedObject"\nCheckOptions:\n clang-analyzer-optin.cplusplus.UninitializedObject:Pedantic: true' > %T/MyClangTidyConfigCSA
// RUN: clang-tidy --verify-config --config-file=%T/MyClangTidyConfigCSA 2>&1 | FileCheck %s -check-prefix=CHECK-VERIFY-CSA-OK -implicit-check-not='{{warnings|error}}'
// CHECK-VERIFY-CSA-OK: No config errors detected.

// RUN: echo -e 'Checks: "-*,clang-analyzer-optin.cplusplus.UninitializedObject"\nCheckOptions:\n clang-analyzer-optin.cplusplus.UninitializedObject.Pedantic: true' > %T/MyClangTidyConfigCSABad
// RUN: not clang-tidy --verify-config --config-file=%T/MyClangTidyConfigCSABad 2>&1 | FileCheck %s -check-prefix=CHECK-VERIFY-CSA-BAD -implicit-check-not='{{warnings|error}}'
// CHECK-VERIFY-CSA-BAD: command-line option '-config': warning: unknown check option 'clang-analyzer-optin.cplusplus.UninitializedObject.Pedantic'; did you mean 'clang-analyzer-optin.cplusplus.UninitializedObject:Pedantic' [-verify-config]

44 changes: 20 additions & 24 deletions clang/CodeOwners.rst → clang/Maintainers.rst
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
=================
Clang Code Owners
Clang Maintainers
=================

This file is a list of the
`code owners <https://llvm.org/docs/DeveloperPolicy.html#code-owners>`_ for
`maintainers <https://llvm.org/docs/DeveloperPolicy.html#maintainers>`_ for
Clang.

.. contents::
:depth: 2
:local:

Current Code Owners
===================
The following people are the active code owners for the project. Please reach
Active Maintainers
==================
The following people are the active maintainers for the project. Please reach
out to them for code reviews, questions about their area of expertise, or other
assistance.

All parts of Clang not covered by someone else
----------------------------------------------
Lead Maintainer
---------------
| Aaron Ballman
| aaron\@aaronballman.com (email), aaron.ballman (Phabricator), AaronBallman (GitHub), AaronBallman (Discourse), aaronballman (Discord), AaronBallman (IRC)

Contained Components
--------------------
These code owners are responsible for particular high-level components within
These maintainers are responsible for particular high-level components within
Clang that are typically contained to one area of the compiler.

AST matchers
~~~~~~~~~~~~
| Manuel Klimek
| klimek\@google.com (email), klimek (Phabricator), r4nt (GitHub)
| Aaron Ballman
| aaron\@aaronballman.com (email), aaron.ballman (Phabricator), AaronBallman (GitHub), AaronBallman (Discourse), aaronballman (Discord), AaronBallman (IRC)

Clang LLVM IR generation
Expand Down Expand Up @@ -60,7 +60,7 @@ Analysis & CFG
Experimental new constant interpreter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Timm Bäder
| tbaeder\@redhat.com (email), tbaeder (Phabricator), tbaederr (GitHub), tbaeder (Discourse), tbaeder (Discord)
| tbaeder\@redhat.com (em), tbaeder (Phabricator), tbaederr (GitHub), tbaeder (Discourse), tbaeder (Discord)

Modules & serialization
Expand Down Expand Up @@ -125,14 +125,9 @@ Driver parts not covered by someone else

Tools
-----
These code owners are responsible for user-facing tools under the Clang
These maintainers are responsible for user-facing tools under the Clang
umbrella or components used to support such tools.

Tooling library
~~~~~~~~~~~~~~~
| Manuel Klimek
| klimek\@google.com (email), klimek (Phabricator), r4nt (GitHub)

clang-format
~~~~~~~~~~~~
Expand Down Expand Up @@ -255,19 +250,20 @@ SYCL conformance
| alexey.bader\@intel.com (email), bader (Phabricator), bader (GitHub)

Former Code Owners
==================
The following people have graciously spent time performing code ownership
Inactive Maintainers
====================
The following people have graciously spent time performing maintainership
responsibilities but are no longer active in that role. Thank you for all your
help with the success of the project!

Emeritus owners
---------------
Emeritus Lead Maintainers
-------------------------
| Doug Gregor (dgregor\@apple.com)
| Richard Smith (richard\@metafoo.co.uk)

Former component owners
-----------------------
Inactive component maintainers
------------------------------
| Chandler Carruth (chandlerc\@gmail.com, chandlerc\@google.com) -- CMake, library layering
| Devin Coughlin (dcoughlin\@apple.com) -- Clang static analyzer
| Manuel Klimek (klimek\@google.com (email), klimek (Phabricator), r4nt (GitHub)) -- Tooling, AST matchers
15 changes: 15 additions & 0 deletions clang/cmake/caches/hexagon-unknown-linux-musl-clang-cross.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is for the llvm+clang options that are specific to building
# a cross-toolchain targeting hexagon linux.
set(DEFAULT_SYSROOT "../target/hexagon-unknown-linux-musl/" CACHE STRING "")
set(CLANG_LINKS_TO_CREATE
hexagon-linux-musl-clang++
hexagon-linux-musl-clang
hexagon-unknown-linux-musl-clang++
hexagon-unknown-linux-musl-clang
hexagon-none-elf-clang++
hexagon-none-elf-clang
hexagon-unknown-none-elf-clang++
hexagon-unknown-none-elf-clang
CACHE STRING "")

set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
15 changes: 15 additions & 0 deletions clang/cmake/caches/hexagon-unknown-linux-musl-clang.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

set(LLVM_TARGETS_TO_BUILD "Hexagon" CACHE STRING "")
set(LLVM_DEFAULT_TARGET_TRIPLE "hexagon-unknown-linux-musl" CACHE STRING "")
set(CLANG_DEFAULT_CXX_STDLIB "libc++" CACHE STRING "")
set(CLANG_DEFAULT_OBJCOPY "llvm-objcopy" CACHE STRING "")
set(CLANG_DEFAULT_RTLIB "compiler-rt" CACHE STRING "")
set(CLANG_DEFAULT_UNWINDLIB "libunwind" CACHE STRING "")
set(CLANG_DEFAULT_LINKER "lld" CACHE STRING "")
set(LLVM_ENABLE_PROJECTS "clang;lld" CACHE STRING "")

set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
# Enabling toolchain-only causes problems when doing some of the
# subsequent builds, will need to investigate:
set(LLVM_INSTALL_TOOLCHAIN_ONLY OFF CACHE BOOL "")
2 changes: 1 addition & 1 deletion clang/docs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ if (LLVM_ENABLE_SPHINX)
"${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}"

COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${CMAKE_CURRENT_SOURCE_DIR}/../CodeOwners.rst"
"${CMAKE_CURRENT_SOURCE_DIR}/../Maintainers.rst"
"${CMAKE_CURRENT_BINARY_DIR}"
)

Expand Down
184 changes: 148 additions & 36 deletions clang/docs/ClangFormatStyleOptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ the configuration (without a prefix: ``Auto``).
.. _AlignArrayOfStructures:

**AlignArrayOfStructures** (``ArrayInitializerAlignmentStyle``) :versionbadge:`clang-format 13` :ref:`¶ <AlignArrayOfStructures>`
if not ``None``, when using initialization for an array of structs
If not ``None``, when using initialization for an array of structs
aligns the fields into columns.


Expand Down Expand Up @@ -307,11 +307,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -392,6 +393,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down Expand Up @@ -449,11 +465,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -534,6 +551,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down Expand Up @@ -591,11 +623,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -676,6 +709,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down Expand Up @@ -734,11 +782,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -819,6 +868,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down Expand Up @@ -996,11 +1060,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -1081,6 +1146,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down Expand Up @@ -1136,11 +1216,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -1221,6 +1302,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down Expand Up @@ -1276,11 +1372,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -1361,6 +1458,21 @@ the configuration (without a prefix: ``Auto``).
a &= 2;
bbb = 2;

* ``bool AlignFunctionDeclarations`` Only for ``AlignConsecutiveDeclarations``. Whether function declarations
are aligned.

.. code-block:: c++

true:
unsigned int f1(void);
void f2(void);
size_t f3(void);

false:
unsigned int f1(void);
void f2(void);
size_t f3(void);

* ``bool AlignFunctionPointers`` Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
aligned.

Expand Down
1 change: 0 additions & 1 deletion clang/docs/CodeOwners.rst

This file was deleted.

1 change: 1 addition & 0 deletions clang/docs/Maintainers.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. include:: ../Maintainers.rst
4 changes: 2 additions & 2 deletions clang/docs/Multilib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ For a more comprehensive example see
# If there is no multilib available for a particular set of flags, and the
# other multilibs are not adequate fallbacks, then you can define a variant
# record with a FatalError key in place of the Dir key.
- FatalError: this multilib collection has no hard-float ABI support
# record with an Error key in place of the Dir key.
- Error: this multilib collection has no hard-float ABI support
Flags: [--target=thumbv7m-none-eabi, -mfloat-abi=hard]
Expand Down
80 changes: 60 additions & 20 deletions clang/docs/RealtimeSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Introduction
============
RealtimeSanitizer (a.k.a. RTSan) is a real-time safety testing tool for C and C++
projects. RTSan can be used to detect real-time violations, i.e. calls to methods
that are not safe for use in functions with deterministic runtime requirements.
that are not safe for use in functions with deterministic run time requirements.
RTSan considers any function marked with the ``[[clang::nonblocking]]`` attribute
to be a real-time function. If RTSan detects a call to ``malloc``, ``free``,
``pthread_mutex_lock``, or anything else that could have a non-deterministic
Expand Down Expand Up @@ -58,31 +58,71 @@ code.
return 0;
}
# Compile and link
% clang++ -fsanitize=realtime -g example_realtime_violation.cpp
% clang++ -fsanitize=realtime example_realtime_violation.cpp
If a real-time safety violation is detected in a ``[[clang::nonblocking]]``
context, or any function invoked by that function, the program will exit with a
non-zero exit code.

.. code-block:: console
% clang++ -fsanitize=realtime -g example_realtime_violation.cpp
% clang++ -fsanitize=realtime example_realtime_violation.cpp
% ./a.out
Real-time violation: intercepted call to real-time unsafe function `malloc` in real-time context! Stack trace:
#0 0x000102893034 in __rtsan::PrintStackTrace() rtsan_stack.cpp:45
#1 0x000102892e64 in __rtsan::Context::ExpectNotRealtime(char const*) rtsan_context.cpp:78
#2 0x00010289397c in malloc rtsan_interceptors.cpp:286
#3 0x000195bd7bd0 in operator new(unsigned long)+0x1c (libc++abi.dylib:arm64+0x16bd0)
#4 0x5c7f00010230f07c (<unknown module>)
#5 0x00010230f058 in std::__1::__libcpp_allocate[abi:ue170006](unsigned long, unsigned long) new:324
#6 0x00010230effc in std::__1::allocator<float>::allocate[abi:ue170006](unsigned long) allocator.h:114
... snip ...
#10 0x00010230e4bc in std::__1::vector<float, std::__1::allocator<float>>::__append(unsigned long) vector:1162
#11 0x00010230dcdc in std::__1::vector<float, std::__1::allocator<float>>::resize(unsigned long) vector:1981
#12 0x00010230dc28 in violation() main.cpp:5
#13 0x00010230dd64 in main main.cpp:9
#14 0x0001958960dc (<unknown module>)
#15 0x2f557ffffffffffc (<unknown module>)
==76290==ERROR: RealtimeSanitizer: unsafe-library-call
Intercepted call to real-time unsafe function `malloc` in real-time context!
#0 0x000102a7b884 in malloc rtsan_interceptors.cpp:426
#1 0x00019c326bd0 in operator new(unsigned long)+0x1c (libc++abi.dylib:arm64+0x16bd0)
#2 0xa30d0001024f79a8 (<unknown module>)
#3 0x0001024f794c in std::__1::__libcpp_allocate[abi:ne200000](unsigned long, unsigned long)+0x44
#4 0x0001024f78c4 in std::__1::allocator<float>::allocate[abi:ne200000](unsigned long)+0x44
... snip ...
#9 0x0001024f6868 in std::__1::vector<float, std::__1::allocator<float>>::resize(unsigned long)+0x48
#10 0x0001024f67b4 in violation()+0x24
#11 0x0001024f68f0 in main+0x18 (a.out:arm64+0x1000028f0)
#12 0x00019bfe3150 (<unknown module>)
#13 0xed5efffffffffffc (<unknown module>)
Blocking functions
------------------

Calls to system library functions such as ``malloc`` are automatically caught by
RealtimeSanitizer. Real-time programmers may also write their own blocking
(real-time unsafe) functions that they wish RealtimeSanitizer to be aware of.
RealtimeSanitizer will raise an error at run time if any function attributed
with ``[[clang::blocking]]`` is called in a ``[[clang::nonblocking]]`` context.

.. code-block:: console
$ cat example_blocking_violation.cpp
#include <atomic>
#include <thread>
std::atomic<bool> has_permission{false};
int wait_for_permission() [[clang::blocking]] {
while (has_permission.load() == false)
std::this_thread::yield();
return 0;
}
int real_time_function() [[clang::nonblocking]] {
return wait_for_permission();
}
int main() {
return real_time_function();
}
$ clang++ -fsanitize=realtime example_blocking_violation.cpp && ./a.out
==76131==ERROR: RealtimeSanitizer: blocking-call
Call to blocking function `wait_for_permission()` in real-time context!
#0 0x0001000c3db0 in wait_for_permission()+0x10 (a.out:arm64+0x100003db0)
#1 0x0001000c3e3c in real_time_function()+0x10 (a.out:arm64+0x100003e3c)
#2 0x0001000c3e68 in main+0x10 (a.out:arm64+0x100003e68)
#3 0x00019bfe3150 (<unknown module>)
#4 0x5a27fffffffffffc (<unknown module>)
Run-time flags
--------------
Expand Down Expand Up @@ -159,7 +199,7 @@ Disabling

In some circumstances, you may want to suppress error reporting in a specific scope.

In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope where the ``ScopedDisabler`` object is instantiated, all sanitizer error reports are suppressed. This suppression applies to the current scope as well as all invoked functions, including any functions called transitively.
In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope where the ``ScopedDisabler`` object is instantiated, all sanitizer error reports are suppressed. This suppression applies to the current scope as well as all invoked functions, including any functions called transitively.

.. code-block:: c++

Expand All @@ -174,7 +214,7 @@ In C++, this is achieved via ``__rtsan::ScopedDisabler``. Within the scope wher

If RealtimeSanitizer is not enabled at compile time (i.e., the code is not compiled with the ``-fsanitize=realtime`` flag), the ``ScopedDisabler`` is compiled as a no-op.

In C, you can use the ``__rtsan_disable()`` and ``rtsan_enable()`` functions to manually disable and re-enable RealtimeSanitizer checks.
In C, you can use the ``__rtsan_disable()`` and ``rtsan_enable()`` functions to manually disable and re-enable RealtimeSanitizer checks.

.. code-block:: c++

Expand Down
11 changes: 11 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ Improvements to Clang's diagnostics

- Clang now emits a diagnostic note at the class declaration when the method definition does not match any declaration (#GH110638).

- Clang now omits warnings for extra parentheses in fold expressions with single expansion (#GH101863).

Improvements to Clang's time-trace
----------------------------------

Expand Down Expand Up @@ -471,6 +473,8 @@ Bug Fixes to C++ Support
- Fixed an issue deducing non-type template arguments of reference type. (#GH73460)
- Fixed an issue in constraint evaluation, where type constraints on the lambda expression
containing outer unexpanded parameters were not correctly expanded. (#GH101754)
- Fixes crashes with function template member specializations, and increases
conformance of explicit instantiation behaviour with MSVC. (#GH111266)
- Fixed a bug in constraint expression comparison where the ``sizeof...`` expression was not handled properly
in certain friend declarations. (#GH93099)

Expand Down Expand Up @@ -510,6 +514,10 @@ OpenACC Specific Changes
Target Specific Changes
-----------------------

- Clang now implements the Solaris-specific mangling of ``std::tm`` as
``tm``, same for ``std::div_t``, ``std::ldiv_t``, and
``std::lconv``, for Solaris ABI compatibility. (#GH33114)

AMDGPU Support
^^^^^^^^^^^^^^

Expand Down Expand Up @@ -616,6 +624,7 @@ clang-format

- Adds ``BreakBinaryOperations`` option.
- Adds ``TemplateNames`` option.
- Adds ``AlignFunctionDeclarations`` option to ``AlignConsecutiveDeclarations``.

libclang
--------
Expand All @@ -628,6 +637,8 @@ Static Analyzer
New features
^^^^^^^^^^^^

- Now CSA models `__builtin_*_overflow` functions. (#GH102602)

- MallocChecker now checks for ``ownership_returns(class, idx)`` and ``ownership_takes(class, idx)``
attributes with class names different from "malloc". Clang static analyzer now reports an error
if class of allocation and deallocation function mismatches.
Expand Down
2 changes: 1 addition & 1 deletion clang/docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ Design Documents
.. toctree::
:maxdepth: 1

CodeOwners
Maintainers
InternalsManual
DriverInternals
Multilib
Expand Down
68 changes: 56 additions & 12 deletions clang/include/clang/AST/APValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -314,51 +314,95 @@ class APValue {
DataType Data;

public:
/// Creates an empty APValue of type None.
APValue() : Kind(None) {}
/// Creates an integer APValue holding the given value.
explicit APValue(APSInt I) : Kind(None) {
MakeInt(); setInt(std::move(I));
}
/// Creates a float APValue holding the given value.
explicit APValue(APFloat F) : Kind(None) {
MakeFloat(); setFloat(std::move(F));
}
/// Creates a fixed-point APValue holding the given value.
explicit APValue(APFixedPoint FX) : Kind(None) {
MakeFixedPoint(std::move(FX));
}
/// Creates a vector APValue with \p N elements. The elements
/// are read from \p E.
explicit APValue(const APValue *E, unsigned N) : Kind(None) {
MakeVector(); setVector(E, N);
}
/// Creates an integer complex APValue with the given real and imaginary
/// values.
APValue(APSInt R, APSInt I) : Kind(None) {
MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
}
/// Creates a float complex APValue with the given real and imaginary values.
APValue(APFloat R, APFloat I) : Kind(None) {
MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
}
APValue(const APValue &RHS);
APValue(APValue &&RHS);
APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
/// Creates an lvalue APValue without an lvalue path.
/// \param Base The base of the lvalue.
/// \param Offset The offset of the lvalue.
/// \param IsNullPtr Whether this lvalue is a null pointer.
APValue(LValueBase Base, const CharUnits &Offset, NoLValuePath,
bool IsNullPtr = false)
: Kind(None) {
MakeLValue(); setLValue(B, O, N, IsNullPtr);
}
APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
bool OnePastTheEnd, bool IsNullPtr = false)
MakeLValue();
setLValue(Base, Offset, NoLValuePath{}, IsNullPtr);
}
/// Creates an lvalue APValue with an lvalue path.
/// \param Base The base of the lvalue.
/// \param Offset The offset of the lvalue.
/// \param Path The lvalue path.
/// \param OnePastTheEnd Whether this lvalue is one-past-the-end of the
/// subobject it points to.
/// \param IsNullPtr Whether this lvalue is a null pointer.
APValue(LValueBase Base, const CharUnits &Offset,
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
bool IsNullPtr = false)
: Kind(None) {
MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
}
MakeLValue();
setLValue(Base, Offset, Path, OnePastTheEnd, IsNullPtr);
}
/// Creates a new array APValue.
/// \param UninitArray Marker. Pass an empty UninitArray.
/// \param InitElts Number of elements you're going to initialize in the
/// array.
/// \param Size Full size of the array.
APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(None) {
MakeArray(InitElts, Size);
}
APValue(UninitStruct, unsigned B, unsigned M) : Kind(None) {
MakeStruct(B, M);
}
explicit APValue(const FieldDecl *D, const APValue &V = APValue())
/// Creates a new struct APValue.
/// \param UninitStruct Marker. Pass an empty UninitStruct.
/// \param NumBases Number of bases.
/// \param NumMembers Number of members.
APValue(UninitStruct, unsigned NumBases, unsigned NumMembers) : Kind(None) {
MakeStruct(NumBases, NumMembers);
}
/// Creates a new union APValue.
/// \param ActiveDecl The FieldDecl of the active union member.
/// \param ActiveValue The value of the active union member.
explicit APValue(const FieldDecl *ActiveDecl,
const APValue &ActiveValue = APValue())
: Kind(None) {
MakeUnion(); setUnion(D, V);
MakeUnion();
setUnion(ActiveDecl, ActiveValue);
}
/// Creates a new member pointer APValue.
/// \param Member Declaration of the member
/// \param IsDerivedMember Whether member is a derived one.
/// \param Path The path of the member.
APValue(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path) : Kind(None) {
MakeMemberPointer(Member, IsDerivedMember, Path);
}
/// Creates a new address label diff APValue.
/// \param LHSExpr The left-hand side of the difference.
/// \param RHSExpr The right-hand side of the difference.
APValue(const AddrLabelExpr* LHSExpr, const AddrLabelExpr* RHSExpr)
: Kind(None) {
MakeAddrLabelDiff(); setAddrLabelDiff(LHSExpr, RHSExpr);
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ComputeDependence.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class ObjCSubscriptRefExpr;
class ObjCIsaExpr;
class ObjCIndirectCopyRestoreExpr;
class ObjCMessageExpr;
class OpenACCAsteriskSizeExpr;

// The following functions are called from constructors of `Expr`, so they
// should not access anything beyond basic
Expand Down Expand Up @@ -203,6 +204,7 @@ ExprDependence computeDependence(ObjCSubscriptRefExpr *E);
ExprDependence computeDependence(ObjCIsaExpr *E);
ExprDependence computeDependence(ObjCIndirectCopyRestoreExpr *E);
ExprDependence computeDependence(ObjCMessageExpr *E);
ExprDependence computeDependence(OpenACCAsteriskSizeExpr *E);

} // namespace clang
#endif
44 changes: 44 additions & 0 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,41 @@ class PredefinedExpr final
}
};

/// This expression type represents an asterisk in an OpenACC Size-Expr, used in
/// the 'tile' and 'gang' clauses. It is of 'int' type, but should not be
/// evaluated.
class OpenACCAsteriskSizeExpr final : public Expr {
friend class ASTStmtReader;
SourceLocation AsteriskLoc;

OpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc, QualType IntTy)
: Expr(OpenACCAsteriskSizeExprClass, IntTy, VK_PRValue, OK_Ordinary),
AsteriskLoc(AsteriskLoc) {}

void setAsteriskLocation(SourceLocation Loc) { AsteriskLoc = Loc; }

public:
static OpenACCAsteriskSizeExpr *Create(const ASTContext &C,
SourceLocation Loc);
static OpenACCAsteriskSizeExpr *CreateEmpty(const ASTContext &C);

SourceLocation getBeginLoc() const { return AsteriskLoc; }
SourceLocation getEndLoc() const { return AsteriskLoc; }
SourceLocation getLocation() const { return AsteriskLoc; }

static bool classof(const Stmt *T) {
return T->getStmtClass() == OpenACCAsteriskSizeExprClass;
}
// Iterators
child_range children() {
return child_range(child_iterator(), child_iterator());
}

const_child_range children() const {
return const_child_range(const_child_iterator(), const_child_iterator());
}
};

// This represents a use of the __builtin_sycl_unique_stable_name, which takes a
// type-id, and at CodeGen time emits a unique string representation of the
// type in a way that permits us to properly encode information about the SYCL
Expand Down Expand Up @@ -2135,11 +2170,13 @@ class SYCLUniqueStableNameExpr final : public Expr {
class ParenExpr : public Expr {
SourceLocation L, R;
Stmt *Val;

public:
ParenExpr(SourceLocation l, SourceLocation r, Expr *val)
: Expr(ParenExprClass, val->getType(), val->getValueKind(),
val->getObjectKind()),
L(l), R(r), Val(val) {
ParenExprBits.ProducedByFoldExpansion = false;
setDependence(computeDependence(this));
}

Expand Down Expand Up @@ -2171,6 +2208,13 @@ class ParenExpr : public Expr {
const_child_range children() const {
return const_child_range(&Val, &Val + 1);
}

bool isProducedByFoldExpansion() const {
return ParenExprBits.ProducedByFoldExpansion != 0;
}
void setIsProducedByFoldExpansion(bool ProducedByFoldExpansion = true) {
ParenExprBits.ProducedByFoldExpansion = ProducedByFoldExpansion;
}
};

/// UnaryOperator - This represents the unary-expression's (except sizeof and
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/JSONNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ class JSONNodeDumper

void VisitDeclRefExpr(const DeclRefExpr *DRE);
void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *E);
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *E);
void VisitPredefinedExpr(const PredefinedExpr *PE);
void VisitUnaryOperator(const UnaryOperator *UO);
void VisitBinaryOperator(const BinaryOperator *BO);
Expand Down
29 changes: 29 additions & 0 deletions clang/include/clang/AST/OpenACCClause.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,35 @@ class OpenACCNumGangsClause final
}
};

class OpenACCTileClause final
: public OpenACCClauseWithExprs,
public llvm::TrailingObjects<OpenACCTileClause, Expr *> {
OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc,
ArrayRef<Expr *> SizeExprs, SourceLocation EndLoc)
: OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc,
EndLoc) {
std::uninitialized_copy(SizeExprs.begin(), SizeExprs.end(),
getTrailingObjects<Expr *>());
setExprs(MutableArrayRef(getTrailingObjects<Expr *>(), SizeExprs.size()));
}

public:
static bool classof(const OpenACCClause *C) {
return C->getClauseKind() == OpenACCClauseKind::Tile;
}
static OpenACCTileClause *Create(const ASTContext &C, SourceLocation BeginLoc,
SourceLocation LParenLoc,
ArrayRef<Expr *> SizeExprs,
SourceLocation EndLoc);
llvm::ArrayRef<Expr *> getSizeExprs() {
return OpenACCClauseWithExprs::getExprs();
}

llvm::ArrayRef<Expr *> getSizeExprs() const {
return OpenACCClauseWithExprs::getExprs();
}
};

/// Represents one of a handful of clauses that have a single integer
/// expression.
class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs {
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2867,6 +2867,7 @@ DEF_TRAVERSE_STMT(ParenListExpr, {})
DEF_TRAVERSE_STMT(SYCLUniqueStableNameExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
})
DEF_TRAVERSE_STMT(OpenACCAsteriskSizeExpr, {})
DEF_TRAVERSE_STMT(PredefinedExpr, {})
DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
Expand Down
13 changes: 13 additions & 0 deletions clang/include/clang/AST/Stmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,18 @@ class alignas(void *) Stmt {
unsigned Kind : 3;
};

class ParenExprBitfields {
friend class ASTStmtReader;
friend class ASTStmtWriter;
friend class ParenExpr;

LLVM_PREFERRED_TYPE(ExprBitfields)
unsigned : NumExprBits;

LLVM_PREFERRED_TYPE(bool)
unsigned ProducedByFoldExpansion : 1;
};

class StmtExprBitfields {
friend class ASTStmtReader;
friend class StmtExpr;
Expand Down Expand Up @@ -1241,6 +1253,7 @@ class alignas(void *) Stmt {
GenericSelectionExprBitfields GenericSelectionExprBits;
PseudoObjectExprBitfields PseudoObjectExprBits;
SourceLocExprBitfields SourceLocExprBits;
ParenExprBitfields ParenExprBits;

// GNU Extensions.
StmtExprBitfields StmtExprBits;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/AST/TextNodeDumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ class TextNodeDumper
void VisitHLSLOutArgExpr(const HLSLOutArgExpr *E);
void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S);
void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S);
void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S);
void VisitEmbedExpr(const EmbedExpr *S);
void VisitAtomicExpr(const AtomicExpr *AE);
};
Expand Down
12 changes: 12 additions & 0 deletions clang/include/clang/Basic/Builtins.td
Original file line number Diff line number Diff line change
Expand Up @@ -4739,6 +4739,12 @@ def HLSLClamp : LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}

def HLSLCross: LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_cross"];
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}

def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_dot"];
let Attributes = [NoThrow, Const];
Expand Down Expand Up @@ -4818,6 +4824,12 @@ def HLSLStep: LangBuiltin<"HLSL_LANG"> {
let Prototype = "void(...)";
}

def HLSLRadians : LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_elementwise_radians"];
let Attributes = [NoThrow, Const];
let Prototype = "void(...)";
}

// Builtins for XRay.
def XRayCustomEvent : Builtin {
let Spellings = ["__xray_customevent"];
Expand Down
29 changes: 18 additions & 11 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10510,8 +10510,8 @@ def err_first_argument_to_cwsc_pdtor_call : Error<
def err_second_argument_to_cwsc_not_pointer : Error<
"second argument to __builtin_call_with_static_chain must be of pointer type">;

def err_vector_incorrect_num_initializers : Error<
"%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
def err_vector_incorrect_num_elements : Error<
"%select{too many|too few}0 elements in vector %select{initialization|operand}3 (expected %1 elements, have %2)">;
def err_altivec_empty_initializer : Error<"expected initializer">;

def err_invalid_neon_type_code : Error<
Expand Down Expand Up @@ -12666,17 +12666,24 @@ def err_acc_loop_spec_conflict
def err_acc_collapse_loop_count
: Error<"OpenACC 'collapse' clause loop count must be a %select{constant "
"expression|positive integer value, evaluated to %1}0">;
def err_acc_invalid_in_collapse_loop
: Error<"%select{OpenACC '%1' construct|while loop|do loop}0 cannot appear "
"in intervening code of a 'loop' with a 'collapse' clause">;
def note_acc_collapse_clause_here
: Note<"active 'collapse' clause defined here">;
def err_acc_collapse_multiple_loops
def err_acc_size_expr_value
: Error<
"OpenACC 'tile' clause size expression must be %select{an asterisk "
"or a constant expression|positive integer value, evaluated to %1}0">;
def err_acc_invalid_in_loop
: Error<"%select{OpenACC '%2' construct|while loop|do loop}0 cannot appear "
"in intervening code of a 'loop' with a '%1' clause">;
def note_acc_active_clause_here
: Note<"active '%0' clause defined here">;
def err_acc_clause_multiple_loops
: Error<"more than one for-loop in a loop associated with OpenACC 'loop' "
"construct with a 'collapse' clause">;
def err_acc_collapse_insufficient_loops
: Error<"'collapse' clause specifies a loop count greater than the number "
"construct with a '%select{collapse|tile}0' clause">;
def err_acc_insufficient_loops
: Error<"'%0' clause specifies a loop count greater than the number "
"of available loops">;
def err_acc_intervening_code
: Error<"inner loops must be tightly nested inside a '%0' clause on "
"a 'loop' construct">;

// AMDGCN builtins diagnostics
def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/OpenACCClauses.def
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ VISIT_CLAUSE(Private)
VISIT_CLAUSE(Reduction)
VISIT_CLAUSE(Self)
VISIT_CLAUSE(Seq)
VISIT_CLAUSE(Tile)
VISIT_CLAUSE(VectorLength)
VISIT_CLAUSE(Wait)

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/StmtNodes.td
Original file line number Diff line number Diff line change
Expand Up @@ -308,5 +308,8 @@ def OpenACCAssociatedStmtConstruct
def OpenACCComputeConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;
def OpenACCLoopConstruct : StmtNode<OpenACCAssociatedStmtConstruct>;

// OpenACC Additional Expressions.
def OpenACCAsteriskSizeExpr : StmtNode<Expr>;

// HLSL Constructs.
def HLSLOutArgExpr : StmtNode<Expr>;
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/arm_sme.td
Original file line number Diff line number Diff line change
Expand Up @@ -818,7 +818,7 @@ multiclass ZAReadzArray<string vg_num>{
defm SVREADZ_VG2 : ZAReadzArray<"2">;
defm SVREADZ_VG4 : ZAReadzArray<"4">;

let SMETargetGuard = "sme2,sme-lutv2" in {
let SMETargetGuard = "sme-lutv2" in {
def SVWRITE_LANE_ZT : SInst<"svwrite_lane_zt[_{d}]", "vidi", "cUcsUsiUilUlfhdb", MergeNone, "aarch64_sme_write_lane_zt", [IsStreaming, IsInOutZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck1_3>]>;
def SVWRITE_ZT : SInst<"svwrite_zt[_{d}]", "vid", "cUcsUsiUilUlfhdb", MergeNone, "aarch64_sme_write_zt", [IsStreaming, IsOutZT0], [ImmCheck<0, ImmCheck0_0>]>;
def SVLUTI4_ZT_X4 : SInst<"svluti4_zt_{d}_x4", "4i2.u", "cUc", MergeNone, "aarch64_sme_luti4_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>]>;
Expand Down
30 changes: 16 additions & 14 deletions clang/include/clang/Basic/arm_sve.td
Original file line number Diff line number Diff line change
Expand Up @@ -943,11 +943,6 @@ defm SVFCVTZS_S64_F16 : SInstCvtMXZ<"svcvt_s64[_f16]", "ddPO", "dPO", "l", "aar
defm SVFCVTZS_S32_F32 : SInstCvtMXZ<"svcvt_s32[_f32]", "ddPM", "dPM", "i", "aarch64_sve_fcvtzs", [IsOverloadCvt]>;
defm SVFCVTZS_S64_F32 : SInstCvtMXZ<"svcvt_s64[_f32]", "ddPM", "dPM", "l", "aarch64_sve_fcvtzs_i64f32">;

let SVETargetGuard = "sve,bf16", SMETargetGuard = "sme,bf16" in {
defm SVCVT_BF16_F32 : SInstCvtMXZ<"svcvt_bf16[_f32]", "ddPM", "dPM", "b", "aarch64_sve_fcvt_bf16f32">;
def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b", MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone, VerifyRuntimeMode]>;
}

// svcvt_s##_f64
defm SVFCVTZS_S32_F64 : SInstCvtMXZ<"svcvt_s32[_f64]", "ttPd", "tPd", "d", "aarch64_sve_fcvtzs_i32f64">;
defm SVFCVTZS_S64_F64 : SInstCvtMXZ<"svcvt_s64[_f64]", "ddPN", "dPN", "l", "aarch64_sve_fcvtzs", [IsOverloadCvt]>;
Expand Down Expand Up @@ -1003,19 +998,26 @@ defm SVFCVT_F32_F64 : SInstCvtMXZ<"svcvt_f32[_f64]", "MMPd", "MPd", "d", "aarc
defm SVFCVT_F64_F16 : SInstCvtMXZ<"svcvt_f64[_f16]", "ddPO", "dPO", "d", "aarch64_sve_fcvt_f64f16">;
defm SVFCVT_F64_F32 : SInstCvtMXZ<"svcvt_f64[_f32]", "ddPM", "dPM", "d", "aarch64_sve_fcvt_f64f32">;

let SVETargetGuard = "sve2", SMETargetGuard = "sme" in {
defm SVCVTLT_F32 : SInstCvtMX<"svcvtlt_f32[_f16]", "ddPh", "dPh", "f", "aarch64_sve_fcvtlt_f32f16">;
defm SVCVTLT_F64 : SInstCvtMX<"svcvtlt_f64[_f32]", "ddPh", "dPh", "d", "aarch64_sve_fcvtlt_f64f32">;
let SVETargetGuard = "sve,bf16", SMETargetGuard = "sme,bf16" in {
defm SVCVT_BF16_F32 : SInstCvtMXZ<"svcvt_bf16[_f32]", "$$Pd", "$Pd", "f", "aarch64_sve_fcvt_bf16f32_v2">;

def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "$$Pd", "f", MergeOp1, "aarch64_sve_fcvtnt_bf16f32_v2", [IsOverloadNone, VerifyRuntimeMode]>;
// SVCVTNT_X_BF16_F32 : Implemented as macro by SveEmitter.cpp
}

defm SVCVTX_F32 : SInstCvtMXZ<"svcvtx_f32[_f64]", "MMPd", "MPd", "d", "aarch64_sve_fcvtx_f32f64">;
let SVETargetGuard = "sve2", SMETargetGuard = "sme" in {
defm SVCVTLT_F32_F16 : SInstCvtMX<"svcvtlt_f32[_f16]", "ddPh", "dPh", "f", "aarch64_sve_fcvtlt_f32f16">;
defm SVCVTLT_F64_F32 : SInstCvtMX<"svcvtlt_f64[_f32]", "ddPh", "dPh", "d", "aarch64_sve_fcvtlt_f64f32">;

def SVCVTNT_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone, VerifyRuntimeMode]>;
def SVCVTNT_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone, VerifyRuntimeMode]>;
// SVCVTNT_X : Implemented as macro by SveEmitter.cpp
defm SVCVTX_F32_F64 : SInstCvtMXZ<"svcvtx_f32[_f64]", "MMPd", "MPd", "d", "aarch64_sve_fcvtx_f32f64">;

def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone, VerifyRuntimeMode]>;
// SVCVTXNT_X_F32 : Implemented as macro by SveEmitter.cpp
def SVCVTNT_F16_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone, VerifyRuntimeMode]>;
def SVCVTNT_F32_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone, VerifyRuntimeMode]>;
// SVCVTNT_X_F16_F32 : Implemented as macro by SveEmitter.cpp
// SVCVTNT_X_F32_F64 : Implemented as macro by SveEmitter.cpp

def SVCVTXNT_F32_F64 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone, VerifyRuntimeMode]>;
// SVCVTXNT_X_F32_F64 : Implemented as macro by SveEmitter.cpp
}

////////////////////////////////////////////////////////////////////////////////
Expand Down
62 changes: 62 additions & 0 deletions clang/include/clang/CIR/.clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
InheritParentConfig: true
Checks: >
-misc-const-correctness,
-llvm-header-guard,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-branch-clone,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multiple-statement-macro,
bugprone-suspicious-semicolon,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-unused-raii,
bugprone-unused-return-value,
misc-redundant-expression,
misc-static-assert,
misc-unused-using-decls,
modernize-use-bool-literals,
modernize-loop-convert,
modernize-make-unique,
modernize-raw-string-literal,
modernize-use-equals-default,
modernize-use-default-member-init,
modernize-use-emplace,
modernize-use-nullptr,
modernize-use-override,
modernize-use-using,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-algorithm,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-no-automatic-move,
performance-trivially-destructible,
performance-unnecessary-copy-initialization,
performance-unnecessary-value-param,
readability-avoid-const-params-in-decls,
readability-const-return-type,
readability-container-size-empty,
readability-identifier-naming,
readability-inconsistent-declaration-parameter-name,
readability-misleading-indentation,
readability-redundant-control-flow,
readability-redundant-smartptr-get,
readability-simplify-boolean-expr,
readability-simplify-subscript-expr,
readability-use-anyofallof
CheckOptions:
- key: readability-identifier-naming.MemberCase
value: camelBack
- key: readability-identifier-naming.ParameterCase
value: camelBack
- key: readability-identifier-naming.VariableCase
value: camelBack
53 changes: 53 additions & 0 deletions clang/include/clang/CIRFrontendAction/.clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
InheritParentConfig: true
Checks: >
-misc-const-correctness,
-llvm-header-guard,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-branch-clone,
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misplaced-widening-cast,
bugprone-move-forwarding-reference,
bugprone-multiple-statement-macro,
bugprone-suspicious-semicolon,
bugprone-swapped-arguments,
bugprone-terminating-continue,
bugprone-unused-raii,
bugprone-unused-return-value,
misc-redundant-expression,
misc-static-assert,
misc-unused-using-decls,
modernize-use-bool-literals,
modernize-loop-convert,
modernize-make-unique,
modernize-raw-string-literal,
modernize-use-equals-default,
modernize-use-default-member-init,
modernize-use-emplace,
modernize-use-nullptr,
modernize-use-override,
modernize-use-using,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
performance-inefficient-algorithm,
performance-inefficient-vector-operation,
performance-move-const-arg,
performance-no-automatic-move,
performance-trivially-destructible,
performance-unnecessary-copy-initialization,
performance-unnecessary-value-param,
readability-avoid-const-params-in-decls,
readability-const-return-type,
readability-container-size-empty,
readability-identifier-naming,
readability-inconsistent-declaration-parameter-name,
readability-misleading-indentation,
readability-redundant-control-flow,
readability-redundant-smartptr-get,
readability-simplify-boolean-expr,
readability-simplify-subscript-expr,
readability-use-anyofallof
8 changes: 4 additions & 4 deletions clang/include/clang/Driver/Multilib.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Multilib {
// Some Multilib objects don't actually represent library directories you can
// select. Instead, they represent failures of multilib selection, of the
// form 'Sorry, we don't have any library compatible with these constraints'.
std::optional<std::string> FatalError;
std::optional<std::string> Error;

public:
/// GCCSuffix, OSSuffix & IncludeSuffix will be appended directly to the
Expand All @@ -63,7 +63,7 @@ class Multilib {
Multilib(StringRef GCCSuffix = {}, StringRef OSSuffix = {},
StringRef IncludeSuffix = {}, const flags_list &Flags = flags_list(),
StringRef ExclusiveGroup = {},
std::optional<StringRef> FatalError = std::nullopt);
std::optional<StringRef> Error = std::nullopt);

/// Get the detected GCC installation path suffix for the multi-arch
/// target variant. Always starts with a '/', unless empty
Expand Down Expand Up @@ -94,9 +94,9 @@ class Multilib {

bool operator==(const Multilib &Other) const;

bool isFatalError() const { return FatalError.has_value(); }
bool isError() const { return Error.has_value(); }

const std::string &getFatalError() const { return FatalError.value(); }
const std::string &getErrorMessage() const { return Error.value(); }
};

raw_ostream &operator<<(raw_ostream &OS, const Multilib &M);
Expand Down
12 changes: 8 additions & 4 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1195,10 +1195,11 @@ def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
def c : Flag<["-"], "c">, Flags<[NoXarchOption]>,
Visibility<[ClangOption, FlangOption]>, Group<Action_Group>,
HelpText<"Only run preprocess, compile, and assemble steps">;
defm convergent_functions : BoolFOption<"convergent-functions",
LangOpts<"ConvergentFunctions">, DefaultFalse,
NegFlag<SetFalse, [], [ClangOption], "Assume all functions may be convergent.">,
PosFlag<SetTrue, [], [ClangOption, CC1Option]>>;
def fconvergent_functions : Flag<["-"], "fconvergent-functions">,
Visibility<[ClangOption, CC1Option]>,
HelpText< "Assume all functions may be convergent.">;
def fno_convergent_functions : Flag<["-"], "fno-convergent-functions">,
Visibility<[ClangOption, CC1Option]>;

// Common offloading options
let Group = offload_Group in {
Expand Down Expand Up @@ -5557,6 +5558,9 @@ def mthumb : Flag<["-"], "mthumb">, Group<m_Group>;
def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>,
Visibility<[ClangOption, FlangOption]>,
HelpText<"Only supported on AArch64, PowerPC, RISC-V, SPARC, SystemZ, and X86">;
def multi_lib_config : Joined<["-", "--"], "multi-lib-config=">,
HelpText<"Path to the YAML configuration file to be used for multilib selection">,
MetaVarName<"<file>">;
def multi__module : Flag<["-"], "multi_module">;
def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">;
def multiply__defined : Separate<["-"], "multiply_defined">;
Expand Down
28 changes: 22 additions & 6 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct FormatStyle {
/// Don't align array initializer columns.
AIAS_None
};
/// if not ``None``, when using initialization for an array of structs
/// If not ``None``, when using initialization for an array of structs
/// aligns the fields into columns.
///
/// \note
Expand All @@ -145,11 +145,12 @@ struct FormatStyle {
/// Alignment options.
///
/// They can also be read as a whole for compatibility. The choices are:
/// - None
/// - Consecutive
/// - AcrossEmptyLines
/// - AcrossComments
/// - AcrossEmptyLinesAndComments
///
/// * ``None``
/// * ``Consecutive``
/// * ``AcrossEmptyLines``
/// * ``AcrossComments``
/// * ``AcrossEmptyLinesAndComments``
///
/// For example, to align across empty lines and not across comments, either
/// of these work.
Expand Down Expand Up @@ -225,6 +226,20 @@ struct FormatStyle {
/// bbb = 2;
/// \endcode
bool AlignCompound;
/// Only for ``AlignConsecutiveDeclarations``. Whether function declarations
/// are aligned.
/// \code
/// true:
/// unsigned int f1(void);
/// void f2(void);
/// size_t f3(void);
///
/// false:
/// unsigned int f1(void);
/// void f2(void);
/// size_t f3(void);
/// \endcode
bool AlignFunctionDeclarations;
/// Only for ``AlignConsecutiveDeclarations``. Whether function pointers are
/// aligned.
/// \code
Expand Down Expand Up @@ -264,6 +279,7 @@ struct FormatStyle {
return Enabled == R.Enabled && AcrossEmptyLines == R.AcrossEmptyLines &&
AcrossComments == R.AcrossComments &&
AlignCompound == R.AlignCompound &&
AlignFunctionDeclarations == R.AlignFunctionDeclarations &&
AlignFunctionPointers == R.AlignFunctionPointers &&
PadOperators == R.PadOperators;
}
Expand Down
7 changes: 5 additions & 2 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3786,10 +3786,13 @@ class Parser : public CodeCompletionHandler {
OpenACCIntExprParseResult ParseOpenACCAsyncArgument(OpenACCDirectiveKind DK,
OpenACCClauseKind CK,
SourceLocation Loc);

/// Parses the 'size-expr', which is an integral value, or an asterisk.
bool ParseOpenACCSizeExpr();
/// Asterisk is represented by a OpenACCAsteriskSizeExpr
ExprResult ParseOpenACCSizeExpr(OpenACCClauseKind CK);
/// Parses a comma delimited list of 'size-expr's.
bool ParseOpenACCSizeExprList();
bool ParseOpenACCSizeExprList(OpenACCClauseKind CK,
llvm::SmallVectorImpl<Expr *> &SizeExprs);
/// Parses a 'gang-arg-list', used for the 'gang' clause.
bool ParseOpenACCGangArgList(SourceLocation GangLoc);
/// Parses a 'gang-arg', used for the 'gang' clause.
Expand Down
83 changes: 63 additions & 20 deletions clang/include/clang/Sema/SemaOpenACC.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ class SemaOpenACC : public SemaBase {
/// above collection.
bool InsideComputeConstruct = false;

/// Certain clauses care about the same things that aren't specific to the
/// individual clause, but can be shared by a few, so store them here. All
/// require a 'no intervening constructs' rule, so we know they are all from
/// the same 'place'.
struct LoopCheckingInfo {
/// Records whether we've seen the top level 'for'. We already diagnose
/// later that the 'top level' is a for loop, so we use this to suppress the
/// 'collapse inner loop not a 'for' loop' diagnostic.
LLVM_PREFERRED_TYPE(bool)
unsigned TopLevelLoopSeen : 1;

/// Records whether this 'tier' of the loop has already seen a 'for' loop,
/// used to diagnose if there are multiple 'for' loops at any one level.
LLVM_PREFERRED_TYPE(bool)
unsigned CurLevelHasLoopAlready : 1;
} LoopInfo{/*TopLevelLoopSeen=*/false, /*CurLevelHasLoopAlready=*/false};

/// The 'collapse' clause requires quite a bit of checking while
/// parsing/instantiating its body, so this structure/object keeps all of the
/// necessary information as we do checking. This should rarely be directly
Expand All @@ -59,25 +76,27 @@ class SemaOpenACC : public SemaBase {
/// else it should be 'N' minus the current depth traversed.
std::optional<llvm::APSInt> CurCollapseCount;

/// Records whether we've seen the top level 'for'. We already diagnose
/// later that the 'top level' is a for loop, so we use this to suppress the
/// 'collapse inner loop not a 'for' loop' diagnostic.
LLVM_PREFERRED_TYPE(bool)
unsigned TopLevelLoopSeen : 1;

/// Records whether this 'tier' of the loop has already seen a 'for' loop,
/// used to diagnose if there are multiple 'for' loops at any one level.
LLVM_PREFERRED_TYPE(bool)
unsigned CurLevelHasLoopAlready : 1;

/// Records whether we've hit a CurCollapseCount of '0' on the way down,
/// which allows us to diagnose if the value of 'N' is too large for the
/// current number of 'for' loops.
LLVM_PREFERRED_TYPE(bool)
unsigned CollapseDepthSatisfied : 1;
} CollapseInfo{nullptr, std::nullopt, /*TopLevelLoopSeen=*/false,
/*CurLevelHasLoopAlready=*/false,
/*CollapseDepthSatisfied=*/true};
bool CollapseDepthSatisfied = true;
} CollapseInfo;

/// The 'tile' clause requires a bit of additional checking as well, so like
/// the `CollapseCheckingInfo`, ensure we maintain information here too.
struct TileCheckingInfo {
OpenACCTileClause *ActiveTile = nullptr;

/// This is the number of expressions on a 'tile' clause. This doesn't have
/// to be an APSInt because it isn't the result of a constexpr, just by our
/// own counting of elements.
std::optional<unsigned> CurTileCount;

/// Records whether we've hit a 'CurTileCount' of '0' on the wya down,
/// which allows us to diagnose if the number of arguments is too large for
/// the current number of 'for' loops.
bool TileDepthSatisfied = true;
} TileInfo;

public:
// Redeclaration of the version in OpenACCClause.h.
Expand Down Expand Up @@ -179,6 +198,7 @@ class SemaOpenACC : public SemaBase {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");

Expand Down Expand Up @@ -224,6 +244,7 @@ class SemaOpenACC : public SemaBase {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");

Expand Down Expand Up @@ -335,6 +356,7 @@ class SemaOpenACC : public SemaBase {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
Details = IntExprDetails{{IntExprs.begin(), IntExprs.end()}};
Expand All @@ -343,6 +365,7 @@ class SemaOpenACC : public SemaBase {
assert((ClauseKind == OpenACCClauseKind::NumGangs ||
ClauseKind == OpenACCClauseKind::NumWorkers ||
ClauseKind == OpenACCClauseKind::Async ||
ClauseKind == OpenACCClauseKind::Tile ||
ClauseKind == OpenACCClauseKind::VectorLength) &&
"Parsed clause kind does not have a int exprs");
Details = IntExprDetails{std::move(IntExprs)};
Expand Down Expand Up @@ -522,17 +545,26 @@ class SemaOpenACC : public SemaBase {
SourceLocation RBLoc);
/// Checks the loop depth value for a collapse clause.
ExprResult CheckCollapseLoopCount(Expr *LoopCount);
/// Checks a single size expr for a tile clause. 'gang' could possibly call
/// this, but has slightly stricter rules as to valid values.
ExprResult CheckTileSizeExpr(Expr *SizeExpr);

ExprResult BuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);
ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc);

/// Helper type to restore the state of various 'loop' constructs when we run
/// into a loop (for, etc) inside the construct.
class LoopInConstructRAII {
SemaOpenACC &SemaRef;
LoopCheckingInfo OldLoopInfo;
CollapseCheckingInfo OldCollapseInfo;
TileCheckingInfo OldTileInfo;
bool PreserveDepth;

public:
LoopInConstructRAII(SemaOpenACC &SemaRef, bool PreserveDepth = true)
: SemaRef(SemaRef), OldCollapseInfo(SemaRef.CollapseInfo),
: SemaRef(SemaRef), OldLoopInfo(SemaRef.LoopInfo),
OldCollapseInfo(SemaRef.CollapseInfo), OldTileInfo(SemaRef.TileInfo),
PreserveDepth(PreserveDepth) {}
~LoopInConstructRAII() {
// The associated-statement level of this should NOT preserve this, as it
Expand All @@ -541,12 +573,20 @@ class SemaOpenACC : public SemaBase {
bool CollapseDepthSatisified =
PreserveDepth ? SemaRef.CollapseInfo.CollapseDepthSatisfied
: OldCollapseInfo.CollapseDepthSatisfied;
bool TileDepthSatisfied = PreserveDepth
? SemaRef.TileInfo.TileDepthSatisfied
: OldTileInfo.TileDepthSatisfied;
bool CurLevelHasLoopAlready =
PreserveDepth ? SemaRef.CollapseInfo.CurLevelHasLoopAlready
: OldCollapseInfo.CurLevelHasLoopAlready;
PreserveDepth ? SemaRef.LoopInfo.CurLevelHasLoopAlready
: OldLoopInfo.CurLevelHasLoopAlready;

SemaRef.LoopInfo = OldLoopInfo;
SemaRef.CollapseInfo = OldCollapseInfo;
SemaRef.TileInfo = OldTileInfo;

SemaRef.CollapseInfo.CollapseDepthSatisfied = CollapseDepthSatisified;
SemaRef.CollapseInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
SemaRef.TileInfo.TileDepthSatisfied = TileDepthSatisfied;
SemaRef.LoopInfo.CurLevelHasLoopAlready = CurLevelHasLoopAlready;
}
};

Expand All @@ -567,6 +607,9 @@ class SemaOpenACC : public SemaBase {
void SetCollapseInfoBeforeAssociatedStmt(
ArrayRef<const OpenACCClause *> UnInstClauses,
ArrayRef<OpenACCClause *> Clauses);
void SetTileInfoBeforeAssociatedStmt(
ArrayRef<const OpenACCClause *> UnInstClauses,
ArrayRef<OpenACCClause *> Clauses);
~AssociatedStmtRAII();
};
};
Expand Down
4 changes: 3 additions & 1 deletion clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2002,12 +2002,14 @@ enum StmtCode {
// SYCLUniqueStableNameExpr
EXPR_SYCL_UNIQUE_STABLE_NAME,

// OpenACC Constructs
// OpenACC Constructs/Exprs
STMT_OPENACC_COMPUTE_CONSTRUCT,
STMT_OPENACC_LOOP_CONSTRUCT,
EXPR_OPENACC_ASTERISK_SIZE,

// HLSL Constructs
EXPR_HLSL_OUT_ARG,

};

/// The kinds of designators that can occur in a
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14439,8 +14439,6 @@ bool ASTContext::useAbbreviatedThunkName(GlobalDecl VirtualMethodDecl,
Mangler->mangleThunk(Method, Thunk, /* elideOverrideInfo */ false,
mangledNameStream);

if (Thunks.find(ElidedName) == Thunks.end())
Thunks[ElidedName] = {};
Thunks[ElidedName].push_back(std::string(MangledName));
}
}
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2128,6 +2128,13 @@ bool Compiler<Emitter>::VisitUnaryExprOrTypeTraitExpr(
return this->emitConst(1, E);
}

if (Kind == UETT_OpenMPRequiredSimdAlign) {
assert(E->isArgumentType());
unsigned Bits = ASTCtx.getOpenMPDefaultSimdAlign(E->getArgumentType());

return this->emitConst(ASTCtx.toCharUnitsFromBits(Bits).getQuantity(), E);
}

return false;
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/ByteCode/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
Desc->IsConst = IsConst || D->IsConst;
Desc->IsFieldMutable = IsMutable || D->IsMutable;
Desc->InUnion = InUnion;
Desc->IsArrayElement = true;

if (auto Fn = D->ElemDesc->CtorFn)
Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsActive,
Expand Down Expand Up @@ -408,6 +409,8 @@ QualType Descriptor::getType() const {
QualType Descriptor::getElemQualType() const {
assert(isArray());
QualType T = getType();
if (T->isPointerOrReferenceType())
return T->getPointeeType();
if (const auto *AT = T->getAsArrayTypeUnsafe())
return AT->getElementType();
if (const auto *CT = T->getAs<ComplexType>())
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/AST/ByteCode/Descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,16 @@ struct InlineDescriptor {
/// Flag indicating if the field is mutable (if in a record).
LLVM_PREFERRED_TYPE(bool)
unsigned IsFieldMutable : 1;
/// Flag indicating if the field is an element of a composite array.
LLVM_PREFERRED_TYPE(bool)
unsigned IsArrayElement : 1;

const Descriptor *Desc;

InlineDescriptor(const Descriptor *D)
: Offset(sizeof(InlineDescriptor)), IsConst(false), IsInitialized(false),
IsBase(false), IsActive(false), IsFieldMutable(false), Desc(D) {}
IsBase(false), IsActive(false), IsFieldMutable(false),
IsArrayElement(false), Desc(D) {}

void dump() const { dump(llvm::errs()); }
void dump(llvm::raw_ostream &OS) const;
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,10 @@ bool handleFixedPointOverflow(InterpState &S, CodePtr OpPC,
return S.noteUndefinedBehavior();
}

// https://github.com/llvm/llvm-project/issues/102513
#if defined(_WIN32) && !defined(__clang__) && !defined(NDEBUG)
#pragma optimize("", off)
#endif
bool Interpret(InterpState &S, APValue &Result) {
// The current stack frame when we started Interpret().
// This is being used by the ops to determine wheter
Expand All @@ -1430,6 +1434,10 @@ bool Interpret(InterpState &S, APValue &Result) {
}
}
}
// https://github.com/llvm/llvm-project/issues/102513
#if defined(_WIN32) && !defined(__clang__) && !defined(NDEBUG)
#pragma optimize("", on)
#endif

} // namespace interp
} // namespace clang
4 changes: 2 additions & 2 deletions clang/lib/AST/ByteCode/InterpBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ bool Block::hasPointer(const Pointer *P) const {
#endif

DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
: Root(Root),
B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) {
: Root(Root), B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, Blk->IsWeak,
/*isDead=*/true) {
// Add the block to the chain of dead blocks.
if (Root)
Root->Prev = this;
Expand Down
Loading