https://github.com/Lancern updated 
https://github.com/llvm/llvm-project/pull/75937

>From 8924617e16a035730c4c33f17c726dd5e5bb5f00 Mon Sep 17 00:00:00 2001
From: Sirui Mu <msrlanc...@gmail.com>
Date: Tue, 19 Dec 2023 22:24:23 +0800
Subject: [PATCH] [clangd][Sema] add noexcept to override functions during code
 completion

---
 clang/lib/Sema/SemaCodeComplete.cpp     | 77 ++++++++++++++++---------
 clang/test/CodeCompletion/overrides.cpp | 14 +++++
 2 files changed, 64 insertions(+), 27 deletions(-)

diff --git a/clang/lib/Sema/SemaCodeComplete.cpp 
b/clang/lib/Sema/SemaCodeComplete.cpp
index f9f7c192f19d2..e206425bf1c9d 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/AttributeCommonInfo.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/Specifiers.h"
 #include "clang/Lex/HeaderSearch.h"
@@ -184,7 +185,7 @@ class ResultBuilder {
 
   /// Overloaded C++ member functions found by SemaLookup.
   /// Used to determine when one overload is dominated by another.
-  llvm::DenseMap<std::pair<DeclContext *, /*Name*/uintptr_t>, ShadowMapEntry>
+  llvm::DenseMap<std::pair<DeclContext *, /*Name=*/uintptr_t>, ShadowMapEntry>
       OverloadMap;
 
   /// If we're potentially referring to a C++ member function, the set
@@ -1432,16 +1433,16 @@ void ResultBuilder::AddResult(Result R, DeclContext 
*CurContext,
         }
         // Detect cases where a ref-qualified method cannot be invoked.
         switch (Method->getRefQualifier()) {
-          case RQ_LValue:
-            if (ObjectKind != VK_LValue && !MethodQuals.hasConst())
-              return;
-            break;
-          case RQ_RValue:
-            if (ObjectKind == VK_LValue)
-              return;
-            break;
-          case RQ_None:
-            break;
+        case RQ_LValue:
+          if (ObjectKind != VK_LValue && !MethodQuals.hasConst())
+            return;
+          break;
+        case RQ_RValue:
+          if (ObjectKind == VK_LValue)
+            return;
+          break;
+        case RQ_None:
+          break;
         }
 
         /// Check whether this dominates another overloaded method, which 
should
@@ -1490,9 +1491,7 @@ void ResultBuilder::AddResult(Result R) {
 void ResultBuilder::EnterNewScope() { ShadowMaps.emplace_back(); }
 
 /// Exit from the current scope.
-void ResultBuilder::ExitScope() {
-  ShadowMaps.pop_back();
-}
+void ResultBuilder::ExitScope() { ShadowMaps.pop_back(); }
 
 /// Determines whether this given declaration will be found by
 /// ordinary name lookup.
@@ -2557,7 +2556,8 @@ 
AddOrdinaryNameResults(SemaCodeCompletion::ParserCompletionContext CCC,
       ReturnType = Method->getReturnType();
     else if (SemaRef.getCurBlock() &&
              !SemaRef.getCurBlock()->ReturnType.isNull())
-      ReturnType = SemaRef.getCurBlock()->ReturnType;;
+      ReturnType = SemaRef.getCurBlock()->ReturnType;
+    ;
     if (ReturnType.isNull() || ReturnType->isVoidType()) {
       Builder.AddTypedTextChunk("return");
       Builder.AddChunk(CodeCompletionString::CK_SemiColon);
@@ -3427,6 +3427,25 @@ 
AddFunctionTypeQualsToCompletionString(CodeCompletionBuilder &Result,
   Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
 }
 
+static void
+AddFunctionExceptSpecToCompletionString(std::string &NameAndSignature,
+                                        const FunctionDecl *Function) {
+  const auto *Proto = Function->getType()->getAs<FunctionProtoType>();
+  if (!Proto)
+    return;
+
+  auto ExceptInfo = Proto->getExceptionSpecInfo();
+  switch (ExceptInfo.Type) {
+  case EST_BasicNoexcept:
+  case EST_NoexceptTrue:
+    NameAndSignature += " noexcept";
+    break;
+
+  default:
+    break;
+  }
+}
+
 /// Add the name of the given declaration
 static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy 
&Policy,
                               const NamedDecl *ND,
@@ -3642,6 +3661,13 @@ 
CodeCompletionResult::createCodeCompletionStringForOverride(
   std::string NameAndSignature;
   // For overrides all chunks go into the result, none are informative.
   printOverrideString(*CCS, BeforeName, NameAndSignature);
+
+  // If the virtual function is declared with "noexcept", add it in the result
+  // code completion string.
+  const auto *VirtualFunc = dyn_cast<FunctionDecl>(Declaration);
+  assert(VirtualFunc && "overridden decl must be a function");
+  AddFunctionExceptSpecToCompletionString(NameAndSignature, VirtualFunc);
+
   NameAndSignature += " override";
 
   Result.AddTextChunk(Result.getAllocator().CopyString(BeforeName));
@@ -4886,7 +4912,8 @@ static void AddEnumerators(ResultBuilder &Results, 
ASTContext &Context,
                            EnumDecl *Enum, DeclContext *CurContext,
                            const CoveredEnumerators &Enumerators) {
   NestedNameSpecifier *Qualifier = Enumerators.SuggestedQualifier;
-  if (Context.getLangOpts().CPlusPlus && !Qualifier && 
Enumerators.Seen.empty()) {
+  if (Context.getLangOpts().CPlusPlus && !Qualifier &&
+      Enumerators.Seen.empty()) {
     // If there are no prior enumerators in C++, check whether we have to
     // qualify the names of the enumerators that we suggest, because they
     // may not be visible in this scope.
@@ -5292,8 +5319,7 @@ AddObjCProperties(const CodeCompletionContext &CCContext,
                         AllowNullaryMethods, CurContext, AddedProperties,
                         Results, IsBaseExprStatement, IsClassProperty,
                         /*InOriginalClass*/ false);
-  } else if (const auto *Category =
-                 dyn_cast<ObjCCategoryDecl>(Container)) {
+  } else if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
     // Look through protocols.
     for (auto *P : Category->protocols())
       AddObjCProperties(CCContext, P, AllowCategories, AllowNullaryMethods,
@@ -6159,8 +6185,7 @@ void SemaCodeCompletion::CodeCompleteCase(Scope *S) {
 
     Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
     if (auto *DRE = dyn_cast<DeclRefExpr>(CaseVal))
-      if (auto *Enumerator =
-              dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
+      if (auto *Enumerator = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
         // We look into the AST of the case statement to determine which
         // enumerator was named. Alternatively, we could compute the value of
         // the integral constant expression, then compare it against the
@@ -8480,11 +8505,10 @@ void 
SemaCodeCompletion::CodeCompleteObjCInstanceMessage(
       return;
     RecExpr = Conv.get();
   }
-  QualType ReceiverType = RecExpr
-                              ? RecExpr->getType()
-                              : Super ? Context.getObjCObjectPointerType(
-                                            
Context.getObjCInterfaceType(Super))
-                                      : Context.getObjCIdType();
+  QualType ReceiverType = RecExpr ? RecExpr->getType()
+                          : Super ? Context.getObjCObjectPointerType(
+                                        Context.getObjCInterfaceType(Super))
+                                  : Context.getObjCIdType();
 
   // If we're messaging an expression with type "id" or "Class", check
   // whether we know something special about the receiver that allows
@@ -10356,8 +10380,7 @@ void 
SemaCodeCompletion::CodeCompleteIncludedFile(llvm::StringRef Dir,
   };
 
   // Helper: scans IncludeDir for nice files, and adds results for each.
-  auto AddFilesFromIncludeDir = [&](StringRef IncludeDir,
-                                    bool IsSystem,
+  auto AddFilesFromIncludeDir = [&](StringRef IncludeDir, bool IsSystem,
                                     DirectoryLookup::LookupType_t LookupType) {
     llvm::SmallString<128> Dir = IncludeDir;
     if (!NativeRelDir.empty()) {
diff --git a/clang/test/CodeCompletion/overrides.cpp 
b/clang/test/CodeCompletion/overrides.cpp
index 7f330904eede9..0a12973f846b7 100644
--- a/clang/test/CodeCompletion/overrides.cpp
+++ b/clang/test/CodeCompletion/overrides.cpp
@@ -41,3 +41,17 @@ void func() {
 // Runs completion at empty line on line 37.
 // RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-5):1 %s -o 
- | FileCheck -check-prefix=CHECK-CC4 %s
 // CHECK-CC4: COMPLETION: Pattern : void vfunc(bool param, int p) override{{$}}
+
+class NoexceptBase {
+ public:
+  virtual void method() noexcept;
+};
+
+class NoexceptDerived : public NoexceptBase {
+ public:
+  met;
+};
+
+// Runs completion at met^ on line 52.
+// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:%(line-4):6 %s -o 
- | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: COMPLETION: Pattern : void method() noexcept override{{$}}

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

Reply via email to