[PATCH] D116283: Added an option to add a space between operator overloading and opening parentheses in clang-format

2021-12-26 Thread Rajat Bajpai via Phabricator via cfe-commits
rajatbajpai created this revision.
rajatbajpai added a reviewer: MyDeveloperDay.
rajatbajpai added a project: clang-format.
rajatbajpai requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This change adds an option AfterOperatorOverloading in SpaceBeforeParensOptions 
to add a space between operator overloading and opening parentheses in 
clang-format.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116283

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/lib/Format/TokenAnnotator.cpp
  clang/test/Format/space-before-parens.cpp

Index: clang/test/Format/space-before-parens.cpp
===
--- /dev/null
+++ clang/test/Format/space-before-parens.cpp
@@ -0,0 +1,9 @@
+// RUN: clang-format -style="{SpaceBeforeParens: Custom, SpaceBeforeParensOptions: {AfterOperator: false}}" %s | FileCheck -strict-whitespace -check-prefix=CHECK1 %s
+// Test space between overloaded operator and left parentheses
+// RUN: clang-format -style="{SpaceBeforeParens: Custom, SpaceBeforeParensOptions: {AfterOperator: true}}" %s | FileCheck -strict-whitespace -check-prefix=CHECK2 %s
+class Test {
+  auto func() -> int;
+  // CHECK1: {{^\ \ auto\ operator\+\+\(int\)\ \-\>\ int;$}}
+  // CHECK2: {{^\ \ auto\ operator\+\+\ \(int\)\ \-\>\ int;$}}
+  auto operator++(int) -> int;
+};
Index: clang/lib/Format/TokenAnnotator.cpp
===
--- clang/lib/Format/TokenAnnotator.cpp
+++ clang/lib/Format/TokenAnnotator.cpp
@@ -2921,9 +2921,15 @@
 }
 
 bool TokenAnnotator::spaceRequiredBeforeParens(const FormatToken &Right) const {
-  return Style.SpaceBeforeParens == FormatStyle::SBPO_Always ||
- (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
-  Right.ParameterCount > 0);
+  if (Style.SpaceBeforeParens == FormatStyle::SBPO_Always)
+return true;
+  if (Right.is(TT_OverloadedOperatorLParen) &&
+  Style.SpaceBeforeParensOptions.AfterOperatorOverloading)
+return true;
+  if (Style.SpaceBeforeParensOptions.BeforeNonEmptyParentheses &&
+  Right.ParameterCount > 0)
+return true;
+  return false;
 }
 
 bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -857,6 +857,8 @@
 IO.mapOptional("AfterIfMacros", Spacing.AfterIfMacros);
 IO.mapOptional("BeforeNonEmptyParentheses",
Spacing.BeforeNonEmptyParentheses);
+IO.mapOptional("AfterOperatorOverloading",
+   Spacing.AfterOperatorOverloading);
   }
 };
 
Index: clang/include/clang/Format/Format.h
===
--- clang/include/clang/Format/Format.h
+++ clang/include/clang/Format/Format.h
@@ -3376,12 +3376,20 @@
 ///f (a); f();
 /// \endcode
 bool BeforeNonEmptyParentheses;
+/// If ``true``, put a space between operator overloading and opening
+/// parentheses.
+/// \code
+///true:  false:
+///void operator++ (int a); vs.void operator++(int
+///a);
+/// \endcode
+bool AfterOperatorOverloading;
 
 SpaceBeforeParensCustom()
 : AfterControlStatements(false), AfterForeachMacros(false),
   AfterFunctionDeclarationName(false),
   AfterFunctionDefinitionName(false), AfterIfMacros(false),
-  BeforeNonEmptyParentheses(false) {}
+  BeforeNonEmptyParentheses(false), AfterOperatorOverloading(false) {}
 
 bool operator==(const SpaceBeforeParensCustom &Other) const {
   return AfterControlStatements == Other.AfterControlStatements &&
@@ -3390,7 +3398,8 @@
  Other.AfterFunctionDeclarationName &&
  AfterFunctionDefinitionName == Other.AfterFunctionDefinitionName &&
  AfterIfMacros == Other.AfterIfMacros &&
- BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses;
+ BeforeNonEmptyParentheses == Other.BeforeNonEmptyParentheses &&
+ AfterOperatorOverloading == Other.AfterOperatorOverloading;
 }
   };
 
Index: clang/docs/ClangFormatStyleOptions.rst
===
--- clang/docs/ClangFormatStyleOptions.rst
+++ clang/docs/ClangFormatStyleOptions.rst
@@ -3761,6 +3761,13 @@
void f (int a); vs.void f();
f (a); f();
 
+  * ``bool AfterOperatorOverloading`` If ``true``, put a space between operator overloading and opening parentheses.
+
+.. code-block:: c++
+
+   true:  false:
+   void operator++ (int a); 

[PATCH] D97121: [clang-tidy] Add a Standalone diagnostics mode to clang-tidy

2021-12-26 Thread Nathan James via Phabricator via cfe-commits
njames93 updated this revision to Diff 396219.
njames93 added a comment.
Herald added a subscriber: carlosgalvezp.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97121/new/

https://reviews.llvm.org/D97121

Files:
  clang-tools-extra/clang-tidy/ClangTidyCheck.h
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h
  clang-tools-extra/clang-tidy/abseil/StringFindStartswithCheck.cpp
  
clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp
  clang-tools-extra/clang-tidy/cppcoreguidelines/InitVariablesCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp
  
clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tools-extra/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp
  clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp
  clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp
  clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
  clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
  clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp
  clang-tools-extra/clang-tidy/performance/TypePromotionInMathFnCheck.cpp
  clang-tools-extra/clang-tidy/performance/UnnecessaryValueParamCheck.cpp
  clang-tools-extra/clang-tidy/utils/IncludeInserter.cpp
  clang-tools-extra/clang-tidy/utils/IncludeInserter.h
  clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp
  clang-tools-extra/clangd/ParsedAST.cpp
  clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
  clang-tools-extra/unittests/clang-tidy/IncludeInserterTest.cpp

Index: clang-tools-extra/unittests/clang-tidy/IncludeInserterTest.cpp
===
--- clang-tools-extra/unittests/clang-tidy/IncludeInserterTest.cpp
+++ clang-tools-extra/unittests/clang-tidy/IncludeInserterTest.cpp
@@ -30,8 +30,10 @@
 public:
   IncludeInserterCheckBase(StringRef CheckName, ClangTidyContext *Context,
utils::IncludeSorter::IncludeStyle Style =
-   utils::IncludeSorter::IS_Google)
-  : ClangTidyCheck(CheckName, Context), Inserter(Style) {}
+   utils::IncludeSorter::IS_Google,
+   bool SelfContainedDiags = false)
+  : ClangTidyCheck(CheckName, Context),
+Inserter(Style, SelfContainedDiags) {}
 
   void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
Preprocessor *ModuleExpanderPP) override {
@@ -85,6 +87,19 @@
   }
 };
 
+class MultipleHeaderSingleInserterCheck : public IncludeInserterCheckBase {
+public:
+  MultipleHeaderSingleInserterCheck(StringRef CheckName,
+ClangTidyContext *Context)
+  : IncludeInserterCheckBase(CheckName, Context,
+ utils::IncludeSorter::IS_Google,
+ /*SelfContainedDiags=*/true) {}
+
+  std::vector headersToInclude() const override {
+return {"path/to/header.h", "path/to/header2.h", "path/to/header.h"};
+  }
+};
+
 class CSystemIncludeInserterCheck : public IncludeInserterCheckBase {
 public:
   CSystemIncludeInserterCheck(StringRef CheckName, ClangTidyContext *Context)
@@ -246,6 +261,41 @@
 PreCode, "clang_tidy/tests/insert_includes_test_input2.cc"));
 }
 
+TEST(IncludeInserterTest, InsertMultipleIncludesNoDeduplicate) {
+  const char *PreCode = R"(
+#include "clang_tidy/tests/insert_includes_test_header.h"
+
+#include 
+#include 
+
+#include "path/to/a/header.h"
+
+void foo() {
+  int a = 0;
+})";
+  // FIXME: ClangFormat bug - https://bugs.llvm.org/show_bug.cgi?id=49298
+  // clang-format off
+  const char *PostCode = R"(
+#include "clang_tidy/tests/insert_includes_test_header.h"
+
+#include 
+#include 
+
+#include "path/to/a/header.h"
+#include "path/to/header.h"
+#include "path/to/header2.h"
+#include "path/to/header.h"
+
+void foo() {
+  int a = 0;
+})";
+  // clang-format on
+
+  EXPECT_EQ(PostCode,
+runCheckOnCode(
+PreCode, "clang_tidy/tests/insert_includes_test_input2.cc"));
+}
+
 TEST(IncludeInserterTest, InsertBeforeFirstNonSystemInclude) {
   const char *PreCode = R"(
 #include "clang_tidy/tests/insert_includes_test_header.h"
Index: clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
===
--- clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -595,6 +595,67 @@
   Diag(Main.range(), "do not use 'else' after 'return'";
 }
 
+TEST(DiagnosticTest, ClangTidySelfContainedDiags) {
+  Annotations Main(R"cpp($MathHeader[[]]
+struct Foo{
+  int A, B;
+  Foo()$Fix[[]] {
+$A[[A = 1;]]
+$B[[B = 1;]]
+  }
+};
+void Init

[PATCH] D116283: Added an option to add a space between operator overloading and opening parentheses in clang-format

2021-12-26 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added a comment.

you need to add a unit test int clang/unittest/Format/FormatTest.cpp (we tend 
to not use lit tests)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116283/new/

https://reviews.llvm.org/D116283

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D115976: [clang] Fix a crash case when reporting an uninitialized field.

2021-12-26 Thread Michael Liao via Phabricator via cfe-commits
hliao updated this revision to Diff 396225.
hliao added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115976/new/

https://reviews.llvm.org/D115976

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/Sema/SemaInit.cpp
  clang/test/SemaCXX/uninitialized.cpp


Index: clang/test/SemaCXX/uninitialized.cpp
===
--- clang/test/SemaCXX/uninitialized.cpp
+++ clang/test/SemaCXX/uninitialized.cpp
@@ -1472,3 +1472,20 @@
   };
 };
 Outer::Inner outerinner;
+
+namespace crash_on_report_uninitialized_field {
+struct S {
+  union {
+struct {
+  const int &f0;
+  const float &f1; // expected-note{{uninitialized reference member is 
here}}
+};
+double d;
+  };
+};
+void bar(struct S &s);
+void foo(int i, float f) {
+  S s = {.f0 = i}; // expected-error{{reference member of type 'const float &' 
uninitialized}}
+  bar(s);
+}
+} // namespace crash_on_report_uninitialized_field
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -695,8 +695,7 @@
 //   member of reference type uninitialized, the program is
 //   ill-formed.
 SemaRef.Diag(Loc, diag::err_init_reference_member_uninitialized)
-  << Field->getType()
-  << ILE->getSyntacticForm()->getSourceRange();
+<< Field->getType() << ILE->getSourceRange();
 SemaRef.Diag(Field->getLocation(),
  diag::note_uninit_reference_member);
   }
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4970,6 +4970,9 @@
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
   SourceLocation getEndLoc() const LLVM_READONLY;
+  SourceRange getSourceRange() const LLVM_READONLY {
+return SourceRange(getBeginLoc(), getEndLoc());
+  }
 
   static bool classof(const Stmt *T) {
 return T->getStmtClass() == InitListExprClass;


Index: clang/test/SemaCXX/uninitialized.cpp
===
--- clang/test/SemaCXX/uninitialized.cpp
+++ clang/test/SemaCXX/uninitialized.cpp
@@ -1472,3 +1472,20 @@
   };
 };
 Outer::Inner outerinner;
+
+namespace crash_on_report_uninitialized_field {
+struct S {
+  union {
+struct {
+  const int &f0;
+  const float &f1; // expected-note{{uninitialized reference member is here}}
+};
+double d;
+  };
+};
+void bar(struct S &s);
+void foo(int i, float f) {
+  S s = {.f0 = i}; // expected-error{{reference member of type 'const float &' uninitialized}}
+  bar(s);
+}
+} // namespace crash_on_report_uninitialized_field
Index: clang/lib/Sema/SemaInit.cpp
===
--- clang/lib/Sema/SemaInit.cpp
+++ clang/lib/Sema/SemaInit.cpp
@@ -695,8 +695,7 @@
 //   member of reference type uninitialized, the program is
 //   ill-formed.
 SemaRef.Diag(Loc, diag::err_init_reference_member_uninitialized)
-  << Field->getType()
-  << ILE->getSyntacticForm()->getSourceRange();
+<< Field->getType() << ILE->getSourceRange();
 SemaRef.Diag(Field->getLocation(),
  diag::note_uninit_reference_member);
   }
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -4970,6 +4970,9 @@
 
   SourceLocation getBeginLoc() const LLVM_READONLY;
   SourceLocation getEndLoc() const LLVM_READONLY;
+  SourceRange getSourceRange() const LLVM_READONLY {
+return SourceRange(getBeginLoc(), getEndLoc());
+  }
 
   static bool classof(const Stmt *T) {
 return T->getStmtClass() == InitListExprClass;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 0542d15 - Remove redundant string initialization (NFC)

2021-12-26 Thread Kazu Hirata via cfe-commits

Author: Kazu Hirata
Date: 2021-12-26T09:39:26-08:00
New Revision: 0542d15211cb1fb45bcd79d485d122c69cd23f28

URL: 
https://github.com/llvm/llvm-project/commit/0542d15211cb1fb45bcd79d485d122c69cd23f28
DIFF: 
https://github.com/llvm/llvm-project/commit/0542d15211cb1fb45bcd79d485d122c69cd23f28.diff

LOG: Remove redundant string initialization (NFC)

Identified with readability-redundant-string-init.

Added: 


Modified: 
clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp
clang/lib/Basic/Targets/M68k.cpp
clang/lib/Basic/Targets/PPC.h
clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/lib/Format/NamespaceEndCommentsFixer.cpp
clang/lib/Frontend/InitHeaderSearch.cpp
clang/lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp
clang/tools/clang-scan-deps/ClangScanDeps.cpp
clang/utils/TableGen/NeonEmitter.cpp
lldb/source/Commands/CommandCompletions.cpp
lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp
lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp

lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp

lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp
lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
lldb/source/Target/RegisterContextUnwind.cpp
llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp 
b/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp
index 9733a4e7c1f56..0691787f1a90f 100644
--- a/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp
@@ -24,7 +24,7 @@ void LimitedRandomnessCheck::registerMatchers(MatchFinder 
*Finder) {
 }
 
 void LimitedRandomnessCheck::check(const MatchFinder::MatchResult &Result) {
-  std::string Msg = "";
+  std::string Msg;
   if (getLangOpts().CPlusPlus)
 Msg = "; use C++11 random library instead";
 

diff  --git a/clang/lib/Basic/Targets/M68k.cpp 
b/clang/lib/Basic/Targets/M68k.cpp
index c0cd8fa90ed6b..ada5b97ed66de 100644
--- a/clang/lib/Basic/Targets/M68k.cpp
+++ b/clang/lib/Basic/Targets/M68k.cpp
@@ -29,7 +29,7 @@ M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
const TargetOptions &)
 : TargetInfo(Triple) {
 
-  std::string Layout = "";
+  std::string Layout;
 
   // M68k is Big Endian
   Layout += "E";

diff  --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index 60701072ac4b6..ac52eb219f54d 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -414,7 +414,7 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public 
PPCTargetInfo {
 LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
 IntMaxType = SignedLong;
 Int64Type = SignedLong;
-std::string DataLayout = "";
+std::string DataLayout;
 
 if (Triple.isOSAIX()) {
   // TODO: Set appropriate ABI for AIX platform.

diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index e35c154215203..b23100d435b42 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -1434,7 +1434,7 @@ llvm::Value 
*CGOpenMPRuntime::emitUpdateLocation(CodeGenFunction &CGF,
   Loc.isInvalid()) {
 SrcLocStr = OMPBuilder.getOrCreateDefaultSrcLocStr();
   } else {
-std::string FunctionName = "";
+std::string FunctionName;
 if (const auto *FD = dyn_cast_or_null(CGF.CurFuncDecl))
   FunctionName = FD->getQualifiedNameAsString();
 PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
@@ -9540,7 +9540,7 @@ emitMappingInformation(CodeGenFunction &CGF, 
llvm::OpenMPIRBuilder &OMPBuilder,
 Loc = MapExprs.getMapDecl()->getLocation();
   }
 
-  std::string ExprName = "";
+  std::string ExprName;
   if (MapExprs.getMapExpr()) {
 PrintingPolicy P(CGF.getContext().getLangOpts());
 llvm::raw_string_ostream OS(ExprName);

diff  --git a/clang/lib/Format/NamespaceEndCommentsFixer.cpp 
b/clang/lib/Format/NamespaceEndCommentsFixer.cpp
index 38ab5b9df76d4..9c00d243f34a8 100644
--- a/clang/lib/Format/NamespaceEndCommentsFixer.cpp
+++ b/clang/lib/Format/NamespaceEndCommentsFixer.cpp
@@ -28,7 +28,7 @@ std::string computeName(const FormatToken *NamespaceTok) {
   assert(NamespaceTok &&
  NamespaceTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro) &&
  "expecting a namespace token");
-  std::string name = "";
+  std::string name;
   const FormatToken *Tok = NamespaceTok->getNextNonComment();
   if (NamespaceTok->is(TT_NamespaceMacro)) {
 // Collects all the 

[PATCH] D116290: [clang-format] Add enforcement of consistent `class`/typename` keyword for template arguments

2021-12-26 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang created this revision.
Herald added a subscriber: mgorny.
avogelsgesang requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Template argument types can be introduced using either the `class` or
the `typename` argument. While there are good arguments for both styles,
usually one wants to use one style consistently across a project.

This commit adds a `TemplateArgumentKeyword` option which can be used
to format all template arguments consistently using either the `class`
or the `typename` argument.

Implementationwise, it closely follows in the footsteps of D69764 
, i.e.
it adds a new `TemplateArgumentKeywordFixer` pass which creates the
appropriate replacements.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116290

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/CMakeLists.txt
  clang/lib/Format/Format.cpp
  clang/lib/Format/TemplateArgumentKeywordFixer.cpp
  clang/lib/Format/TemplateArgumentKeywordFixer.h
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/TemplateArgumentKeywordFixerTest.cpp

Index: clang/unittests/Format/TemplateArgumentKeywordFixerTest.cpp
===
--- /dev/null
+++ clang/unittests/Format/TemplateArgumentKeywordFixerTest.cpp
@@ -0,0 +1,170 @@
+//===- unittest/Format/TemplateArgumentKeywordFixerTest.cpp ---===//
+//
+// 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 "clang/Format/Format.h"
+
+#include "FormatTestUtils.h"
+#include "TestLexer.h"
+#include "gtest/gtest.h"
+
+#include "../../lib/Format/TemplateArgumentKeywordFixer.h"
+
+using testing::ScopedTrace;
+
+namespace clang {
+namespace format {
+namespace {
+
+class TemplateArgumentKeywordFixerTest : public ::testing::Test {
+protected:
+  std::string format(llvm::StringRef Code,
+ const std::vector &Ranges,
+ const FormatStyle &Style) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+FormattingAttemptStatus Status;
+tooling::Replacements Replaces =
+reformat(Style, Code, Ranges, "", &Status);
+EXPECT_TRUE(Status.FormatComplete);
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  std::string format(llvm::StringRef Code, const FormatStyle &Style) {
+return format(Code,
+  /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+  }
+
+  void _verifyFormat(const char *File, int Line, llvm::StringRef Expected,
+ llvm::StringRef Code, const FormatStyle &Style) {
+ScopedTrace t(File, Line, ::testing::Message() << Code.str());
+EXPECT_EQ(Expected.str(), format(Expected, Style))
+<< "Expected code is not stable";
+EXPECT_EQ(Expected.str(), format(Code, Style));
+EXPECT_EQ(Expected.str(), format(test::messUp(Code), Style));
+  }
+};
+
+#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
+
+TEST_F(TemplateArgumentKeywordFixerTest, DisabledByDefault) {
+  FormatStyle Style = getLLVMStyle();
+  EXPECT_EQ(Style.TemplateArgumentKeyword, FormatStyle::TAS_Leave);
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A",
+   "template  class A", Style);
+}
+
+TEST_F(TemplateArgumentKeywordFixerTest, FormatsAsClass) {
+  FormatStyle Style = getLLVMStyle();
+  Style.TemplateArgumentKeyword = FormatStyle::TAS_Class;
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A;",
+   "template  class A;", Style);
+  verifyFormat("template  class A;",
+   "template  class A;", Style);
+  verifyFormat("template  class Y> class A;",
+   "template  typename Y> class A;", Style);
+}
+
+TEST_F(TemplateArgumentKeywordFixerTest, ClassLeavesOtherTypenames) {
+  FormatStyle Style = getLLVMStyle();
+  Style.TemplateArgumentKeyword = FormatStyle::TAS_Class;
+  // `typename` outside of a template should stay unchanged
+  verifyFormat("typename T::nested", "typename T::nested", Style);
+  // `typename` inside a template should stay unchanged if it refers to a nested
+  // type
+  verifyFormat(
+  "template  class A;",
+  "template  class A;", Style);
+  // A legitimate `typename

[PATCH] D116290: [clang-format] Add enforcement of consistent `class`/typename` keyword for template arguments

2021-12-26 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang updated this revision to Diff 396237.
avogelsgesang added a comment.

Fix code formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116290/new/

https://reviews.llvm.org/D116290

Files:
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/CMakeLists.txt
  clang/lib/Format/Format.cpp
  clang/lib/Format/TemplateArgumentKeywordFixer.cpp
  clang/lib/Format/TemplateArgumentKeywordFixer.h
  clang/unittests/Format/CMakeLists.txt
  clang/unittests/Format/TemplateArgumentKeywordFixerTest.cpp

Index: clang/unittests/Format/TemplateArgumentKeywordFixerTest.cpp
===
--- /dev/null
+++ clang/unittests/Format/TemplateArgumentKeywordFixerTest.cpp
@@ -0,0 +1,170 @@
+//===- unittest/Format/TemplateArgumentKeywordFixerTest.cpp ---===//
+//
+// 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 "clang/Format/Format.h"
+
+#include "FormatTestUtils.h"
+#include "TestLexer.h"
+#include "gtest/gtest.h"
+
+#include "../../lib/Format/TemplateArgumentKeywordFixer.h"
+
+using testing::ScopedTrace;
+
+namespace clang {
+namespace format {
+namespace {
+
+class TemplateArgumentKeywordFixerTest : public ::testing::Test {
+protected:
+  std::string format(llvm::StringRef Code,
+ const std::vector &Ranges,
+ const FormatStyle &Style) {
+LLVM_DEBUG(llvm::errs() << "---\n");
+LLVM_DEBUG(llvm::errs() << Code << "\n\n");
+FormattingAttemptStatus Status;
+tooling::Replacements Replaces =
+reformat(Style, Code, Ranges, "", &Status);
+EXPECT_TRUE(Status.FormatComplete);
+auto Result = applyAllReplacements(Code, Replaces);
+EXPECT_TRUE(static_cast(Result));
+LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
+return *Result;
+  }
+
+  std::string format(llvm::StringRef Code, const FormatStyle &Style) {
+return format(Code,
+  /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style);
+  }
+
+  void _verifyFormat(const char *File, int Line, llvm::StringRef Expected,
+ llvm::StringRef Code, const FormatStyle &Style) {
+ScopedTrace t(File, Line, ::testing::Message() << Code.str());
+EXPECT_EQ(Expected.str(), format(Expected, Style))
+<< "Expected code is not stable";
+EXPECT_EQ(Expected.str(), format(Code, Style));
+EXPECT_EQ(Expected.str(), format(test::messUp(Code), Style));
+  }
+};
+
+#define verifyFormat(...) _verifyFormat(__FILE__, __LINE__, __VA_ARGS__)
+
+TEST_F(TemplateArgumentKeywordFixerTest, DisabledByDefault) {
+  FormatStyle Style = getLLVMStyle();
+  EXPECT_EQ(Style.TemplateArgumentKeyword, FormatStyle::TAS_Leave);
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A",
+   "template  class A", Style);
+}
+
+TEST_F(TemplateArgumentKeywordFixerTest, FormatsAsClass) {
+  FormatStyle Style = getLLVMStyle();
+  Style.TemplateArgumentKeyword = FormatStyle::TAS_Class;
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A", "template  class A",
+   Style);
+  verifyFormat("template  class A;",
+   "template  class A;", Style);
+  verifyFormat("template  class A;",
+   "template  class A;", Style);
+  verifyFormat("template  class Y> class A;",
+   "template  typename Y> class A;", Style);
+}
+
+TEST_F(TemplateArgumentKeywordFixerTest, ClassLeavesOtherTypenames) {
+  FormatStyle Style = getLLVMStyle();
+  Style.TemplateArgumentKeyword = FormatStyle::TAS_Class;
+  // `typename` outside of a template should stay unchanged
+  verifyFormat("typename T::nested", "typename T::nested", Style);
+  // `typename` inside a template should stay unchanged if it refers to a nested
+  // type
+  verifyFormat(
+  "template  class A;",
+  "template  class A;", Style);
+  // A legitimate `typename` might also occur in a nested list, directly after
+  // the `,` token It's not sufficient to just check for a comma in front of
+  // `typename`.
+  verifyFormat("template , class Z "
+   "= void> class A;",
+   "template , "
+   "typename Z = void> class A;",
+   Style);
+  // `typename` might also occur in a function call, not only in a type
+  verifyFormat("template (), class Z = "
+   "void> class A;",
+   "template (), "
+   "typename Z = void> class A;",
+   Style);
+  // `typename` might also 

[clang] 31cfb3f - [clang] Remove redundant calls to c_str() (NFC)

2021-12-26 Thread Kazu Hirata via cfe-commits

Author: Kazu Hirata
Date: 2021-12-26T13:31:40-08:00
New Revision: 31cfb3f4f6446512fa0170092af46783a0de9139

URL: 
https://github.com/llvm/llvm-project/commit/31cfb3f4f6446512fa0170092af46783a0de9139
DIFF: 
https://github.com/llvm/llvm-project/commit/31cfb3f4f6446512fa0170092af46783a0de9139.diff

LOG: [clang] Remove redundant calls to c_str() (NFC)

Identified with readability-redundant-string-cstr.

Added: 


Modified: 
clang/lib/CodeGen/CGOpenMPRuntime.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
clang/tools/clang-nvlink-wrapper/ClangNvlinkWrapper.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp 
b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index b23100d435b4..c314044c66dd 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -9551,7 +9551,7 @@ emitMappingInformation(CodeGenFunction &CGF, 
llvm::OpenMPIRBuilder &OMPBuilder,
   }
 
   PresumedLoc PLoc = CGF.getContext().getSourceManager().getPresumedLoc(Loc);
-  return OMPBuilder.getOrCreateSrcLocStr(PLoc.getFilename(), ExprName.c_str(),
+  return OMPBuilder.getOrCreateSrcLocStr(PLoc.getFilename(), ExprName,
  PLoc.getLine(), PLoc.getColumn());
 }
 

diff  --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 407f81a2ae09..ad50c66cb6c1 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1724,7 +1724,7 @@ bool tools::GetSDLFromOffloadArchive(
 std::string OutputLib = D.GetTemporaryPath(
 Twine(Prefix + Lib + "-" + Arch + "-" + Target).str(), "a");
 
-C.addTempFile(C.getArgs().MakeArgString(OutputLib.c_str()));
+C.addTempFile(C.getArgs().MakeArgString(OutputLib));
 
 ArgStringList CmdArgs;
 SmallString<128> DeviceTriple;
@@ -1747,20 +1747,20 @@ bool tools::GetSDLFromOffloadArchive(
 T.getToolChain().GetProgramPath("clang-offload-bundler"));
 
 ArgStringList UBArgs;
-UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg.c_str()));
-UBArgs.push_back(C.getArgs().MakeArgString(TypeArg.c_str()));
-UBArgs.push_back(C.getArgs().MakeArgString(InputArg.c_str()));
-UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg.c_str()));
-UBArgs.push_back(C.getArgs().MakeArgString(OutputArg.c_str()));
+UBArgs.push_back(C.getArgs().MakeArgString(UnbundleArg));
+UBArgs.push_back(C.getArgs().MakeArgString(TypeArg));
+UBArgs.push_back(C.getArgs().MakeArgString(InputArg));
+UBArgs.push_back(C.getArgs().MakeArgString(OffloadArg));
+UBArgs.push_back(C.getArgs().MakeArgString(OutputArg));
 
 // Add this flag to not exit from clang-offload-bundler if no compatible
 // code object is found in heterogenous archive library.
 std::string AdditionalArgs("-allow-missing-bundles");
-UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs.c_str()));
+UBArgs.push_back(C.getArgs().MakeArgString(AdditionalArgs));
 
 C.addCommand(std::make_unique(
 JA, T, ResponseFileSupport::AtFileCurCP(), UBProgram, UBArgs, Inputs,
-InputInfo(&JA, C.getArgs().MakeArgString(OutputLib.c_str();
+InputInfo(&JA, C.getArgs().MakeArgString(OutputLib;
 if (postClangLink)
   CC1Args.push_back("-mlink-builtin-bitcode");
 

diff  --git a/clang/tools/clang-nvlink-wrapper/ClangNvlinkWrapper.cpp 
b/clang/tools/clang-nvlink-wrapper/ClangNvlinkWrapper.cpp
index bc5b9a9f1fde..46a4f30ba881 100644
--- a/clang/tools/clang-nvlink-wrapper/ClangNvlinkWrapper.cpp
+++ b/clang/tools/clang-nvlink-wrapper/ClangNvlinkWrapper.cpp
@@ -63,7 +63,7 @@ static Error runNVLink(std::string NVLinkPath,
 NVLArgs.push_back(Arg);
   }
 
-  if (sys::ExecuteAndWait(NVLinkPath.c_str(), NVLArgs))
+  if (sys::ExecuteAndWait(NVLinkPath, NVLArgs))
 return createStringError(inconvertibleErrorCode(), "'nvlink' failed");
   return Error::success();
 }



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116290: [clang-format] Add enforcement of consistent `class`/typename` keyword for template arguments

2021-12-26 Thread Adrian Vogelsgesang via Phabricator via cfe-commits
avogelsgesang added reviewers: MyDeveloperDay, HazardyKnusperkeks, 
aaron.ballman, curdeius, sammccall, owenpan.
avogelsgesang added a comment.

Adding reviewers from D69764  to this change 
because I think it falls into the same category: It replaces tokens and could 
thereby potentially break code


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116290/new/

https://reviews.llvm.org/D116290

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116203: [clang] adds unary type transformations as compiler built-ins

2021-12-26 Thread Christopher Di Bella via Phabricator via cfe-commits
cjdb updated this revision to Diff 396248.
cjdb edited the summary of this revision.
cjdb added a comment.

adds more type traits


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116203/new/

https://reviews.llvm.org/D116203

Files:
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Format/FormatToken.cpp
  clang/lib/Lex/PPMacroExpansion.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateVariadic.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/SemaCXX/type-traits.cpp

Index: clang/test/SemaCXX/type-traits.cpp
===
--- clang/test/SemaCXX/type-traits.cpp
+++ clang/test/SemaCXX/type-traits.cpp
@@ -2854,3 +2854,552 @@
 #undef T16384
 #undef T32768
 } // namespace type_trait_expr_numargs_overflow
+
+struct S {};
+void check_add_const() {
+  { int a[T(__is_same(__add_const(void), const void))]; }
+  { int a[T(__is_same(__add_const(int), const int))]; }
+  { int a[T(__is_same(__add_const(const int), const int))]; }
+  { int a[T(__is_same(__add_const(volatile int), const volatile int))]; }
+  { int a[T(__is_same(__add_const(const volatile int), const volatile int))]; }
+  { int a[T(__is_same(__add_const(int*), int* const))]; }
+  { int a[T(__is_same(__add_const(int&), int&))]; }
+  { int a[T(__is_same(__add_const(int&&), int&&))]; }
+  { int a[T(__is_same(__add_const(int()), int()))]; }
+  { int a[T(__is_same(__add_const(int(*)()), int(* const)()))]; }
+  { int a[T(__is_same(__add_const(int(&)()), int(&)()))]; }
+
+  { int a[T(__is_same(__add_const(S), const S))]; }
+  { int a[T(__is_same(__add_const(const S), const S))]; }
+  { int a[T(__is_same(__add_const(volatile S), const volatile S))]; }
+  { int a[T(__is_same(__add_const(const volatile S), const volatile S))]; }
+  { int a[T(__is_same(__add_const(int S::*), int S::* const))]; }
+  { int a[T(__is_same(__add_const(int (S::*)()), int (S::* const)()))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() &), int (S::* const)() &))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() &&), int (S::* const)() &&))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() const), int (S::* const)() const))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() const&), int (S::* const)() const&))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() const&&), int (S::* const)() const&&))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() volatile), int (S::* const)() volatile))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() volatile&), int (S::* const)() volatile&))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() volatile&&), int (S::* const)() volatile&&))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() const volatile), int (S::* const)() const volatile))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() const volatile&), int (S::* const)() const volatile&))]; }
+  { int a[T(__is_same(__add_const(int (S::*)() const volatile&&), int (S::* const)() const volatile&&))]; }
+}
+
+void check_remove_const() {
+  { int a[T(__is_same(__remove_const(void), void))]; }
+  { int a[T(__is_same(__remove_const(const void), void))]; }
+  { int a[T(__is_same(__remove_const(int), int))]; }
+  { int a[T(__is_same(__remove_const(const int), int))]; }
+  { int a[T(__is_same(__remove_const(volatile int), volatile int))]; }
+  { int a[T(__is_same(__remove_const(const volatile int), volatile int))]; }
+  { int a[T(__is_same(__remove_const(int*), int*))]; }
+  { int a[T(__is_same(__remove_const(int* const), int*))]; }
+  { int a[T(__is_same(__remove_const(int const* const), int const*))]; }
+  { int a[T(__is_same(__remove_const(int&), int&))]; }
+  { int a[T(__is_same(__remove_const(int const&), int const&))]; }
+  { int a[T(__is_same(__remove_const(int&&), int&&))]; }
+  { int a[T(__is_same(__remove_const(int const&&), int const&&))]; }
+  { int a[T(__is_same(__remove_const(int()), int()))]; }
+  { int a[T(__is_same(__remove_const(int(* const)()), int(*)()))]; }
+  { int a[T(__is_same(__remove_const(int(&)()), int(&)()))]; }
+
+  { int a[T(__is_same(__remove_const(S), S))]; }
+  { int a[T(__is_same(__remove_const(const S),  S))]; }
+  { int a[T(__is_same(__remove_const(volatile S), volatile S))]; }
+  { int a[T(__is_same(__remove_const(const volatile S), volatile S))]; }
+  { int a[T(__is_same(__remove_const(int S::* const), int S::*))]; }
+  { int a[T(__is_same(__remove_const(int (S::* const)()), int (S::*)()))]; }
+  { int a[T(__is_same(__remove_const(int (S::* const)() &), int (S::*)() &))]; }
+  { int a[T(__is_same(__remove_const(int (S::* const)() &&), in

[PATCH] D116014: [clang][CodeGen] Remove the signed version of createExpression

2021-12-26 Thread Shao-Ce SUN via Phabricator via cfe-commits
achieveartificialintelligence added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116014/new/

https://reviews.llvm.org/D116014

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116294: [CodeCompletion] (mostly) fix completion in incomplete C++ ctor initializers.

2021-12-26 Thread Sam McCall via Phabricator via cfe-commits
sammccall created this revision.
sammccall added a reviewer: kadircet.
Herald added subscribers: usaxena95, arphaman.
sammccall requested review of this revision.
Herald added projects: clang, clang-tools-extra.
Herald added a subscriber: cfe-commits.

C++ member function bodies (including ctor initializers) are first captured
into a buffer and then parsed after the class is complete. (This allows
members to be referenced even if declared later).

When the boundary of the function body cannot be established, its buffer is
discarded and late-parsing never happens (it would surely fail).
For code completion this is the wrong tradeoff: the point of the parse is to
generate completions as a side-effect.
Today, when the ctor body wasn't typed yet there are no init list completions.
With this patch we parse such an init-list if it contains the completion point.

There's one caveat: the parser has to decide where to resume parsing members
after a broken init list. Often the first clear recovery point is *after* the
next member, so that member is missing from completion/signature help etc. e.g.

  struct S {
S() m  //<- completion here
int maaa;
int mbbb;
  }

Here "int maaa;" is treated as part of the init list, so "maaa" is not available
as a completion. Maybe in future indentation can be used to recognize that
this is a separate member, not part of the init list.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116294

Files:
  clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
  clang/lib/Parse/ParseCXXInlineMethods.cpp
  clang/test/CodeCompletion/ctor-initializer.cpp

Index: clang/test/CodeCompletion/ctor-initializer.cpp
===
--- clang/test/CodeCompletion/ctor-initializer.cpp
+++ clang/test/CodeCompletion/ctor-initializer.cpp
@@ -103,3 +103,25 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++98 -code-completion-at=%s:100:9 %s -o - | FileCheck -check-prefix=CHECK-CC11 %s
 // RUN: %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:100:9 %s -o - | FileCheck -check-prefix=CHECK-CC11 %s
 // CHECK-CC11: Pattern : Y(<#Y#>)
+
+// Test with incomplete init lists. (Relevant as parsing is *not* cut off).
+struct Incomplete1 {
+  Incomplete1() : mem
+
+  int member1;
+  int member2;
+};
+// RUN: not %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:109:19 %s -o - | FileCheck -check-prefix=CHECK-CC12 %s
+// FIXME: we should see both member1 and member2. But the parser consumes
+//member1 when searching for the end of the init list.
+// CHECK-CC12-NOT: member1(<#int#>)
+// CHECK-CC12: COMPLETION: Pattern : member2(<#int#>)
+
+struct Incomplete2 {
+  Incomplete2() : member2(
+
+  int member1;
+  int member2;
+};
+// RUN: not %clang_cc1 -fsyntax-only -std=c++14 -code-completion-at=%s:121:27 %s -o - | FileCheck -check-prefix=CHECK-CC13 %s
+// CHECK-CC13: PREFERRED-TYPE: int
Index: clang/lib/Parse/ParseCXXInlineMethods.cpp
===
--- clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -140,8 +140,23 @@
   // function body.
   if (ConsumeAndStoreFunctionPrologue(Toks)) {
 // We didn't find the left-brace we expected after the
-// constructor initializer; we already printed an error, and it's likely
-// impossible to recover, so don't try to parse this method later.
+// constructor initializer.
+
+// If we're code-completing and the completion point was in the broken
+// initializer, we want to parse it even though that will fail.
+if (PP.isCodeCompletionEnabled() &&
+llvm::any_of(Toks, [](const Token &Tok) {
+  return Tok.is(tok::code_completion);
+})) {
+  // If we gave up at the completion point, the initializer list was
+  // probably truncated, so don't eat more tokens.
+  if (!Toks.back().is(tok::code_completion))
+SkipMalformedDecl();
+  return FnD;
+}
+
+// We already printed an error, and it's likely impossible to recover,
+// so don't try to parse this method later.
 // Skip over the rest of the decl and back to somewhere that looks
 // reasonable.
 SkipMalformedDecl();
Index: clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
===
--- clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -1953,6 +1953,36 @@
   UnorderedElementsAre(AllOf(Scope("ns::X::"), Named("x_";
 }
 
+// Like other class members, constructor init lists have to parse what's below,
+// after the completion point.
+// But recovering from an incomplete constructor init list is particularly
+// tricky because the bulk of the list is not surrounded by brackets.
+TEST(CompletionTest, ConstructorInitListIncomplete) {
+  auto Results = completions(
+  R"cpp(
+namespace ns {
+  

[PATCH] D116014: [clang][CodeGen] Remove the signed version of createExpression

2021-12-26 Thread Robert Widmann via Phabricator via cfe-commits
CodaFi accepted this revision.
CodaFi added a comment.
This revision is now accepted and ready to land.

C API changes LGTM.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116014/new/

https://reviews.llvm.org/D116014

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D93844: [clang-format] Add possibility to be based on parent directory

2021-12-26 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew added inline comments.



Comment at: clang/lib/Format/Format.cpp:3067
+  if (!ChildFormatTextToApply.empty()) {
+assert(ChildFormatTextToApply.size() == 1);
+

Is there a reason behind limiting the number of children configs to 1 in this 
case? When the fallback is not used, more than 1 children configs are allowed 
(line 3036).

Sorry for digging this up, I came across this seemingly arbitrary decision when 
working on some changes to https://reviews.llvm.org/D72326


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D93844/new/

https://reviews.llvm.org/D93844

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D116298: Add option to specify explicit config file

2021-12-26 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew created this revision.
zwliew requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Specify a specific config file using --style=file:path/to/config/file


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116298

Files:
  clang/docs/ClangFormat.rst
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21586,6 +21586,64 @@
   }());
 }
 
+TEST(FormatStyle, GetStyleFromExternalFile) {
+  llvm::vfs::InMemoryFileSystem FS;
+  // Explicit format file in parent directory.
+  ASSERT_TRUE(
+  FS.addFile("/e/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+  ASSERT_TRUE(
+  FS.addFile("/e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style = getStyle("file:/e/explicit.clang-format",
+"/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE((bool)Style);
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Relative pah to a format file
+  ASSERT_TRUE(
+  FS.addFile("../../e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  Style = getStyle("file:../../e/explicit.clang-format",
+   "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE((bool)Style);
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Missing explicit format file
+  Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
+   "LLVM", "", &FS);
+  ASSERT_FALSE((bool)Style);
+  llvm::consumeError(Style.takeError());
+
+  // Format file from the filesystem
+  SmallString<128> FormatFilePath;
+  std::error_code ECF = llvm::sys::fs::createTemporaryFile(
+  "FormatFileTest", "tpl", FormatFilePath);
+  EXPECT_FALSE((bool)ECF);
+  llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
+  EXPECT_FALSE((bool)ECF);
+  FormatFileTest << "BasedOnStyle: Google\n";
+  FormatFileTest.close();
+
+  SmallString<128> TestFilePath;
+  std::error_code ECT =
+  llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
+  EXPECT_FALSE((bool)ECT);
+  llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
+  CodeFileTest << "int i;\n";
+  CodeFileTest.close();
+
+  std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
+  Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
+
+  llvm::sys::fs::remove(FormatFilePath.c_str());
+  llvm::sys::fs::remove(TestFilePath.c_str());
+  ASSERT_TRUE((bool)Style);
+  ASSERT_EQ(*Style, getGoogleStyle());
+}
+
 TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
   // Column limit is 20.
   std::string Code = "Type *a =\n"
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3181,6 +3181,8 @@
 ".clang-format file located in one of the parent\n"
 "directories of the source file (or current\n"
 "directory for stdin).\n"
+"Use -style=file: to explicitly specify"
+"the configuration file.\n"
 "Use -style=\"{key: value, ...}\" to set specific\n"
 "parameters, e.g.:\n"
 "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
@@ -3263,6 +3265,31 @@
   return Style;
   }
 
+  // User provided clang-format file using -style=file:path/to/format/file
+  // Check for explicit config filename
+  if (!Style.InheritsParentConfig &&
+  StyleName.startswith_insensitive("file:")) {
+auto ConfigFile = StyleName.substr(5);
+llvm::ErrorOr> Text =
+FS->getBufferForFile(ConfigFile.str());
+if (auto EC = Text.getError())
+  return make_string_error(EC.message());
+if (auto EC = parseConfiguration(*Text.get(), &Style, AllowUnknownOptions))
+  return make_string_error("Error reading " + ConfigFile + ": " +
+   EC.message());
+
+LLVM_DEBUG(llvm::dbgs()
+   << "Using configuration file " << ConfigFile << "\n");
+
+if (!Style.InheritsParentConfig)
+  return Style;
+
+// Search for parent configs starting from the parent directory of
+// ConfigFile
+FileName = ConfigFile;
+ChildFormatTextToApply.emplace_back(std::move(*Text));
+  }
+
   // If the style inherits the parent configuration it is a command line
   // configuration, which wants to inherit, so we have to skip the check of the
   // StyleName.
Index: clang/include/clang/Format/Format.h
===

[PATCH] D116299: [clang-format] Apply multiple children configs on fallback style

2021-12-26 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew created this revision.
zwliew requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Allow multiple children configs to be applied on top of the fallback style.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116299

Files:
  clang/lib/Format/Format.cpp


Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3390,17 +3390,16 @@
  UnsuitableConfigFiles);
 
   if (!ChildFormatTextToApply.empty()) {
-assert(ChildFormatTextToApply.size() == 1);
-
 LLVM_DEBUG(llvm::dbgs()
-   << "Applying child configuration on fallback style\n");
-
-auto Ec =
-parseConfiguration(*ChildFormatTextToApply.front(), &FallbackStyle,
-   AllowUnknownOptions, dropDiagnosticHandler);
-// It was already correctly parsed.
-assert(!Ec);
-static_cast(Ec);
+   << "Applying child configurations on fallback style\n");
+
+for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
+  auto Ec = parseConfiguration(*MemBuf, &FallbackStyle, 
AllowUnknownOptions,
+   dropDiagnosticHandler);
+  // It was already correctly parsed.
+  assert(!Ec);
+  static_cast(Ec);
+}
   }
 
   return FallbackStyle;


Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3390,17 +3390,16 @@
  UnsuitableConfigFiles);
 
   if (!ChildFormatTextToApply.empty()) {
-assert(ChildFormatTextToApply.size() == 1);
-
 LLVM_DEBUG(llvm::dbgs()
-   << "Applying child configuration on fallback style\n");
-
-auto Ec =
-parseConfiguration(*ChildFormatTextToApply.front(), &FallbackStyle,
-   AllowUnknownOptions, dropDiagnosticHandler);
-// It was already correctly parsed.
-assert(!Ec);
-static_cast(Ec);
+   << "Applying child configurations on fallback style\n");
+
+for (const auto &MemBuf : llvm::reverse(ChildFormatTextToApply)) {
+  auto Ec = parseConfiguration(*MemBuf, &FallbackStyle, AllowUnknownOptions,
+   dropDiagnosticHandler);
+  // It was already correctly parsed.
+  assert(!Ec);
+  static_cast(Ec);
+}
   }
 
   return FallbackStyle;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] ec501f1 - [clang][CodeGen] Remove the signed version of createExpression

2021-12-26 Thread Shao-Ce SUN via cfe-commits

Author: Shao-Ce SUN
Date: 2021-12-27T14:16:08+08:00
New Revision: ec501f15a8b8ace2b283732740d6d65d40d82e09

URL: 
https://github.com/llvm/llvm-project/commit/ec501f15a8b8ace2b283732740d6d65d40d82e09
DIFF: 
https://github.com/llvm/llvm-project/commit/ec501f15a8b8ace2b283732740d6d65d40d82e09.diff

LOG: [clang][CodeGen] Remove the signed version of createExpression

Fix a TODO. Remove the callers of this signed version and delete.

Reviewed By: CodaFi

Differential Revision: https://reviews.llvm.org/D116014

Added: 


Modified: 
clang/lib/CodeGen/CGDebugInfo.cpp
clang/lib/CodeGen/CGDebugInfo.h
llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
llvm/include/llvm-c/DebugInfo.h
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/IR/DIBuilder.cpp
llvm/lib/IR/DebugInfo.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CGDebugInfo.cpp 
b/clang/lib/CodeGen/CGDebugInfo.cpp
index 6e189a61dd206..b976dcb3058e7 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -722,7 +722,7 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType 
*BT) {
   auto *LowerBound =
   llvm::ConstantAsMetadata::get(llvm::ConstantInt::getSigned(
   llvm::Type::getInt64Ty(CGM.getLLVMContext()), 0));
-  SmallVector Expr(
+  SmallVector Expr(
   {llvm::dwarf::DW_OP_constu, NumElemsPerVG, llvm::dwarf::DW_OP_bregx,
/* AArch64::VG */ 46, 0, llvm::dwarf::DW_OP_mul,
llvm::dwarf::DW_OP_constu, 1, llvm::dwarf::DW_OP_minus});
@@ -768,7 +768,7 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType 
*BT) {
   }
 
   // Element count = (VLENB / SEW) x LMUL
-  SmallVector Expr(
+  SmallVector Expr(
   // The DW_OP_bregx operation has two operands: a register which is
   // specified by an unsigned LEB128 number, followed by a signed 
LEB128
   // offset.
@@ -4325,7 +4325,7 @@ void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
 }
 
 void CGDebugInfo::AppendAddressSpaceXDeref(
-unsigned AddressSpace, SmallVectorImpl &Expr) const {
+unsigned AddressSpace, SmallVectorImpl &Expr) const {
   Optional DWARFAddressSpace =
   CGM.getTarget().getDWARFAddressSpace(AddressSpace);
   if (!DWARFAddressSpace)
@@ -4494,7 +4494,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const 
VarDecl *VD,
 Line = getLineNumber(VD->getLocation());
 Column = getColumnNumber(VD->getLocation());
   }
-  SmallVector Expr;
+  SmallVector Expr;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (VD->isImplicit())
 Flags |= llvm::DINode::FlagArtificial;
@@ -4720,7 +4720,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
   target.getStructLayout(blockInfo.StructureType)
   ->getElementOffset(blockInfo.getCapture(VD).getIndex()));
 
-  SmallVector addr;
+  SmallVector addr;
   addr.push_back(llvm::dwarf::DW_OP_deref);
   addr.push_back(llvm::dwarf::DW_OP_plus_uconst);
   addr.push_back(offset.getQuantity());
@@ -5191,7 +5191,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable 
*Var,
   } else {
 auto Align = getDeclAlignIfRequired(D, CGM.getContext());
 
-SmallVector Expr;
+SmallVector Expr;
 unsigned AddressSpace =
 CGM.getContext().getTargetAddressSpace(D->getType());
 if (CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) {

diff  --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 14ff0eeabd21b..d782bd97f5903 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -363,7 +363,7 @@ class CGDebugInfo {
   /// Extended dereferencing mechanism is has the following format:
   /// DW_OP_constu  DW_OP_swap DW_OP_xderef
   void AppendAddressSpaceXDeref(unsigned AddressSpace,
-SmallVectorImpl &Expr) const;
+SmallVectorImpl &Expr) const;
 
   /// A helper function to collect debug info for the default elements of a
   /// block.

diff  --git a/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c 
b/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
index 794fa6b06ab69..81f4748c5518a 100644
--- a/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
+++ b/llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
@@ -865,7 +865,7 @@ value llvm_instr_set_debug_loc(LLVMValueRef Inst, 
LLVMMetadataRef Loc) {
 LLVMMetadataRef llvm_dibuild_create_constant_value_expression(value Builder,
   value Value) {
   return LLVMDIBuilderCreateConstantValueExpression(DIBuilder_val(Builder),
-(int64_t)Int_val(Value));
+(uint64_t)Int_val(Value));
 }
 
 LLVMMetadataRef llvm_dibuild_create_global_variable_expression_native(

diff  --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo

[PATCH] D116014: [clang][CodeGen] Remove the signed version of createExpression

2021-12-26 Thread Shao-Ce SUN via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGec501f15a8b8: [clang][CodeGen] Remove the signed version of 
createExpression (authored by achieveartificialintelligence).

Changed prior to commit:
  https://reviews.llvm.org/D116014?vs=395366&id=396272#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116014/new/

https://reviews.llvm.org/D116014

Files:
  clang/lib/CodeGen/CGDebugInfo.cpp
  clang/lib/CodeGen/CGDebugInfo.h
  llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
  llvm/include/llvm-c/DebugInfo.h
  llvm/include/llvm/IR/DIBuilder.h
  llvm/lib/IR/DIBuilder.cpp
  llvm/lib/IR/DebugInfo.cpp

Index: llvm/lib/IR/DebugInfo.cpp
===
--- llvm/lib/IR/DebugInfo.cpp
+++ llvm/lib/IR/DebugInfo.cpp
@@ -1436,14 +1436,14 @@
 }
 
 LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder,
-  int64_t *Addr, size_t Length) {
-  return wrap(unwrap(Builder)->createExpression(ArrayRef(Addr,
-  Length)));
+  uint64_t *Addr, size_t Length) {
+  return wrap(
+  unwrap(Builder)->createExpression(ArrayRef(Addr, Length)));
 }
 
 LLVMMetadataRef
 LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder,
-   int64_t Value) {
+   uint64_t Value) {
   return wrap(unwrap(Builder)->createConstantValueExpression(Value));
 }
 
Index: llvm/lib/IR/DIBuilder.cpp
===
--- llvm/lib/IR/DIBuilder.cpp
+++ llvm/lib/IR/DIBuilder.cpp
@@ -821,12 +821,6 @@
   return DIExpression::get(VMContext, Addr);
 }
 
-DIExpression *DIBuilder::createExpression(ArrayRef Signed) {
-  // TODO: Remove the callers of this signed version and delete.
-  SmallVector Addr(Signed.begin(), Signed.end());
-  return createExpression(Addr);
-}
-
 template 
 static DISubprogram *getSubprogram(bool IsDistinct, Ts &&...Args) {
   if (IsDistinct)
Index: llvm/include/llvm/IR/DIBuilder.h
===
--- llvm/include/llvm/IR/DIBuilder.h
+++ llvm/include/llvm/IR/DIBuilder.h
@@ -698,7 +698,6 @@
 /// variable which has a complex address expression for its address.
 /// \param AddrAn array of complex address operations.
 DIExpression *createExpression(ArrayRef Addr = None);
-DIExpression *createExpression(ArrayRef Addr);
 
 /// Create an expression for a variable that does not have an address, but
 /// does have a constant value.
Index: llvm/include/llvm-c/DebugInfo.h
===
--- llvm/include/llvm-c/DebugInfo.h
+++ llvm/include/llvm-c/DebugInfo.h
@@ -1102,7 +1102,7 @@
  * \param Length  Length of the address operation array.
  */
 LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder,
-  int64_t *Addr, size_t Length);
+  uint64_t *Addr, size_t Length);
 
 /**
  * Create a new descriptor for the specified variable that does not have an
@@ -1112,7 +1112,7 @@
  */
 LLVMMetadataRef
 LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder,
-   int64_t Value);
+   uint64_t Value);
 
 /**
  * Create a new descriptor for the specified variable.
Index: llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
===
--- llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
+++ llvm/bindings/ocaml/debuginfo/debuginfo_ocaml.c
@@ -865,7 +865,7 @@
 LLVMMetadataRef llvm_dibuild_create_constant_value_expression(value Builder,
   value Value) {
   return LLVMDIBuilderCreateConstantValueExpression(DIBuilder_val(Builder),
-(int64_t)Int_val(Value));
+(uint64_t)Int_val(Value));
 }
 
 LLVMMetadataRef llvm_dibuild_create_global_variable_expression_native(
Index: clang/lib/CodeGen/CGDebugInfo.h
===
--- clang/lib/CodeGen/CGDebugInfo.h
+++ clang/lib/CodeGen/CGDebugInfo.h
@@ -363,7 +363,7 @@
   /// Extended dereferencing mechanism is has the following format:
   /// DW_OP_constu  DW_OP_swap DW_OP_xderef
   void AppendAddressSpaceXDeref(unsigned AddressSpace,
-SmallVectorImpl &Expr) const;
+SmallVectorImpl &Expr) const;
 
   /// A helper function to collect debug info for the default elements of a
   /// block

[PATCH] D116014: [clang][CodeGen] Remove the signed version of createExpression

2021-12-26 Thread Shao-Ce SUN via Phabricator via cfe-commits
achieveartificialintelligence added a comment.

In D116014#3210212 , @CodaFi wrote:

> C API changes LGTM.

Thanks for your review!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D116014/new/

https://reviews.llvm.org/D116014

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72326: [clang-format] Rebased on master: Add option to specify explicit config file

2021-12-26 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew updated this revision to Diff 396273.
zwliew added a comment.

Support inheritance from parent configs via `BasedOnStyle: InheritParentConfig`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72326/new/

https://reviews.llvm.org/D72326

Files:
  clang/docs/ClangFormat.rst
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21586,6 +21586,64 @@
   }());
 }
 
+TEST(FormatStyle, GetStyleFromExternalFile) {
+  llvm::vfs::InMemoryFileSystem FS;
+  // Explicit format file in parent directory.
+  ASSERT_TRUE(
+  FS.addFile("/e/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+  ASSERT_TRUE(
+  FS.addFile("/e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style = getStyle("file:/e/explicit.clang-format",
+"/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE((bool)Style);
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Relative pah to a format file
+  ASSERT_TRUE(
+  FS.addFile("../../e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  Style = getStyle("file:../../e/explicit.clang-format",
+   "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE((bool)Style);
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Missing explicit format file
+  Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
+   "LLVM", "", &FS);
+  ASSERT_FALSE((bool)Style);
+  llvm::consumeError(Style.takeError());
+
+  // Format file from the filesystem
+  SmallString<128> FormatFilePath;
+  std::error_code ECF = llvm::sys::fs::createTemporaryFile(
+  "FormatFileTest", "tpl", FormatFilePath);
+  EXPECT_FALSE((bool)ECF);
+  llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
+  EXPECT_FALSE((bool)ECF);
+  FormatFileTest << "BasedOnStyle: Google\n";
+  FormatFileTest.close();
+
+  SmallString<128> TestFilePath;
+  std::error_code ECT =
+  llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
+  EXPECT_FALSE((bool)ECT);
+  llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
+  CodeFileTest << "int i;\n";
+  CodeFileTest.close();
+
+  std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
+  Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
+
+  llvm::sys::fs::remove(FormatFilePath.c_str());
+  llvm::sys::fs::remove(TestFilePath.c_str());
+  ASSERT_TRUE((bool)Style);
+  ASSERT_EQ(*Style, getGoogleStyle());
+}
+
 TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
   // Column limit is 20.
   std::string Code = "Type *a =\n"
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3181,6 +3181,8 @@
 ".clang-format file located in one of the parent\n"
 "directories of the source file (or current\n"
 "directory for stdin).\n"
+"Use -style=file: to explicitly specify"
+"the configuration file.\n"
 "Use -style=\"{key: value, ...}\" to set specific\n"
 "parameters, e.g.:\n"
 "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
@@ -3263,6 +3265,31 @@
   return Style;
   }
 
+  // User provided clang-format file using -style=file:path/to/format/file
+  // Check for explicit config filename
+  if (!Style.InheritsParentConfig &&
+  StyleName.startswith_insensitive("file:")) {
+auto ConfigFile = StyleName.substr(5);
+llvm::ErrorOr> Text =
+FS->getBufferForFile(ConfigFile.str());
+if (auto EC = Text.getError())
+  return make_string_error(EC.message());
+if (auto EC = parseConfiguration(*Text.get(), &Style, AllowUnknownOptions))
+  return make_string_error("Error reading " + ConfigFile + ": " +
+   EC.message());
+
+LLVM_DEBUG(llvm::dbgs()
+   << "Using configuration file " << ConfigFile << "\n");
+
+if (!Style.InheritsParentConfig)
+  return Style;
+
+// Search for parent configs starting from the parent directory of
+// ConfigFile
+FileName = ConfigFile;
+ChildFormatTextToApply.emplace_back(std::move(*Text));
+  }
+
   // If the style inherits the parent configuration it is a command line
   // configuration, which wants to inherit, so we have to skip the check of the
   // StyleName.
Index: clang/include/clang/Format/Format.h
==

[PATCH] D72326: [clang-format] Rebased on master: Add option to specify explicit config file

2021-12-26 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew added inline comments.



Comment at: clang/lib/Format/Format.cpp:3393
   if (!ChildFormatTextToApply.empty()) {
 assert(ChildFormatTextToApply.size() == 1);
 

Is there a reason for this to be limited to 1? I came across this case during 
testing, but I can't think of why this should be so.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72326/new/

https://reviews.llvm.org/D72326

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72326: [clang-format] Rebased on master: Add option to specify explicit config file

2021-12-26 Thread Zhao Wei Liew via Phabricator via cfe-commits
zwliew updated this revision to Diff 396274.
zwliew added a comment.

Add a test for inheritance from parent config with base


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72326/new/

https://reviews.llvm.org/D72326

Files:
  clang/docs/ClangFormat.rst
  clang/docs/ClangFormatStyleOptions.rst
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Format/Format.h
  clang/lib/Format/Format.cpp
  clang/unittests/Format/FormatTest.cpp

Index: clang/unittests/Format/FormatTest.cpp
===
--- clang/unittests/Format/FormatTest.cpp
+++ clang/unittests/Format/FormatTest.cpp
@@ -21584,6 +21584,70 @@
 Style.IndentWidth = 7;
 return Style;
   }());
+
+  // Test 9.9: use inheritance from a specific config file
+  Style9 = getStyle("file:/e/sub/sub/.clang-format", "/e/sub/sub/code.cpp",
+"none", "", &FS);
+  ASSERT_TRUE(static_cast(Style9));
+  ASSERT_EQ(*Style9, SubSubStyle);
+}
+
+TEST(FormatStyle, GetStyleFromExternalFile) {
+  llvm::vfs::InMemoryFileSystem FS;
+  // Explicit format file in parent directory.
+  ASSERT_TRUE(
+  FS.addFile("/e/.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
+  ASSERT_TRUE(
+  FS.addFile("/e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  ASSERT_TRUE(FS.addFile("/e/sub/sub/sub/test.cpp", 0,
+ llvm::MemoryBuffer::getMemBuffer("int i;")));
+  auto Style = getStyle("file:/e/explicit.clang-format",
+"/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Relative path to a format file
+  ASSERT_TRUE(
+  FS.addFile("../../e/explicit.clang-format", 0,
+ llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
+  Style = getStyle("file:../../e/explicit.clang-format",
+   "/e/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  ASSERT_TRUE(static_cast(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
+
+  // Missing explicit format file
+  Style = getStyle("file:/e/missing.clang-format", "/e/sub/sub/sub/test.cpp",
+   "LLVM", "", &FS);
+  ASSERT_FALSE(static_cast(Style));
+  llvm::consumeError(Style.takeError());
+
+  // Format file from the filesystem
+  SmallString<128> FormatFilePath;
+  std::error_code ECF = llvm::sys::fs::createTemporaryFile(
+  "FormatFileTest", "tpl", FormatFilePath);
+  EXPECT_FALSE((bool)ECF);
+  llvm::raw_fd_ostream FormatFileTest(FormatFilePath, ECF);
+  EXPECT_FALSE((bool)ECF);
+  FormatFileTest << "BasedOnStyle: Google\n";
+  FormatFileTest.close();
+
+  SmallString<128> TestFilePath;
+  std::error_code ECT =
+  llvm::sys::fs::createTemporaryFile("CodeFileTest", "cc", TestFilePath);
+  EXPECT_FALSE((bool)ECT);
+  llvm::raw_fd_ostream CodeFileTest(TestFilePath, ECT);
+  CodeFileTest << "int i;\n";
+  CodeFileTest.close();
+
+  std::string format_file_arg = std::string("file:") + FormatFilePath.c_str();
+  Style = getStyle(format_file_arg, TestFilePath, "LLVM", "", nullptr);
+
+  llvm::sys::fs::remove(FormatFilePath.c_str());
+  llvm::sys::fs::remove(TestFilePath.c_str());
+  ASSERT_TRUE(static_cast(Style));
+  ASSERT_EQ(*Style, getGoogleStyle());
 }
 
 TEST_F(ReplacementTest, FormatCodeAfterReplacements) {
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -3181,6 +3181,8 @@
 ".clang-format file located in one of the parent\n"
 "directories of the source file (or current\n"
 "directory for stdin).\n"
+"Use -style=file: to explicitly specify"
+"the configuration file.\n"
 "Use -style=\"{key: value, ...}\" to set specific\n"
 "parameters, e.g.:\n"
 "  -style=\"{BasedOnStyle: llvm, IndentWidth: 8}\"";
@@ -3263,6 +3265,31 @@
   return Style;
   }
 
+  // User provided clang-format file using -style=file:path/to/format/file
+  // Check for explicit config filename
+  if (!Style.InheritsParentConfig &&
+  StyleName.startswith_insensitive("file:")) {
+auto ConfigFile = StyleName.substr(5);
+llvm::ErrorOr> Text =
+FS->getBufferForFile(ConfigFile.str());
+if (auto EC = Text.getError())
+  return make_string_error(EC.message());
+if (auto EC = parseConfiguration(*Text.get(), &Style, AllowUnknownOptions))
+  return make_string_error("Error reading " + ConfigFile + ": " +
+   EC.message());
+
+LLVM_DEBUG(llvm::dbgs()
+   << "Using configuration file " << ConfigFile << "\n");
+
+if (!Style.InheritsParentConfig)
+  return Style;
+
+// Search for parent configs starting from the parent directory of
+// ConfigFile
+FileName = ConfigFile;
+ChildFormatTextToApply.emplace_back(std::move(*Text));
+  }
+
   // If the