https://github.com/calumr created
https://github.com/llvm/llvm-project/pull/112689
* This only looks for ^ as a pointer/reference token, which is the main issue
when trying to format C++/CLI.
Obviously there's more to C++/CLI than this minor change, but it's extremely
useful to be able to clang-format our whole codebase now without a ^ mangling
the output.
>From 40f665adce7d32aa194f8500746d0bfbc2d5f2d6 Mon Sep 17 00:00:00 2001
From: Calum Robinson
Date: Thu, 17 Oct 2024 10:11:41 +0100
Subject: [PATCH] [clang-format] Add basic support for C++/CLI (#27126)
* This only looks for ^ as a pointer/reference token, which is the main
issue when trying to format C++/CLI.
---
clang/include/clang/Basic/LangOptions.def| 1 +
clang/lib/Format/Format.cpp | 1 +
clang/lib/Format/FormatToken.h | 4 ++-
clang/lib/Format/QualifierAlignmentFixer.cpp | 2 +-
clang/lib/Format/TokenAnnotator.cpp | 34 +++-
clang/lib/Format/WhitespaceManager.cpp | 24 +++---
clang/lib/Format/WhitespaceManager.h | 4 ++-
7 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.def
b/clang/include/clang/Basic/LangOptions.def
index 68db400c22e6c1..1285ce06d845f3 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -101,6 +101,7 @@ LANGOPT(CPlusPlus17 , 1, 0, "C++17")
LANGOPT(CPlusPlus20 , 1, 0, "C++20")
LANGOPT(CPlusPlus23 , 1, 0, "C++23")
LANGOPT(CPlusPlus26 , 1, 0, "C++26")
+LANGOPT(CPlusPlusCLI , 1, 0, "C++/CLI")
LANGOPT(ObjC , 1, 0, "Objective-C")
BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
"Objective-C auto-synthesized properties")
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 148270795c562f..4344b5b2ad4c26 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3914,6 +3914,7 @@ LangOptions getFormattingLangOpts(const FormatStyle
&Style) {
LangOpts.Bool = 1;
LangOpts.ObjC = 1;
LangOpts.MicrosoftExt = 1;// To get kw___try, kw___finally.
+ LangOpts.CPlusPlusCLI = 1;
LangOpts.DeclSpecKeyword = 1; // To get __declspec.
LangOpts.C99 = 1; // To get kw_restrict for non-underscore-prefixed restrict.
return LangOpts;
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 7d342a7dcca01d..cdf613774fa6bc 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -731,7 +731,9 @@ struct FormatToken {
TT_LambdaArrow, TT_LeadingJavaAnnotation);
}
- bool isPointerOrReference() const {
+ bool isPointerOrReference(const LangOptions &LangOpts) const {
+if (LangOpts.CPlusPlusCLI && is(tok::caret))
+ return true;
return isOneOf(tok::star, tok::amp, tok::ampamp);
}
diff --git a/clang/lib/Format/QualifierAlignmentFixer.cpp
b/clang/lib/Format/QualifierAlignmentFixer.cpp
index 593f8efff25aa9..f07c8913b907ac 100644
--- a/clang/lib/Format/QualifierAlignmentFixer.cpp
+++ b/clang/lib/Format/QualifierAlignmentFixer.cpp
@@ -385,7 +385,7 @@ const FormatToken
*LeftRightQualifierAlignmentFixer::analyzeLeft(
// For left qualifiers preceeded by nothing, a template declaration, or
*,&,&&
// we only perform sorting.
- if (!TypeToken || TypeToken->isPointerOrReference() ||
+ if (!TypeToken || TypeToken->isPointerOrReference(LangOpts) ||
TypeToken->ClosesRequiresClause || TypeToken->ClosesTemplateDeclaration)
{
// Don't sort past a non-configured qualifier token.
diff --git a/clang/lib/Format/TokenAnnotator.cpp
b/clang/lib/Format/TokenAnnotator.cpp
index fcefaa7bb298ea..5a33c1c00c8b24 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -468,8 +468,8 @@ class AnnotatingParser {
// void (&&FunctionReference)(void);
// void (^ObjCBlock)(void);
bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
-bool ProbablyFunctionType =
-CurrentToken->isPointerOrReference() || CurrentToken->is(tok::caret);
+bool ProbablyFunctionType = CurrentToken->isPointerOrReference(LangOpts) ||
+CurrentToken->is(tok::caret);
bool HasMultipleLines = false;
bool HasMultipleParametersOnALine = false;
bool MightBeObjCForRangeLoop =
@@ -507,7 +507,8 @@ class AnnotatingParser {
// auto my_lambda = MACRO((Type *type, int i) { .. body .. });
for (FormatToken *Tok = &OpeningParen; Tok != CurrentToken;
Tok = Tok->Next) {
-if (Tok->is(TT_BinaryOperator) && Tok->isPointerOrReference())
+if (Tok->is(TT_BinaryOperator) &&
+Tok->isPointerOrReference(LangOpts))
Tok->setType(TT_PointerOrReference);
}
}
@@ -578,7 +579,7 @@ class AnnotatingParser {
Tok != CurrentToken &&
!Tok->isOneOf(t