Skip to content

Commit 8a44352

Browse files
author
git apple-llvm automerger
committed
Merge commit 'a42ce094d903' from llvm.org/main into next
2 parents edd54dd + a42ce09 commit 8a44352

File tree

9 files changed

+72
-8
lines changed

9 files changed

+72
-8
lines changed

clang-tools-extra/clangd/CodeComplete.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ struct CompletionCandidate {
215215
// Returns a token identifying the overload set this is part of.
216216
// 0 indicates it's not part of any overload set.
217217
size_t overloadSet(const CodeCompleteOptions &Opts, llvm::StringRef FileName,
218-
IncludeInserter *Inserter) const {
218+
IncludeInserter *Inserter,
219+
CodeCompletionContext::Kind CCContextKind) const {
219220
if (!Opts.BundleOverloads.value_or(false))
220221
return 0;
221222

@@ -224,7 +225,7 @@ struct CompletionCandidate {
224225
// bundle those, so we must resolve the header to be included here.
225226
std::string HeaderForHash;
226227
if (Inserter) {
227-
if (auto Header = headerToInsertIfAllowed(Opts)) {
228+
if (auto Header = headerToInsertIfAllowed(Opts, CCContextKind)) {
228229
if (auto HeaderFile = toHeaderFile(*Header, FileName)) {
229230
if (auto Spelled =
230231
Inserter->calculateIncludePath(*HeaderFile, FileName))
@@ -272,11 +273,21 @@ struct CompletionCandidate {
272273
return 0;
273274
}
274275

276+
bool contextAllowsHeaderInsertion(CodeCompletionContext::Kind Kind) const {
277+
// Explicitly disable insertions for forward declarations since they don't
278+
// reference the declaration.
279+
if (Kind == CodeCompletionContext::CCC_ObjCClassForwardDecl)
280+
return false;
281+
return true;
282+
}
283+
275284
// The best header to include if include insertion is allowed.
276285
std::optional<llvm::StringRef>
277-
headerToInsertIfAllowed(const CodeCompleteOptions &Opts) const {
286+
headerToInsertIfAllowed(const CodeCompleteOptions &Opts,
287+
CodeCompletionContext::Kind ContextKind) const {
278288
if (Opts.InsertIncludes == CodeCompleteOptions::NeverInsert ||
279-
RankedIncludeHeaders.empty())
289+
RankedIncludeHeaders.empty() ||
290+
!contextAllowsHeaderInsertion(ContextKind))
280291
return std::nullopt;
281292
if (SemaResult && SemaResult->Declaration) {
282293
// Avoid inserting new #include if the declaration is found in the current
@@ -402,7 +413,8 @@ struct CodeCompletionBuilder {
402413
std::move(*Spelled),
403414
Includes.shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted));
404415
};
405-
bool ShouldInsert = C.headerToInsertIfAllowed(Opts).has_value();
416+
bool ShouldInsert =
417+
C.headerToInsertIfAllowed(Opts, ContextKind).has_value();
406418
Symbol::IncludeDirective Directive = insertionDirective(Opts);
407419
// Calculate include paths and edits for all possible headers.
408420
for (const auto &Inc : C.RankedIncludeHeaders) {
@@ -781,6 +793,7 @@ bool contextAllowsIndex(enum CodeCompletionContext::Kind K) {
781793
case CodeCompletionContext::CCC_ObjCInterfaceName:
782794
case CodeCompletionContext::CCC_Symbol:
783795
case CodeCompletionContext::CCC_SymbolOrNewName:
796+
case CodeCompletionContext::CCC_ObjCClassForwardDecl:
784797
return true;
785798
case CodeCompletionContext::CCC_OtherWithMacros:
786799
case CodeCompletionContext::CCC_DotMemberAccess:
@@ -1423,6 +1436,10 @@ bool includeSymbolFromIndex(CodeCompletionContext::Kind Kind,
14231436
else if (Kind == CodeCompletionContext::CCC_ObjCProtocolName)
14241437
// Don't show anything else in ObjC protocol completions.
14251438
return false;
1439+
1440+
if (Kind == CodeCompletionContext::CCC_ObjCClassForwardDecl)
1441+
return Sym.SymInfo.Kind == index::SymbolKind::Class &&
1442+
Sym.SymInfo.Lang == index::SymbolLanguage::ObjC;
14261443
return true;
14271444
}
14281445

@@ -1833,8 +1850,8 @@ class CodeCompleteFlow {
18331850
assert(IdentifierResult);
18341851
C.Name = IdentifierResult->Name;
18351852
}
1836-
if (auto OverloadSet =
1837-
C.overloadSet(Opts, FileName, Inserter ? &*Inserter : nullptr)) {
1853+
if (auto OverloadSet = C.overloadSet(
1854+
Opts, FileName, Inserter ? &*Inserter : nullptr, CCContextKind)) {
18381855
auto Ret = BundleLookup.try_emplace(OverloadSet, Bundles.size());
18391856
if (Ret.second)
18401857
Bundles.emplace_back();

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3434,6 +3434,20 @@ TEST(CompletionTest, ObjectiveCCategoryFromIndexIgnored) {
34343434
EXPECT_THAT(Results.Completions, IsEmpty());
34353435
}
34363436

3437+
TEST(CompletionTest, ObjectiveCForwardDeclFromIndex) {
3438+
Symbol FoodClass = objcClass("FoodClass");
3439+
FoodClass.IncludeHeaders.emplace_back("\"Foo.h\"", 2, Symbol::Import);
3440+
Symbol SymFood = objcProtocol("Food");
3441+
auto Results = completions("@class Foo^", {SymFood, FoodClass},
3442+
/*Opts=*/{}, "Foo.m");
3443+
3444+
// Should only give class names without any include insertion.
3445+
EXPECT_THAT(Results.Completions,
3446+
UnorderedElementsAre(AllOf(named("FoodClass"),
3447+
kind(CompletionItemKind::Class),
3448+
Not(insertInclude()))));
3449+
}
3450+
34373451
TEST(CompletionTest, CursorInSnippets) {
34383452
clangd::CodeCompleteOptions Options;
34393453
Options.EnableSnippets = true;

clang/include/clang/Sema/CodeCompleteConsumer.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,10 @@ class CodeCompletionContext {
333333

334334
/// An unknown context, in which we are recovering from a parsing
335335
/// error and don't know which completions we should give.
336-
CCC_Recovery
336+
CCC_Recovery,
337+
338+
/// Code completion in a @class forward declaration.
339+
CCC_ObjCClassForwardDecl
337340
};
338341

339342
using VisitedContextSet = llvm::SmallPtrSet<DeclContext *, 8>;

clang/include/clang/Sema/Sema.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13477,6 +13477,7 @@ class Sema final {
1347713477
ArrayRef<IdentifierLocPair> Protocols);
1347813478
void CodeCompleteObjCProtocolDecl(Scope *S);
1347913479
void CodeCompleteObjCInterfaceDecl(Scope *S);
13480+
void CodeCompleteObjCClassForwardDecl(Scope *S);
1348013481
void CodeCompleteObjCSuperclass(Scope *S,
1348113482
IdentifierInfo *ClassName,
1348213483
SourceLocation ClassNameLoc);

clang/lib/Frontend/ASTUnit.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ static uint64_t getDeclShowContexts(const NamedDecl *ND,
322322
if (ID->getDefinition())
323323
Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
324324
Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
325+
Contexts |= (1LL << CodeCompletionContext::CCC_ObjCClassForwardDecl);
325326
}
326327

327328
// Deal with tag names.
@@ -2031,6 +2032,7 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
20312032
case CodeCompletionContext::CCC_IncludedFile:
20322033
case CodeCompletionContext::CCC_Attribute:
20332034
case CodeCompletionContext::CCC_NewName:
2035+
case CodeCompletionContext::CCC_ObjCClassForwardDecl:
20342036
// We're looking for nothing, or we're looking for names that cannot
20352037
// be hidden.
20362038
return;

clang/lib/Parse/ParseObjc.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@ Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
153153

154154
while (true) {
155155
MaybeSkipAttributes(tok::objc_class);
156+
if (Tok.is(tok::code_completion)) {
157+
cutOffParsing();
158+
Actions.CodeCompleteObjCClassForwardDecl(getCurScope());
159+
return Actions.ConvertDeclToDeclGroup(nullptr);
160+
}
156161
if (expectIdentifier()) {
157162
SkipUntil(tok::semi);
158163
return Actions.ConvertDeclToDeclGroup(nullptr);

clang/lib/Sema/CodeCompleteConsumer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ bool CodeCompletionContext::wantConstructorResults() const {
8383
case CCC_ObjCCategoryName:
8484
case CCC_IncludedFile:
8585
case CCC_Attribute:
86+
case CCC_ObjCClassForwardDecl:
8687
return false;
8788
}
8889

@@ -166,6 +167,8 @@ StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
166167
return "Attribute";
167168
case CCKind::CCC_Recovery:
168169
return "Recovery";
170+
case CCKind::CCC_ObjCClassForwardDecl:
171+
return "ObjCClassForwardDecl";
169172
}
170173
llvm_unreachable("Invalid CodeCompletionContext::Kind!");
171174
}

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8418,6 +8418,24 @@ void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
84188418
Results.data(), Results.size());
84198419
}
84208420

8421+
void Sema::CodeCompleteObjCClassForwardDecl(Scope *S) {
8422+
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
8423+
CodeCompleter->getCodeCompletionTUInfo(),
8424+
CodeCompletionContext::CCC_ObjCClassForwardDecl);
8425+
Results.EnterNewScope();
8426+
8427+
if (CodeCompleter->includeGlobals()) {
8428+
// Add all classes.
8429+
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
8430+
false, Results);
8431+
}
8432+
8433+
Results.ExitScope();
8434+
8435+
HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
8436+
Results.data(), Results.size());
8437+
}
8438+
84218439
void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
84228440
SourceLocation ClassNameLoc) {
84238441
ResultBuilder Results(*this, CodeCompleter->getAllocator(),

clang/tools/libclang/CIndexCodeCompletion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,7 @@ static unsigned long long getContextsForContextKind(
537537
case CodeCompletionContext::CCC_Other:
538538
case CodeCompletionContext::CCC_ObjCInterface:
539539
case CodeCompletionContext::CCC_ObjCImplementation:
540+
case CodeCompletionContext::CCC_ObjCClassForwardDecl:
540541
case CodeCompletionContext::CCC_NewName:
541542
case CodeCompletionContext::CCC_MacroName:
542543
case CodeCompletionContext::CCC_PreprocessorExpression:

0 commit comments

Comments
 (0)