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" 26*ec727ea7Spatrick #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) { 359e5dd7070Spatrick const NamedDecl *ND = dyn_cast<NamedDecl>(DC); 360e5dd7070Spatrick if (!ND) 361e5dd7070Spatrick return {}; 362e5dd7070Spatrick 363e5dd7070Spatrick // Check whether we've already cached the parent name. 364e5dd7070Spatrick StringRef &CachedParentName = ParentNames[DC]; 365e5dd7070Spatrick if (!CachedParentName.empty()) 366e5dd7070Spatrick return CachedParentName; 367e5dd7070Spatrick 368e5dd7070Spatrick // If we already processed this DeclContext and assigned empty to it, the 369e5dd7070Spatrick // data pointer will be non-null. 370e5dd7070Spatrick if (CachedParentName.data() != nullptr) 371e5dd7070Spatrick return {}; 372e5dd7070Spatrick 373e5dd7070Spatrick // Find the interesting names. 374e5dd7070Spatrick SmallVector<const DeclContext *, 2> Contexts; 375e5dd7070Spatrick while (DC && !DC->isFunctionOrMethod()) { 376e5dd7070Spatrick if (const auto *ND = dyn_cast<NamedDecl>(DC)) { 377e5dd7070Spatrick if (ND->getIdentifier()) 378e5dd7070Spatrick Contexts.push_back(DC); 379e5dd7070Spatrick } 380e5dd7070Spatrick 381e5dd7070Spatrick DC = DC->getParent(); 382e5dd7070Spatrick } 383e5dd7070Spatrick 384e5dd7070Spatrick { 385e5dd7070Spatrick SmallString<128> S; 386e5dd7070Spatrick llvm::raw_svector_ostream OS(S); 387e5dd7070Spatrick bool First = true; 388e5dd7070Spatrick for (unsigned I = Contexts.size(); I != 0; --I) { 389e5dd7070Spatrick if (First) 390e5dd7070Spatrick First = false; 391e5dd7070Spatrick else { 392e5dd7070Spatrick OS << "::"; 393e5dd7070Spatrick } 394e5dd7070Spatrick 395e5dd7070Spatrick const DeclContext *CurDC = Contexts[I - 1]; 396e5dd7070Spatrick if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC)) 397e5dd7070Spatrick CurDC = CatImpl->getCategoryDecl(); 398e5dd7070Spatrick 399e5dd7070Spatrick if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) { 400e5dd7070Spatrick const ObjCInterfaceDecl *Interface = Cat->getClassInterface(); 401e5dd7070Spatrick if (!Interface) { 402e5dd7070Spatrick // Assign an empty StringRef but with non-null data to distinguish 403e5dd7070Spatrick // between empty because we didn't process the DeclContext yet. 404e5dd7070Spatrick CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0); 405e5dd7070Spatrick return {}; 406e5dd7070Spatrick } 407e5dd7070Spatrick 408e5dd7070Spatrick OS << Interface->getName() << '(' << Cat->getName() << ')'; 409e5dd7070Spatrick } else { 410e5dd7070Spatrick OS << cast<NamedDecl>(CurDC)->getName(); 411e5dd7070Spatrick } 412e5dd7070Spatrick } 413e5dd7070Spatrick 414e5dd7070Spatrick CachedParentName = AllocatorRef->CopyString(OS.str()); 415e5dd7070Spatrick } 416e5dd7070Spatrick 417e5dd7070Spatrick return CachedParentName; 418e5dd7070Spatrick } 419e5dd7070Spatrick 420e5dd7070Spatrick CodeCompletionString *CodeCompletionBuilder::TakeString() { 421e5dd7070Spatrick void *Mem = getAllocator().Allocate( 422e5dd7070Spatrick sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() + 423e5dd7070Spatrick sizeof(const char *) * Annotations.size(), 424e5dd7070Spatrick alignof(CodeCompletionString)); 425e5dd7070Spatrick CodeCompletionString *Result = new (Mem) CodeCompletionString( 426e5dd7070Spatrick Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(), 427e5dd7070Spatrick Annotations.size(), ParentName, BriefComment); 428e5dd7070Spatrick Chunks.clear(); 429e5dd7070Spatrick return Result; 430e5dd7070Spatrick } 431e5dd7070Spatrick 432e5dd7070Spatrick void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) { 433e5dd7070Spatrick Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text)); 434e5dd7070Spatrick } 435e5dd7070Spatrick 436e5dd7070Spatrick void CodeCompletionBuilder::AddTextChunk(const char *Text) { 437e5dd7070Spatrick Chunks.push_back(Chunk::CreateText(Text)); 438e5dd7070Spatrick } 439e5dd7070Spatrick 440e5dd7070Spatrick void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) { 441e5dd7070Spatrick Chunks.push_back(Chunk::CreateOptional(Optional)); 442e5dd7070Spatrick } 443e5dd7070Spatrick 444e5dd7070Spatrick void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) { 445e5dd7070Spatrick Chunks.push_back(Chunk::CreatePlaceholder(Placeholder)); 446e5dd7070Spatrick } 447e5dd7070Spatrick 448e5dd7070Spatrick void CodeCompletionBuilder::AddInformativeChunk(const char *Text) { 449e5dd7070Spatrick Chunks.push_back(Chunk::CreateInformative(Text)); 450e5dd7070Spatrick } 451e5dd7070Spatrick 452e5dd7070Spatrick void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) { 453e5dd7070Spatrick Chunks.push_back(Chunk::CreateResultType(ResultType)); 454e5dd7070Spatrick } 455e5dd7070Spatrick 456e5dd7070Spatrick void CodeCompletionBuilder::AddCurrentParameterChunk( 457e5dd7070Spatrick const char *CurrentParameter) { 458e5dd7070Spatrick Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter)); 459e5dd7070Spatrick } 460e5dd7070Spatrick 461e5dd7070Spatrick void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK, 462e5dd7070Spatrick const char *Text) { 463e5dd7070Spatrick Chunks.push_back(Chunk(CK, Text)); 464e5dd7070Spatrick } 465e5dd7070Spatrick 466e5dd7070Spatrick void CodeCompletionBuilder::addParentContext(const DeclContext *DC) { 467e5dd7070Spatrick if (DC->isTranslationUnit()) 468e5dd7070Spatrick return; 469e5dd7070Spatrick 470e5dd7070Spatrick if (DC->isFunctionOrMethod()) 471e5dd7070Spatrick return; 472e5dd7070Spatrick 473e5dd7070Spatrick const NamedDecl *ND = dyn_cast<NamedDecl>(DC); 474e5dd7070Spatrick if (!ND) 475e5dd7070Spatrick return; 476e5dd7070Spatrick 477e5dd7070Spatrick ParentName = getCodeCompletionTUInfo().getParentName(DC); 478e5dd7070Spatrick } 479e5dd7070Spatrick 480e5dd7070Spatrick void CodeCompletionBuilder::addBriefComment(StringRef Comment) { 481e5dd7070Spatrick BriefComment = Allocator.CopyString(Comment); 482e5dd7070Spatrick } 483e5dd7070Spatrick 484e5dd7070Spatrick //===----------------------------------------------------------------------===// 485e5dd7070Spatrick // Code completion overload candidate implementation 486e5dd7070Spatrick //===----------------------------------------------------------------------===// 487e5dd7070Spatrick FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const { 488e5dd7070Spatrick if (getKind() == CK_Function) 489e5dd7070Spatrick return Function; 490e5dd7070Spatrick else if (getKind() == CK_FunctionTemplate) 491e5dd7070Spatrick return FunctionTemplate->getTemplatedDecl(); 492e5dd7070Spatrick else 493e5dd7070Spatrick return nullptr; 494e5dd7070Spatrick } 495e5dd7070Spatrick 496e5dd7070Spatrick const FunctionType * 497e5dd7070Spatrick CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { 498e5dd7070Spatrick switch (Kind) { 499e5dd7070Spatrick case CK_Function: 500e5dd7070Spatrick return Function->getType()->getAs<FunctionType>(); 501e5dd7070Spatrick 502e5dd7070Spatrick case CK_FunctionTemplate: 503e5dd7070Spatrick return FunctionTemplate->getTemplatedDecl() 504e5dd7070Spatrick ->getType() 505e5dd7070Spatrick ->getAs<FunctionType>(); 506e5dd7070Spatrick 507e5dd7070Spatrick case CK_FunctionType: 508e5dd7070Spatrick return Type; 509e5dd7070Spatrick } 510e5dd7070Spatrick 511e5dd7070Spatrick llvm_unreachable("Invalid CandidateKind!"); 512e5dd7070Spatrick } 513e5dd7070Spatrick 514e5dd7070Spatrick //===----------------------------------------------------------------------===// 515e5dd7070Spatrick // Code completion consumer implementation 516e5dd7070Spatrick //===----------------------------------------------------------------------===// 517e5dd7070Spatrick 518e5dd7070Spatrick CodeCompleteConsumer::~CodeCompleteConsumer() = default; 519e5dd7070Spatrick 520e5dd7070Spatrick bool PrintingCodeCompleteConsumer::isResultFilteredOut( 521e5dd7070Spatrick StringRef Filter, CodeCompletionResult Result) { 522e5dd7070Spatrick switch (Result.Kind) { 523e5dd7070Spatrick case CodeCompletionResult::RK_Declaration: 524e5dd7070Spatrick return !(Result.Declaration->getIdentifier() && 525e5dd7070Spatrick Result.Declaration->getIdentifier()->getName().startswith(Filter)); 526e5dd7070Spatrick case CodeCompletionResult::RK_Keyword: 527e5dd7070Spatrick return !StringRef(Result.Keyword).startswith(Filter); 528e5dd7070Spatrick case CodeCompletionResult::RK_Macro: 529e5dd7070Spatrick return !Result.Macro->getName().startswith(Filter); 530e5dd7070Spatrick case CodeCompletionResult::RK_Pattern: 531e5dd7070Spatrick return !(Result.Pattern->getTypedText() && 532e5dd7070Spatrick StringRef(Result.Pattern->getTypedText()).startswith(Filter)); 533e5dd7070Spatrick } 534e5dd7070Spatrick llvm_unreachable("Unknown code completion result Kind."); 535e5dd7070Spatrick } 536e5dd7070Spatrick 537e5dd7070Spatrick void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults( 538e5dd7070Spatrick Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results, 539e5dd7070Spatrick unsigned NumResults) { 540e5dd7070Spatrick std::stable_sort(Results, Results + NumResults); 541e5dd7070Spatrick 542e5dd7070Spatrick if (!Context.getPreferredType().isNull()) 543e5dd7070Spatrick OS << "PREFERRED-TYPE: " << Context.getPreferredType().getAsString() 544e5dd7070Spatrick << "\n"; 545e5dd7070Spatrick 546e5dd7070Spatrick StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); 547e5dd7070Spatrick // Print the completions. 548e5dd7070Spatrick for (unsigned I = 0; I != NumResults; ++I) { 549e5dd7070Spatrick if (!Filter.empty() && isResultFilteredOut(Filter, Results[I])) 550e5dd7070Spatrick continue; 551e5dd7070Spatrick OS << "COMPLETION: "; 552e5dd7070Spatrick switch (Results[I].Kind) { 553e5dd7070Spatrick case CodeCompletionResult::RK_Declaration: 554e5dd7070Spatrick OS << *Results[I].Declaration; 555e5dd7070Spatrick { 556e5dd7070Spatrick std::vector<std::string> Tags; 557e5dd7070Spatrick if (Results[I].Hidden) 558e5dd7070Spatrick Tags.push_back("Hidden"); 559e5dd7070Spatrick if (Results[I].InBaseClass) 560e5dd7070Spatrick Tags.push_back("InBase"); 561e5dd7070Spatrick if (Results[I].Availability == 562e5dd7070Spatrick CXAvailabilityKind::CXAvailability_NotAccessible) 563e5dd7070Spatrick Tags.push_back("Inaccessible"); 564e5dd7070Spatrick if (!Tags.empty()) 565e5dd7070Spatrick OS << " (" << llvm::join(Tags, ",") << ")"; 566e5dd7070Spatrick } 567e5dd7070Spatrick if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( 568e5dd7070Spatrick SemaRef, Context, getAllocator(), CCTUInfo, 569e5dd7070Spatrick includeBriefComments())) { 570e5dd7070Spatrick OS << " : " << CCS->getAsString(); 571e5dd7070Spatrick if (const char *BriefComment = CCS->getBriefComment()) 572e5dd7070Spatrick OS << " : " << BriefComment; 573e5dd7070Spatrick } 574*ec727ea7Spatrick break; 575*ec727ea7Spatrick 576*ec727ea7Spatrick case CodeCompletionResult::RK_Keyword: 577*ec727ea7Spatrick OS << Results[I].Keyword; 578*ec727ea7Spatrick break; 579*ec727ea7Spatrick 580*ec727ea7Spatrick case CodeCompletionResult::RK_Macro: 581*ec727ea7Spatrick OS << Results[I].Macro->getName(); 582*ec727ea7Spatrick if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString( 583*ec727ea7Spatrick SemaRef, Context, getAllocator(), CCTUInfo, 584*ec727ea7Spatrick includeBriefComments())) { 585*ec727ea7Spatrick OS << " : " << CCS->getAsString(); 586*ec727ea7Spatrick } 587*ec727ea7Spatrick break; 588*ec727ea7Spatrick 589*ec727ea7Spatrick case CodeCompletionResult::RK_Pattern: 590*ec727ea7Spatrick OS << "Pattern : " << Results[I].Pattern->getAsString(); 591*ec727ea7Spatrick break; 592*ec727ea7Spatrick } 593e5dd7070Spatrick for (const FixItHint &FixIt : Results[I].FixIts) { 594e5dd7070Spatrick const SourceLocation BLoc = FixIt.RemoveRange.getBegin(); 595e5dd7070Spatrick const SourceLocation ELoc = FixIt.RemoveRange.getEnd(); 596e5dd7070Spatrick 597e5dd7070Spatrick SourceManager &SM = SemaRef.SourceMgr; 598e5dd7070Spatrick std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc); 599e5dd7070Spatrick std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc); 600e5dd7070Spatrick // Adjust for token ranges. 601e5dd7070Spatrick if (FixIt.RemoveRange.isTokenRange()) 602e5dd7070Spatrick EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts); 603e5dd7070Spatrick 604e5dd7070Spatrick OS << " (requires fix-it:" 605e5dd7070Spatrick << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':' 606e5dd7070Spatrick << SM.getColumnNumber(BInfo.first, BInfo.second) << '-' 607e5dd7070Spatrick << SM.getLineNumber(EInfo.first, EInfo.second) << ':' 608e5dd7070Spatrick << SM.getColumnNumber(EInfo.first, EInfo.second) << "}" 609e5dd7070Spatrick << " to \"" << FixIt.CodeToInsert << "\")"; 610e5dd7070Spatrick } 611e5dd7070Spatrick OS << '\n'; 612e5dd7070Spatrick } 613e5dd7070Spatrick } 614e5dd7070Spatrick 615e5dd7070Spatrick // This function is used solely to preserve the former presentation of overloads 616e5dd7070Spatrick // by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString 617e5dd7070Spatrick // needs to be improved for printing the newer and more detailed overload 618e5dd7070Spatrick // chunks. 619e5dd7070Spatrick static std::string getOverloadAsString(const CodeCompletionString &CCS) { 620e5dd7070Spatrick std::string Result; 621e5dd7070Spatrick llvm::raw_string_ostream OS(Result); 622e5dd7070Spatrick 623e5dd7070Spatrick for (auto &C : CCS) { 624e5dd7070Spatrick switch (C.Kind) { 625e5dd7070Spatrick case CodeCompletionString::CK_Informative: 626e5dd7070Spatrick case CodeCompletionString::CK_ResultType: 627e5dd7070Spatrick OS << "[#" << C.Text << "#]"; 628e5dd7070Spatrick break; 629e5dd7070Spatrick 630e5dd7070Spatrick case CodeCompletionString::CK_CurrentParameter: 631e5dd7070Spatrick OS << "<#" << C.Text << "#>"; 632e5dd7070Spatrick break; 633e5dd7070Spatrick 634e5dd7070Spatrick // FIXME: We can also print optional parameters of an overload. 635e5dd7070Spatrick case CodeCompletionString::CK_Optional: 636e5dd7070Spatrick break; 637e5dd7070Spatrick 638e5dd7070Spatrick default: 639e5dd7070Spatrick OS << C.Text; 640e5dd7070Spatrick break; 641e5dd7070Spatrick } 642e5dd7070Spatrick } 643e5dd7070Spatrick return OS.str(); 644e5dd7070Spatrick } 645e5dd7070Spatrick 646e5dd7070Spatrick void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( 647e5dd7070Spatrick Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates, 648e5dd7070Spatrick unsigned NumCandidates, SourceLocation OpenParLoc) { 649e5dd7070Spatrick OS << "OPENING_PAREN_LOC: "; 650e5dd7070Spatrick OpenParLoc.print(OS, SemaRef.getSourceManager()); 651e5dd7070Spatrick OS << "\n"; 652e5dd7070Spatrick 653e5dd7070Spatrick for (unsigned I = 0; I != NumCandidates; ++I) { 654e5dd7070Spatrick if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString( 655e5dd7070Spatrick CurrentArg, SemaRef, getAllocator(), CCTUInfo, 656e5dd7070Spatrick includeBriefComments())) { 657e5dd7070Spatrick OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n"; 658e5dd7070Spatrick } 659e5dd7070Spatrick } 660e5dd7070Spatrick } 661e5dd7070Spatrick 662e5dd7070Spatrick /// Retrieve the effective availability of the given declaration. 663e5dd7070Spatrick static AvailabilityResult getDeclAvailability(const Decl *D) { 664e5dd7070Spatrick AvailabilityResult AR = D->getAvailability(); 665e5dd7070Spatrick if (isa<EnumConstantDecl>(D)) 666e5dd7070Spatrick AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability()); 667e5dd7070Spatrick return AR; 668e5dd7070Spatrick } 669e5dd7070Spatrick 670e5dd7070Spatrick void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) { 671e5dd7070Spatrick switch (Kind) { 672e5dd7070Spatrick case RK_Pattern: 673e5dd7070Spatrick if (!Declaration) { 674e5dd7070Spatrick // Do nothing: Patterns can come with cursor kinds! 675e5dd7070Spatrick break; 676e5dd7070Spatrick } 677e5dd7070Spatrick LLVM_FALLTHROUGH; 678e5dd7070Spatrick 679e5dd7070Spatrick case RK_Declaration: { 680e5dd7070Spatrick // Set the availability based on attributes. 681e5dd7070Spatrick switch (getDeclAvailability(Declaration)) { 682e5dd7070Spatrick case AR_Available: 683e5dd7070Spatrick case AR_NotYetIntroduced: 684e5dd7070Spatrick Availability = CXAvailability_Available; 685e5dd7070Spatrick break; 686e5dd7070Spatrick 687e5dd7070Spatrick case AR_Deprecated: 688e5dd7070Spatrick Availability = CXAvailability_Deprecated; 689e5dd7070Spatrick break; 690e5dd7070Spatrick 691e5dd7070Spatrick case AR_Unavailable: 692e5dd7070Spatrick Availability = CXAvailability_NotAvailable; 693e5dd7070Spatrick break; 694e5dd7070Spatrick } 695e5dd7070Spatrick 696e5dd7070Spatrick if (const auto *Function = dyn_cast<FunctionDecl>(Declaration)) 697e5dd7070Spatrick if (Function->isDeleted()) 698e5dd7070Spatrick Availability = CXAvailability_NotAvailable; 699e5dd7070Spatrick 700e5dd7070Spatrick CursorKind = getCursorKindForDecl(Declaration); 701e5dd7070Spatrick if (CursorKind == CXCursor_UnexposedDecl) { 702e5dd7070Spatrick // FIXME: Forward declarations of Objective-C classes and protocols 703e5dd7070Spatrick // are not directly exposed, but we want code completion to treat them 704e5dd7070Spatrick // like a definition. 705e5dd7070Spatrick if (isa<ObjCInterfaceDecl>(Declaration)) 706e5dd7070Spatrick CursorKind = CXCursor_ObjCInterfaceDecl; 707e5dd7070Spatrick else if (isa<ObjCProtocolDecl>(Declaration)) 708e5dd7070Spatrick CursorKind = CXCursor_ObjCProtocolDecl; 709e5dd7070Spatrick else 710e5dd7070Spatrick CursorKind = CXCursor_NotImplemented; 711e5dd7070Spatrick } 712e5dd7070Spatrick break; 713e5dd7070Spatrick } 714e5dd7070Spatrick 715e5dd7070Spatrick case RK_Macro: 716e5dd7070Spatrick case RK_Keyword: 717e5dd7070Spatrick llvm_unreachable("Macro and keyword kinds are handled by the constructors"); 718e5dd7070Spatrick } 719e5dd7070Spatrick 720e5dd7070Spatrick if (!Accessible) 721e5dd7070Spatrick Availability = CXAvailability_NotAccessible; 722e5dd7070Spatrick } 723e5dd7070Spatrick 724e5dd7070Spatrick /// Retrieve the name that should be used to order a result. 725e5dd7070Spatrick /// 726e5dd7070Spatrick /// If the name needs to be constructed as a string, that string will be 727e5dd7070Spatrick /// saved into Saved and the returned StringRef will refer to it. 728e5dd7070Spatrick StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const { 729e5dd7070Spatrick switch (Kind) { 730e5dd7070Spatrick case RK_Keyword: 731e5dd7070Spatrick return Keyword; 732e5dd7070Spatrick case RK_Pattern: 733e5dd7070Spatrick return Pattern->getTypedText(); 734e5dd7070Spatrick case RK_Macro: 735e5dd7070Spatrick return Macro->getName(); 736e5dd7070Spatrick case RK_Declaration: 737e5dd7070Spatrick // Handle declarations below. 738e5dd7070Spatrick break; 739e5dd7070Spatrick } 740e5dd7070Spatrick 741e5dd7070Spatrick DeclarationName Name = Declaration->getDeclName(); 742e5dd7070Spatrick 743e5dd7070Spatrick // If the name is a simple identifier (by far the common case), or a 744e5dd7070Spatrick // zero-argument selector, just return a reference to that identifier. 745e5dd7070Spatrick if (IdentifierInfo *Id = Name.getAsIdentifierInfo()) 746e5dd7070Spatrick return Id->getName(); 747e5dd7070Spatrick if (Name.isObjCZeroArgSelector()) 748e5dd7070Spatrick if (IdentifierInfo *Id = Name.getObjCSelector().getIdentifierInfoForSlot(0)) 749e5dd7070Spatrick return Id->getName(); 750e5dd7070Spatrick 751e5dd7070Spatrick Saved = Name.getAsString(); 752e5dd7070Spatrick return Saved; 753e5dd7070Spatrick } 754e5dd7070Spatrick 755e5dd7070Spatrick bool clang::operator<(const CodeCompletionResult &X, 756e5dd7070Spatrick const CodeCompletionResult &Y) { 757e5dd7070Spatrick std::string XSaved, YSaved; 758e5dd7070Spatrick StringRef XStr = X.getOrderedName(XSaved); 759e5dd7070Spatrick StringRef YStr = Y.getOrderedName(YSaved); 760e5dd7070Spatrick int cmp = XStr.compare_lower(YStr); 761e5dd7070Spatrick if (cmp) 762e5dd7070Spatrick return cmp < 0; 763e5dd7070Spatrick 764e5dd7070Spatrick // If case-insensitive comparison fails, try case-sensitive comparison. 765e5dd7070Spatrick return XStr.compare(YStr) < 0; 766e5dd7070Spatrick } 767