1e5dd7070Spatrick //===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===// 2e5dd7070Spatrick // 3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information. 5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e5dd7070Spatrick // 7e5dd7070Spatrick //===----------------------------------------------------------------------===// 8e5dd7070Spatrick // 9e5dd7070Spatrick // This file implements the CodeCompleteConsumer class. 10e5dd7070Spatrick // 11e5dd7070Spatrick //===----------------------------------------------------------------------===// 12e5dd7070Spatrick 13e5dd7070Spatrick #include "clang/Sema/CodeCompleteConsumer.h" 14e5dd7070Spatrick #include "clang-c/Index.h" 15e5dd7070Spatrick #include "clang/AST/Decl.h" 16e5dd7070Spatrick #include "clang/AST/DeclBase.h" 17e5dd7070Spatrick #include "clang/AST/DeclObjC.h" 18e5dd7070Spatrick #include "clang/AST/DeclTemplate.h" 19e5dd7070Spatrick #include "clang/AST/DeclarationName.h" 20e5dd7070Spatrick #include "clang/AST/Type.h" 21e5dd7070Spatrick #include "clang/Basic/IdentifierTable.h" 22e5dd7070Spatrick #include "clang/Lex/Preprocessor.h" 23e5dd7070Spatrick #include "clang/Sema/Sema.h" 24e5dd7070Spatrick #include "llvm/ADT/SmallString.h" 25e5dd7070Spatrick #include "llvm/ADT/SmallVector.h" 26ec727ea7Spatrick #include "llvm/ADT/StringExtras.h" 27e5dd7070Spatrick #include "llvm/ADT/StringRef.h" 28e5dd7070Spatrick #include "llvm/ADT/Twine.h" 29e5dd7070Spatrick #include "llvm/Support/Casting.h" 30e5dd7070Spatrick #include "llvm/Support/Compiler.h" 31e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h" 32e5dd7070Spatrick #include "llvm/Support/FormatVariadic.h" 33e5dd7070Spatrick #include "llvm/Support/raw_ostream.h" 34e5dd7070Spatrick #include <algorithm> 35e5dd7070Spatrick #include <cassert> 36e5dd7070Spatrick #include <cstdint> 37e5dd7070Spatrick #include <string> 38e5dd7070Spatrick 39e5dd7070Spatrick using namespace clang; 40e5dd7070Spatrick 41e5dd7070Spatrick //===----------------------------------------------------------------------===// 42e5dd7070Spatrick // Code completion context implementation 43e5dd7070Spatrick //===----------------------------------------------------------------------===// 44e5dd7070Spatrick 45e5dd7070Spatrick bool CodeCompletionContext::wantConstructorResults() const { 46e5dd7070Spatrick switch (CCKind) { 47e5dd7070Spatrick case CCC_Recovery: 48e5dd7070Spatrick case CCC_Statement: 49e5dd7070Spatrick case CCC_Expression: 50e5dd7070Spatrick case CCC_ObjCMessageReceiver: 51e5dd7070Spatrick case CCC_ParenthesizedExpression: 52e5dd7070Spatrick case CCC_Symbol: 53e5dd7070Spatrick case CCC_SymbolOrNewName: 54e5dd7070Spatrick return true; 55e5dd7070Spatrick 56e5dd7070Spatrick case CCC_TopLevel: 57e5dd7070Spatrick case CCC_ObjCInterface: 58e5dd7070Spatrick case CCC_ObjCImplementation: 59e5dd7070Spatrick case CCC_ObjCIvarList: 60e5dd7070Spatrick case CCC_ClassStructUnion: 61e5dd7070Spatrick case CCC_DotMemberAccess: 62e5dd7070Spatrick case CCC_ArrowMemberAccess: 63e5dd7070Spatrick case CCC_ObjCPropertyAccess: 64e5dd7070Spatrick case CCC_EnumTag: 65e5dd7070Spatrick case CCC_UnionTag: 66e5dd7070Spatrick case CCC_ClassOrStructTag: 67e5dd7070Spatrick case CCC_ObjCProtocolName: 68e5dd7070Spatrick case CCC_Namespace: 69e5dd7070Spatrick case CCC_Type: 70e5dd7070Spatrick case CCC_NewName: 71e5dd7070Spatrick case CCC_MacroName: 72e5dd7070Spatrick case CCC_MacroNameUse: 73e5dd7070Spatrick case CCC_PreprocessorExpression: 74e5dd7070Spatrick case CCC_PreprocessorDirective: 75e5dd7070Spatrick case CCC_NaturalLanguage: 76e5dd7070Spatrick case CCC_SelectorName: 77e5dd7070Spatrick case CCC_TypeQualifiers: 78e5dd7070Spatrick case CCC_Other: 79e5dd7070Spatrick case CCC_OtherWithMacros: 80e5dd7070Spatrick case CCC_ObjCInstanceMessage: 81e5dd7070Spatrick case CCC_ObjCClassMessage: 82e5dd7070Spatrick case CCC_ObjCInterfaceName: 83e5dd7070Spatrick case CCC_ObjCCategoryName: 84e5dd7070Spatrick case CCC_IncludedFile: 85e5dd7070Spatrick return false; 86e5dd7070Spatrick } 87e5dd7070Spatrick 88e5dd7070Spatrick llvm_unreachable("Invalid CodeCompletionContext::Kind!"); 89e5dd7070Spatrick } 90e5dd7070Spatrick 91e5dd7070Spatrick StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) { 92e5dd7070Spatrick using CCKind = CodeCompletionContext::Kind; 93e5dd7070Spatrick switch (Kind) { 94e5dd7070Spatrick case CCKind::CCC_Other: 95e5dd7070Spatrick return "Other"; 96e5dd7070Spatrick case CCKind::CCC_OtherWithMacros: 97e5dd7070Spatrick return "OtherWithMacros"; 98e5dd7070Spatrick case CCKind::CCC_TopLevel: 99e5dd7070Spatrick return "TopLevel"; 100e5dd7070Spatrick case CCKind::CCC_ObjCInterface: 101e5dd7070Spatrick return "ObjCInterface"; 102e5dd7070Spatrick case CCKind::CCC_ObjCImplementation: 103e5dd7070Spatrick return "ObjCImplementation"; 104e5dd7070Spatrick case CCKind::CCC_ObjCIvarList: 105e5dd7070Spatrick return "ObjCIvarList"; 106e5dd7070Spatrick case CCKind::CCC_ClassStructUnion: 107e5dd7070Spatrick return "ClassStructUnion"; 108e5dd7070Spatrick case CCKind::CCC_Statement: 109e5dd7070Spatrick return "Statement"; 110e5dd7070Spatrick case CCKind::CCC_Expression: 111e5dd7070Spatrick return "Expression"; 112e5dd7070Spatrick case CCKind::CCC_ObjCMessageReceiver: 113e5dd7070Spatrick return "ObjCMessageReceiver"; 114e5dd7070Spatrick case CCKind::CCC_DotMemberAccess: 115e5dd7070Spatrick return "DotMemberAccess"; 116e5dd7070Spatrick case CCKind::CCC_ArrowMemberAccess: 117e5dd7070Spatrick return "ArrowMemberAccess"; 118e5dd7070Spatrick case CCKind::CCC_ObjCPropertyAccess: 119e5dd7070Spatrick return "ObjCPropertyAccess"; 120e5dd7070Spatrick case CCKind::CCC_EnumTag: 121e5dd7070Spatrick return "EnumTag"; 122e5dd7070Spatrick case CCKind::CCC_UnionTag: 123e5dd7070Spatrick return "UnionTag"; 124e5dd7070Spatrick case CCKind::CCC_ClassOrStructTag: 125e5dd7070Spatrick return "ClassOrStructTag"; 126e5dd7070Spatrick case CCKind::CCC_ObjCProtocolName: 127e5dd7070Spatrick return "ObjCProtocolName"; 128e5dd7070Spatrick case CCKind::CCC_Namespace: 129e5dd7070Spatrick return "Namespace"; 130e5dd7070Spatrick case CCKind::CCC_Type: 131e5dd7070Spatrick return "Type"; 132e5dd7070Spatrick case CCKind::CCC_NewName: 133e5dd7070Spatrick return "NewName"; 134e5dd7070Spatrick case CCKind::CCC_Symbol: 135e5dd7070Spatrick return "Symbol"; 136e5dd7070Spatrick case CCKind::CCC_SymbolOrNewName: 137e5dd7070Spatrick return "SymbolOrNewName"; 138e5dd7070Spatrick case CCKind::CCC_MacroName: 139e5dd7070Spatrick return "MacroName"; 140e5dd7070Spatrick case CCKind::CCC_MacroNameUse: 141e5dd7070Spatrick return "MacroNameUse"; 142e5dd7070Spatrick case CCKind::CCC_PreprocessorExpression: 143e5dd7070Spatrick return "PreprocessorExpression"; 144e5dd7070Spatrick case CCKind::CCC_PreprocessorDirective: 145e5dd7070Spatrick return "PreprocessorDirective"; 146e5dd7070Spatrick case CCKind::CCC_NaturalLanguage: 147e5dd7070Spatrick return "NaturalLanguage"; 148e5dd7070Spatrick case CCKind::CCC_SelectorName: 149e5dd7070Spatrick return "SelectorName"; 150e5dd7070Spatrick case CCKind::CCC_TypeQualifiers: 151e5dd7070Spatrick return "TypeQualifiers"; 152e5dd7070Spatrick case CCKind::CCC_ParenthesizedExpression: 153e5dd7070Spatrick return "ParenthesizedExpression"; 154e5dd7070Spatrick case CCKind::CCC_ObjCInstanceMessage: 155e5dd7070Spatrick return "ObjCInstanceMessage"; 156e5dd7070Spatrick case CCKind::CCC_ObjCClassMessage: 157e5dd7070Spatrick return "ObjCClassMessage"; 158e5dd7070Spatrick case CCKind::CCC_ObjCInterfaceName: 159e5dd7070Spatrick return "ObjCInterfaceName"; 160e5dd7070Spatrick case CCKind::CCC_ObjCCategoryName: 161e5dd7070Spatrick return "ObjCCategoryName"; 162e5dd7070Spatrick case CCKind::CCC_IncludedFile: 163e5dd7070Spatrick return "IncludedFile"; 164e5dd7070Spatrick case CCKind::CCC_Recovery: 165e5dd7070Spatrick return "Recovery"; 166e5dd7070Spatrick } 167e5dd7070Spatrick llvm_unreachable("Invalid CodeCompletionContext::Kind!"); 168e5dd7070Spatrick } 169e5dd7070Spatrick 170e5dd7070Spatrick //===----------------------------------------------------------------------===// 171e5dd7070Spatrick // Code completion string implementation 172e5dd7070Spatrick //===----------------------------------------------------------------------===// 173e5dd7070Spatrick 174e5dd7070Spatrick CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text) 175e5dd7070Spatrick : Kind(Kind), Text("") { 176e5dd7070Spatrick switch (Kind) { 177e5dd7070Spatrick case CK_TypedText: 178e5dd7070Spatrick case CK_Text: 179e5dd7070Spatrick case CK_Placeholder: 180e5dd7070Spatrick case CK_Informative: 181e5dd7070Spatrick case CK_ResultType: 182e5dd7070Spatrick case CK_CurrentParameter: 183e5dd7070Spatrick this->Text = Text; 184e5dd7070Spatrick break; 185e5dd7070Spatrick 186e5dd7070Spatrick case CK_Optional: 187e5dd7070Spatrick llvm_unreachable("Optional strings cannot be created from text"); 188e5dd7070Spatrick 189e5dd7070Spatrick case CK_LeftParen: 190e5dd7070Spatrick this->Text = "("; 191e5dd7070Spatrick break; 192e5dd7070Spatrick 193e5dd7070Spatrick case CK_RightParen: 194e5dd7070Spatrick this->Text = ")"; 195e5dd7070Spatrick break; 196e5dd7070Spatrick 197e5dd7070Spatrick case CK_LeftBracket: 198e5dd7070Spatrick this->Text = "["; 199e5dd7070Spatrick break; 200e5dd7070Spatrick 201e5dd7070Spatrick case CK_RightBracket: 202e5dd7070Spatrick this->Text = "]"; 203e5dd7070Spatrick break; 204e5dd7070Spatrick 205e5dd7070Spatrick case CK_LeftBrace: 206e5dd7070Spatrick this->Text = "{"; 207e5dd7070Spatrick break; 208e5dd7070Spatrick 209e5dd7070Spatrick case CK_RightBrace: 210e5dd7070Spatrick this->Text = "}"; 211e5dd7070Spatrick break; 212e5dd7070Spatrick 213e5dd7070Spatrick case CK_LeftAngle: 214e5dd7070Spatrick this->Text = "<"; 215e5dd7070Spatrick break; 216e5dd7070Spatrick 217e5dd7070Spatrick case CK_RightAngle: 218e5dd7070Spatrick this->Text = ">"; 219e5dd7070Spatrick break; 220e5dd7070Spatrick 221e5dd7070Spatrick case CK_Comma: 222e5dd7070Spatrick this->Text = ", "; 223e5dd7070Spatrick break; 224e5dd7070Spatrick 225e5dd7070Spatrick case CK_Colon: 226e5dd7070Spatrick this->Text = ":"; 227e5dd7070Spatrick break; 228e5dd7070Spatrick 229e5dd7070Spatrick case CK_SemiColon: 230e5dd7070Spatrick this->Text = ";"; 231e5dd7070Spatrick break; 232e5dd7070Spatrick 233e5dd7070Spatrick case CK_Equal: 234e5dd7070Spatrick this->Text = " = "; 235e5dd7070Spatrick break; 236e5dd7070Spatrick 237e5dd7070Spatrick case CK_HorizontalSpace: 238e5dd7070Spatrick this->Text = " "; 239e5dd7070Spatrick break; 240e5dd7070Spatrick 241e5dd7070Spatrick case CK_VerticalSpace: 242e5dd7070Spatrick this->Text = "\n"; 243e5dd7070Spatrick break; 244e5dd7070Spatrick } 245e5dd7070Spatrick } 246e5dd7070Spatrick 247e5dd7070Spatrick CodeCompletionString::Chunk 248e5dd7070Spatrick CodeCompletionString::Chunk::CreateText(const char *Text) { 249e5dd7070Spatrick return Chunk(CK_Text, Text); 250e5dd7070Spatrick } 251e5dd7070Spatrick 252e5dd7070Spatrick CodeCompletionString::Chunk 253e5dd7070Spatrick CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) { 254e5dd7070Spatrick Chunk Result; 255e5dd7070Spatrick Result.Kind = CK_Optional; 256e5dd7070Spatrick Result.Optional = Optional; 257e5dd7070Spatrick return Result; 258e5dd7070Spatrick } 259e5dd7070Spatrick 260e5dd7070Spatrick CodeCompletionString::Chunk 261e5dd7070Spatrick CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) { 262e5dd7070Spatrick return Chunk(CK_Placeholder, Placeholder); 263e5dd7070Spatrick } 264e5dd7070Spatrick 265e5dd7070Spatrick CodeCompletionString::Chunk 266e5dd7070Spatrick CodeCompletionString::Chunk::CreateInformative(const char *Informative) { 267e5dd7070Spatrick return Chunk(CK_Informative, Informative); 268e5dd7070Spatrick } 269e5dd7070Spatrick 270e5dd7070Spatrick CodeCompletionString::Chunk 271e5dd7070Spatrick CodeCompletionString::Chunk::CreateResultType(const char *ResultType) { 272e5dd7070Spatrick return Chunk(CK_ResultType, ResultType); 273e5dd7070Spatrick } 274e5dd7070Spatrick 275e5dd7070Spatrick CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter( 276e5dd7070Spatrick const char *CurrentParameter) { 277e5dd7070Spatrick return Chunk(CK_CurrentParameter, CurrentParameter); 278e5dd7070Spatrick } 279e5dd7070Spatrick 280e5dd7070Spatrick CodeCompletionString::CodeCompletionString( 281e5dd7070Spatrick const Chunk *Chunks, unsigned NumChunks, unsigned Priority, 282e5dd7070Spatrick CXAvailabilityKind Availability, const char **Annotations, 283e5dd7070Spatrick unsigned NumAnnotations, StringRef ParentName, const char *BriefComment) 284e5dd7070Spatrick : NumChunks(NumChunks), NumAnnotations(NumAnnotations), Priority(Priority), 285e5dd7070Spatrick Availability(Availability), ParentName(ParentName), 286e5dd7070Spatrick BriefComment(BriefComment) { 287e5dd7070Spatrick assert(NumChunks <= 0xffff); 288e5dd7070Spatrick assert(NumAnnotations <= 0xffff); 289e5dd7070Spatrick 290e5dd7070Spatrick Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1); 291e5dd7070Spatrick for (unsigned I = 0; I != NumChunks; ++I) 292e5dd7070Spatrick StoredChunks[I] = Chunks[I]; 293e5dd7070Spatrick 294e5dd7070Spatrick const char **StoredAnnotations = 295e5dd7070Spatrick reinterpret_cast<const char **>(StoredChunks + NumChunks); 296e5dd7070Spatrick for (unsigned I = 0; I != NumAnnotations; ++I) 297e5dd7070Spatrick StoredAnnotations[I] = Annotations[I]; 298e5dd7070Spatrick } 299e5dd7070Spatrick 300e5dd7070Spatrick unsigned CodeCompletionString::getAnnotationCount() const { 301e5dd7070Spatrick return NumAnnotations; 302e5dd7070Spatrick } 303e5dd7070Spatrick 304e5dd7070Spatrick const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const { 305e5dd7070Spatrick if (AnnotationNr < NumAnnotations) 306e5dd7070Spatrick return reinterpret_cast<const char *const *>(end())[AnnotationNr]; 307e5dd7070Spatrick else 308e5dd7070Spatrick return nullptr; 309e5dd7070Spatrick } 310e5dd7070Spatrick 311e5dd7070Spatrick std::string CodeCompletionString::getAsString() const { 312e5dd7070Spatrick std::string Result; 313e5dd7070Spatrick llvm::raw_string_ostream OS(Result); 314e5dd7070Spatrick 315e5dd7070Spatrick for (const Chunk &C : *this) { 316e5dd7070Spatrick switch (C.Kind) { 317e5dd7070Spatrick case CK_Optional: 318e5dd7070Spatrick OS << "{#" << C.Optional->getAsString() << "#}"; 319e5dd7070Spatrick break; 320e5dd7070Spatrick case CK_Placeholder: 321e5dd7070Spatrick OS << "<#" << C.Text << "#>"; 322e5dd7070Spatrick break; 323e5dd7070Spatrick case CK_Informative: 324e5dd7070Spatrick case CK_ResultType: 325e5dd7070Spatrick OS << "[#" << C.Text << "#]"; 326e5dd7070Spatrick break; 327e5dd7070Spatrick case CK_CurrentParameter: 328e5dd7070Spatrick OS << "<#" << C.Text << "#>"; 329e5dd7070Spatrick break; 330e5dd7070Spatrick default: 331e5dd7070Spatrick OS << C.Text; 332e5dd7070Spatrick break; 333e5dd7070Spatrick } 334e5dd7070Spatrick } 335e5dd7070Spatrick return OS.str(); 336e5dd7070Spatrick } 337e5dd7070Spatrick 338e5dd7070Spatrick const char *CodeCompletionString::getTypedText() const { 339e5dd7070Spatrick for (const Chunk &C : *this) 340e5dd7070Spatrick if (C.Kind == CK_TypedText) 341e5dd7070Spatrick return C.Text; 342e5dd7070Spatrick 343e5dd7070Spatrick return nullptr; 344e5dd7070Spatrick } 345e5dd7070Spatrick 346e5dd7070Spatrick const char *CodeCompletionAllocator::CopyString(const Twine &String) { 347e5dd7070Spatrick SmallString<128> Data; 348e5dd7070Spatrick StringRef Ref = String.toStringRef(Data); 349e5dd7070Spatrick // FIXME: It would be more efficient to teach Twine to tell us its size and 350e5dd7070Spatrick // then add a routine there to fill in an allocated char* with the contents 351e5dd7070Spatrick // of the string. 352e5dd7070Spatrick char *Mem = (char *)Allocate(Ref.size() + 1, 1); 353e5dd7070Spatrick std::copy(Ref.begin(), Ref.end(), Mem); 354e5dd7070Spatrick Mem[Ref.size()] = 0; 355e5dd7070Spatrick return Mem; 356e5dd7070Spatrick } 357e5dd7070Spatrick 358e5dd7070Spatrick StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) { 359*a9ac8606Spatrick if (!isa<NamedDecl>(DC)) 360e5dd7070Spatrick return {}; 361e5dd7070Spatrick 362e5dd7070Spatrick // Check whether we've already cached the parent name. 363e5dd7070Spatrick StringRef &CachedParentName = ParentNames[DC]; 364e5dd7070Spatrick if (!CachedParentName.empty()) 365e5dd7070Spatrick return CachedParentName; 366e5dd7070Spatrick 367e5dd7070Spatrick // If we already processed this DeclContext and assigned empty to it, the 368e5dd7070Spatrick // data pointer will be non-null. 369e5dd7070Spatrick if (CachedParentName.data() != nullptr) 370e5dd7070Spatrick return {}; 371e5dd7070Spatrick 372e5dd7070Spatrick // Find the interesting names. 373e5dd7070Spatrick SmallVector<const DeclContext *, 2> Contexts; 374e5dd7070Spatrick while (DC && !DC->isFunctionOrMethod()) { 375e5dd7070Spatrick if (const auto *ND = dyn_cast<NamedDecl>(DC)) { 376e5dd7070Spatrick if (ND->getIdentifier()) 377e5dd7070Spatrick Contexts.push_back(DC); 378e5dd7070Spatrick } 379e5dd7070Spatrick 380e5dd7070Spatrick DC = DC->getParent(); 381e5dd7070Spatrick } 382e5dd7070Spatrick 383e5dd7070Spatrick { 384e5dd7070Spatrick SmallString<128> S; 385e5dd7070Spatrick llvm::raw_svector_ostream OS(S); 386e5dd7070Spatrick bool First = true; 387e5dd7070Spatrick for (unsigned I = Contexts.size(); I != 0; --I) { 388e5dd7070Spatrick if (First) 389e5dd7070Spatrick First = false; 390e5dd7070Spatrick else { 391e5dd7070Spatrick OS << "::"; 392e5dd7070Spatrick } 393e5dd7070Spatrick 394e5dd7070Spatrick const DeclContext *CurDC = Contexts[I - 1]; 395e5dd7070Spatrick if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC)) 396e5dd7070Spatrick CurDC = CatImpl->getCategoryDecl(); 397e5dd7070Spatrick 398e5dd7070Spatrick if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) { 399e5dd7070Spatrick const ObjCInterfaceDecl *Interface = Cat->getClassInterface(); 400e5dd7070Spatrick if (!Interface) { 401e5dd7070Spatrick // Assign an empty StringRef but with non-null data to distinguish 402e5dd7070Spatrick // between empty because we didn't process the DeclContext yet. 403e5dd7070Spatrick CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0); 404e5dd7070Spatrick return {}; 405e5dd7070Spatrick } 406e5dd7070Spatrick 407e5dd7070Spatrick OS << Interface->getName() << '(' << Cat->getName() << ')'; 408e5dd7070Spatrick } else { 409e5dd7070Spatrick OS << cast<NamedDecl>(CurDC)->getName(); 410e5dd7070Spatrick } 411e5dd7070Spatrick } 412e5dd7070Spatrick 413e5dd7070Spatrick CachedParentName = AllocatorRef->CopyString(OS.str()); 414e5dd7070Spatrick } 415e5dd7070Spatrick 416e5dd7070Spatrick return CachedParentName; 417e5dd7070Spatrick } 418e5dd7070Spatrick 419e5dd7070Spatrick CodeCompletionString *CodeCompletionBuilder::TakeString() { 420e5dd7070Spatrick void *Mem = getAllocator().Allocate( 421e5dd7070Spatrick sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() + 422e5dd7070Spatrick sizeof(const char *) * Annotations.size(), 423e5dd7070Spatrick alignof(CodeCompletionString)); 424e5dd7070Spatrick CodeCompletionString *Result = new (Mem) CodeCompletionString( 425e5dd7070Spatrick Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(), 426e5dd7070Spatrick Annotations.size(), ParentName, BriefComment); 427e5dd7070Spatrick Chunks.clear(); 428e5dd7070Spatrick return Result; 429e5dd7070Spatrick } 430e5dd7070Spatrick 431e5dd7070Spatrick void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) { 432e5dd7070Spatrick Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text)); 433e5dd7070Spatrick } 434e5dd7070Spatrick 435e5dd7070Spatrick void CodeCompletionBuilder::AddTextChunk(const char *Text) { 436e5dd7070Spatrick Chunks.push_back(Chunk::CreateText(Text)); 437e5dd7070Spatrick } 438e5dd7070Spatrick 439e5dd7070Spatrick void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) { 440e5dd7070Spatrick Chunks.push_back(Chunk::CreateOptional(Optional)); 441e5dd7070Spatrick } 442e5dd7070Spatrick 443e5dd7070Spatrick void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) { 444e5dd7070Spatrick Chunks.push_back(Chunk::CreatePlaceholder(Placeholder)); 445e5dd7070Spatrick } 446e5dd7070Spatrick 447e5dd7070Spatrick void CodeCompletionBuilder::AddInformativeChunk(const char *Text) { 448e5dd7070Spatrick Chunks.push_back(Chunk::CreateInformative(Text)); 449e5dd7070Spatrick } 450e5dd7070Spatrick 451e5dd7070Spatrick void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) { 452e5dd7070Spatrick Chunks.push_back(Chunk::CreateResultType(ResultType)); 453e5dd7070Spatrick } 454e5dd7070Spatrick 455e5dd7070Spatrick void CodeCompletionBuilder::AddCurrentParameterChunk( 456e5dd7070Spatrick const char *CurrentParameter) { 457e5dd7070Spatrick Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter)); 458e5dd7070Spatrick } 459e5dd7070Spatrick 460e5dd7070Spatrick void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK, 461e5dd7070Spatrick const char *Text) { 462e5dd7070Spatrick Chunks.push_back(Chunk(CK, Text)); 463e5dd7070Spatrick } 464e5dd7070Spatrick 465e5dd7070Spatrick void CodeCompletionBuilder::addParentContext(const DeclContext *DC) { 466e5dd7070Spatrick if (DC->isTranslationUnit()) 467e5dd7070Spatrick return; 468e5dd7070Spatrick 469e5dd7070Spatrick if (DC->isFunctionOrMethod()) 470e5dd7070Spatrick return; 471e5dd7070Spatrick 472*a9ac8606Spatrick if (!isa<NamedDecl>(DC)) 473e5dd7070Spatrick return; 474e5dd7070Spatrick 475e5dd7070Spatrick ParentName = getCodeCompletionTUInfo().getParentName(DC); 476e5dd7070Spatrick } 477e5dd7070Spatrick 478e5dd7070Spatrick void CodeCompletionBuilder::addBriefComment(StringRef Comment) { 479e5dd7070Spatrick BriefComment = Allocator.CopyString(Comment); 480e5dd7070Spatrick } 481e5dd7070Spatrick 482e5dd7070Spatrick //===----------------------------------------------------------------------===// 483e5dd7070Spatrick // Code completion overload candidate implementation 484e5dd7070Spatrick //===----------------------------------------------------------------------===// 485e5dd7070Spatrick FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const { 486e5dd7070Spatrick if (getKind() == CK_Function) 487e5dd7070Spatrick return Function; 488e5dd7070Spatrick else if (getKind() == CK_FunctionTemplate) 489e5dd7070Spatrick return FunctionTemplate->getTemplatedDecl(); 490e5dd7070Spatrick else 491e5dd7070Spatrick return nullptr; 492e5dd7070Spatrick } 493e5dd7070Spatrick 494e5dd7070Spatrick const FunctionType * 495e5dd7070Spatrick CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { 496e5dd7070Spatrick switch (Kind) { 497e5dd7070Spatrick case CK_Function: 498e5dd7070Spatrick return Function->getType()->getAs<FunctionType>(); 499e5dd7070Spatrick 500e5dd7070Spatrick case CK_FunctionTemplate: 501e5dd7070Spatrick return FunctionTemplate->getTemplatedDecl() 502e5dd7070Spatrick ->getType() 503e5dd7070Spatrick ->getAs<FunctionType>(); 504e5dd7070Spatrick 505e5dd7070Spatrick case CK_FunctionType: 506e5dd7070Spatrick return Type; 507e5dd7070Spatrick } 508e5dd7070Spatrick 509e5dd7070Spatrick llvm_unreachable("Invalid CandidateKind!"); 510e5dd7070Spatrick } 511e5dd7070Spatrick 512e5dd7070Spatrick //===----------------------------------------------------------------------===// 513e5dd7070Spatrick // Code completion consumer implementation 514e5dd7070Spatrick //===----------------------------------------------------------------------===// 515e5dd7070Spatrick 516e5dd7070Spatrick CodeCompleteConsumer::~CodeCompleteConsumer() = default; 517e5dd7070Spatrick 518e5dd7070Spatrick bool PrintingCodeCompleteConsumer::isResultFilteredOut( 519e5dd7070Spatrick StringRef Filter, CodeCompletionResult Result) { 520e5dd7070Spatrick switch (Result.Kind) { 521e5dd7070Spatrick case CodeCompletionResult::RK_Declaration: 522e5dd7070Spatrick return !(Result.Declaration->getIdentifier() && 523e5dd7070Spatrick Result.Declaration->getIdentifier()->getName().startswith(Filter)); 524e5dd7070Spatrick case CodeCompletionResult::RK_Keyword: 525e5dd7070Spatrick return !StringRef(Result.Keyword).startswith(Filter); 526e5dd7070Spatrick case CodeCompletionResult::RK_Macro: 527e5dd7070Spatrick return !Result.Macro->getName().startswith(Filter); 528e5dd7070Spatrick case CodeCompletionResult::RK_Pattern: 529e5dd7070Spatrick return !(Result.Pattern->getTypedText() && 530e5dd7070Spatrick StringRef(Result.Pattern->getTypedText()).startswith(Filter)); 531e5dd7070Spatrick } 532e5dd7070Spatrick llvm_unreachable("Unknown code completion result Kind."); 533e5dd7070Spatrick } 534e5dd7070Spatrick 535e5dd7070Spatrick void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults( 536e5dd7070Spatrick Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results, 537e5dd7070Spatrick unsigned NumResults) { 538e5dd7070Spatrick std::stable_sort(Results, Results + NumResults); 539e5dd7070Spatrick 540e5dd7070Spatrick if (!Context.getPreferredType().isNull()) 541e5dd7070Spatrick OS << "PREFERRED-TYPE: " << Context.getPreferredType().getAsString() 542e5dd7070Spatrick << "\n"; 543e5dd7070Spatrick 544e5dd7070Spatrick StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); 545e5dd7070Spatrick // Print the completions. 546e5dd7070Spatrick for (unsigned I = 0; I != NumResults; ++I) { 547e5dd7070Spatrick if (!Filter.empty() && isResultFilteredOut(Filter, Results[I])) 548e5dd7070Spatrick continue; 549e5dd7070Spatrick OS << "COMPLETION: "; 550e5dd7070Spatrick switch (Results[I].Kind) { 551e5dd7070Spatrick case CodeCompletionResult::RK_Declaration: 552e5dd7070Spatrick OS << *Results[I].Declaration; 553e5dd7070Spatrick { 554e5dd7070Spatrick std::vector<std::string> Tags; 555e5dd7070Spatrick if (Results[I].Hidden) 556e5dd7070Spatrick Tags.push_back("Hidden"); 557e5dd7070Spatrick if (Results[I].InBaseClass) 558e5dd7070Spatrick Tags.push_back("InBase"); 559e5dd7070Spatrick if (Results[I].Availability == 560e5dd7070Spatrick CXAvailabilityKind::CXAvailability_NotAccessible) 561e5dd7070Spatrick Tags.push_back("Inaccessible"); 562e5dd7070Spatrick if (!Tags.empty()) 563e5dd7070Spatrick OS << " (" << llvm::join(Tags, ",") << ")"; 564e5dd7070Spatrick } 565e5dd7070Spatrick if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( 566e5dd7070Spatrick SemaRef, Context, getAllocator(), CCTUInfo, 567e5dd7070Spatrick includeBriefComments())) { 568e5dd7070Spatrick OS << " : " << CCS->getAsString(); 569e5dd7070Spatrick if (const char *BriefComment = CCS->getBriefComment()) 570e5dd7070Spatrick OS << " : " << BriefComment; 571e5dd7070Spatrick } 572ec727ea7Spatrick break; 573ec727ea7Spatrick 574ec727ea7Spatrick case CodeCompletionResult::RK_Keyword: 575ec727ea7Spatrick OS << Results[I].Keyword; 576ec727ea7Spatrick break; 577ec727ea7Spatrick 578ec727ea7Spatrick case CodeCompletionResult::RK_Macro: 579ec727ea7Spatrick OS << Results[I].Macro->getName(); 580ec727ea7Spatrick if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( 581ec727ea7Spatrick SemaRef, Context, getAllocator(), CCTUInfo, 582ec727ea7Spatrick includeBriefComments())) { 583ec727ea7Spatrick OS << " : " << CCS->getAsString(); 584ec727ea7Spatrick } 585ec727ea7Spatrick break; 586ec727ea7Spatrick 587ec727ea7Spatrick case CodeCompletionResult::RK_Pattern: 588ec727ea7Spatrick OS << "Pattern : " << Results[I].Pattern->getAsString(); 589ec727ea7Spatrick break; 590ec727ea7Spatrick } 591e5dd7070Spatrick for (const FixItHint &FixIt : Results[I].FixIts) { 592e5dd7070Spatrick const SourceLocation BLoc = FixIt.RemoveRange.getBegin(); 593e5dd7070Spatrick const SourceLocation ELoc = FixIt.RemoveRange.getEnd(); 594e5dd7070Spatrick 595e5dd7070Spatrick SourceManager &SM = SemaRef.SourceMgr; 596e5dd7070Spatrick std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc); 597e5dd7070Spatrick std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc); 598e5dd7070Spatrick // Adjust for token ranges. 599e5dd7070Spatrick if (FixIt.RemoveRange.isTokenRange()) 600e5dd7070Spatrick EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts); 601e5dd7070Spatrick 602e5dd7070Spatrick OS << " (requires fix-it:" 603e5dd7070Spatrick << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':' 604e5dd7070Spatrick << SM.getColumnNumber(BInfo.first, BInfo.second) << '-' 605e5dd7070Spatrick << SM.getLineNumber(EInfo.first, EInfo.second) << ':' 606e5dd7070Spatrick << SM.getColumnNumber(EInfo.first, EInfo.second) << "}" 607e5dd7070Spatrick << " to \"" << FixIt.CodeToInsert << "\")"; 608e5dd7070Spatrick } 609e5dd7070Spatrick OS << '\n'; 610e5dd7070Spatrick } 611e5dd7070Spatrick } 612e5dd7070Spatrick 613e5dd7070Spatrick // This function is used solely to preserve the former presentation of overloads 614e5dd7070Spatrick // by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString 615e5dd7070Spatrick // needs to be improved for printing the newer and more detailed overload 616e5dd7070Spatrick // chunks. 617e5dd7070Spatrick static std::string getOverloadAsString(const CodeCompletionString &CCS) { 618e5dd7070Spatrick std::string Result; 619e5dd7070Spatrick llvm::raw_string_ostream OS(Result); 620e5dd7070Spatrick 621e5dd7070Spatrick for (auto &C : CCS) { 622e5dd7070Spatrick switch (C.Kind) { 623e5dd7070Spatrick case CodeCompletionString::CK_Informative: 624e5dd7070Spatrick case CodeCompletionString::CK_ResultType: 625e5dd7070Spatrick OS << "[#" << C.Text << "#]"; 626e5dd7070Spatrick break; 627e5dd7070Spatrick 628e5dd7070Spatrick case CodeCompletionString::CK_CurrentParameter: 629e5dd7070Spatrick OS << "<#" << C.Text << "#>"; 630e5dd7070Spatrick break; 631e5dd7070Spatrick 632e5dd7070Spatrick // FIXME: We can also print optional parameters of an overload. 633e5dd7070Spatrick case CodeCompletionString::CK_Optional: 634e5dd7070Spatrick break; 635e5dd7070Spatrick 636e5dd7070Spatrick default: 637e5dd7070Spatrick OS << C.Text; 638e5dd7070Spatrick break; 639e5dd7070Spatrick } 640e5dd7070Spatrick } 641e5dd7070Spatrick return OS.str(); 642e5dd7070Spatrick } 643e5dd7070Spatrick 644e5dd7070Spatrick void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( 645e5dd7070Spatrick Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates, 646e5dd7070Spatrick unsigned NumCandidates, SourceLocation OpenParLoc) { 647e5dd7070Spatrick OS << "OPENING_PAREN_LOC: "; 648e5dd7070Spatrick OpenParLoc.print(OS, SemaRef.getSourceManager()); 649e5dd7070Spatrick OS << "\n"; 650e5dd7070Spatrick 651e5dd7070Spatrick for (unsigned I = 0; I != NumCandidates; ++I) { 652e5dd7070Spatrick if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString( 653e5dd7070Spatrick CurrentArg, SemaRef, getAllocator(), CCTUInfo, 654e5dd7070Spatrick includeBriefComments())) { 655e5dd7070Spatrick OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n"; 656e5dd7070Spatrick } 657e5dd7070Spatrick } 658e5dd7070Spatrick } 659e5dd7070Spatrick 660e5dd7070Spatrick /// Retrieve the effective availability of the given declaration. 661e5dd7070Spatrick static AvailabilityResult getDeclAvailability(const Decl *D) { 662e5dd7070Spatrick AvailabilityResult AR = D->getAvailability(); 663e5dd7070Spatrick if (isa<EnumConstantDecl>(D)) 664e5dd7070Spatrick AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability()); 665e5dd7070Spatrick return AR; 666e5dd7070Spatrick } 667e5dd7070Spatrick 668e5dd7070Spatrick void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { 669e5dd7070Spatrick switch (Kind) { 670e5dd7070Spatrick case RK_Pattern: 671e5dd7070Spatrick if (!Declaration) { 672e5dd7070Spatrick // Do nothing: Patterns can come with cursor kinds! 673e5dd7070Spatrick break; 674e5dd7070Spatrick } 675e5dd7070Spatrick LLVM_FALLTHROUGH; 676e5dd7070Spatrick 677e5dd7070Spatrick case RK_Declaration: { 678e5dd7070Spatrick // Set the availability based on attributes. 679e5dd7070Spatrick switch (getDeclAvailability(Declaration)) { 680e5dd7070Spatrick case AR_Available: 681e5dd7070Spatrick case AR_NotYetIntroduced: 682e5dd7070Spatrick Availability = CXAvailability_Available; 683e5dd7070Spatrick break; 684e5dd7070Spatrick 685e5dd7070Spatrick case AR_Deprecated: 686e5dd7070Spatrick Availability = CXAvailability_Deprecated; 687e5dd7070Spatrick break; 688e5dd7070Spatrick 689e5dd7070Spatrick case AR_Unavailable: 690e5dd7070Spatrick Availability = CXAvailability_NotAvailable; 691e5dd7070Spatrick break; 692e5dd7070Spatrick } 693e5dd7070Spatrick 694e5dd7070Spatrick if (const auto *Function = dyn_cast<FunctionDecl>(Declaration)) 695e5dd7070Spatrick if (Function->isDeleted()) 696e5dd7070Spatrick Availability = CXAvailability_NotAvailable; 697e5dd7070Spatrick 698e5dd7070Spatrick CursorKind = getCursorKindForDecl(Declaration); 699e5dd7070Spatrick if (CursorKind == CXCursor_UnexposedDecl) { 700e5dd7070Spatrick // FIXME: Forward declarations of Objective-C classes and protocols 701e5dd7070Spatrick // are not directly exposed, but we want code completion to treat them 702e5dd7070Spatrick // like a definition. 703e5dd7070Spatrick if (isa<ObjCInterfaceDecl>(Declaration)) 704e5dd7070Spatrick CursorKind = CXCursor_ObjCInterfaceDecl; 705e5dd7070Spatrick else if (isa<ObjCProtocolDecl>(Declaration)) 706e5dd7070Spatrick CursorKind = CXCursor_ObjCProtocolDecl; 707e5dd7070Spatrick else 708e5dd7070Spatrick CursorKind = CXCursor_NotImplemented; 709e5dd7070Spatrick } 710e5dd7070Spatrick break; 711e5dd7070Spatrick } 712e5dd7070Spatrick 713e5dd7070Spatrick case RK_Macro: 714e5dd7070Spatrick case RK_Keyword: 715e5dd7070Spatrick llvm_unreachable("Macro and keyword kinds are handled by the constructors"); 716e5dd7070Spatrick } 717e5dd7070Spatrick 718e5dd7070Spatrick if (!Accessible) 719e5dd7070Spatrick Availability = CXAvailability_NotAccessible; 720e5dd7070Spatrick } 721e5dd7070Spatrick 722e5dd7070Spatrick /// Retrieve the name that should be used to order a result. 723e5dd7070Spatrick /// 724e5dd7070Spatrick /// If the name needs to be constructed as a string, that string will be 725e5dd7070Spatrick /// saved into Saved and the returned StringRef will refer to it. 726e5dd7070Spatrick StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const { 727e5dd7070Spatrick switch (Kind) { 728e5dd7070Spatrick case RK_Keyword: 729e5dd7070Spatrick return Keyword; 730e5dd7070Spatrick case RK_Pattern: 731e5dd7070Spatrick return Pattern->getTypedText(); 732e5dd7070Spatrick case RK_Macro: 733e5dd7070Spatrick return Macro->getName(); 734e5dd7070Spatrick case RK_Declaration: 735e5dd7070Spatrick // Handle declarations below. 736e5dd7070Spatrick break; 737e5dd7070Spatrick } 738e5dd7070Spatrick 739e5dd7070Spatrick DeclarationName Name = Declaration->getDeclName(); 740e5dd7070Spatrick 741e5dd7070Spatrick // If the name is a simple identifier (by far the common case), or a 742e5dd7070Spatrick // zero-argument selector, just return a reference to that identifier. 743e5dd7070Spatrick if (IdentifierInfo *Id = Name.getAsIdentifierInfo()) 744e5dd7070Spatrick return Id->getName(); 745e5dd7070Spatrick if (Name.isObjCZeroArgSelector()) 746e5dd7070Spatrick if (IdentifierInfo *Id = Name.getObjCSelector().getIdentifierInfoForSlot(0)) 747e5dd7070Spatrick return Id->getName(); 748e5dd7070Spatrick 749e5dd7070Spatrick Saved = Name.getAsString(); 750e5dd7070Spatrick return Saved; 751e5dd7070Spatrick } 752e5dd7070Spatrick 753e5dd7070Spatrick bool clang::operator<(const CodeCompletionResult &X, 754e5dd7070Spatrick const CodeCompletionResult &Y) { 755e5dd7070Spatrick std::string XSaved, YSaved; 756e5dd7070Spatrick StringRef XStr = X.getOrderedName(XSaved); 757e5dd7070Spatrick StringRef YStr = Y.getOrderedName(YSaved); 758*a9ac8606Spatrick int cmp = XStr.compare_insensitive(YStr); 759e5dd7070Spatrick if (cmp) 760e5dd7070Spatrick return cmp < 0; 761e5dd7070Spatrick 762e5dd7070Spatrick // If case-insensitive comparison fails, try case-sensitive comparison. 763e5dd7070Spatrick return XStr.compare(YStr) < 0; 764e5dd7070Spatrick } 765