clang API Documentation

CodeCompleteConsumer.cpp
Go to the documentation of this file.
00001 //===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements the CodeCompleteConsumer class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 #include "clang/Sema/CodeCompleteConsumer.h"
00014 #include "clang-c/Index.h"
00015 #include "clang/AST/DeclCXX.h"
00016 #include "clang/AST/DeclObjC.h"
00017 #include "clang/AST/DeclTemplate.h"
00018 #include "clang/Sema/Scope.h"
00019 #include "clang/Sema/Sema.h"
00020 #include "llvm/ADT/STLExtras.h"
00021 #include "llvm/ADT/SmallString.h"
00022 #include "llvm/ADT/Twine.h"
00023 #include "llvm/Support/raw_ostream.h"
00024 #include <algorithm>
00025 #include <cstring>
00026 #include <functional>
00027 
00028 using namespace clang;
00029 
00030 //===----------------------------------------------------------------------===//
00031 // Code completion context implementation
00032 //===----------------------------------------------------------------------===//
00033 
00034 bool CodeCompletionContext::wantConstructorResults() const {
00035   switch (Kind) {
00036   case CCC_Recovery:
00037   case CCC_Statement:
00038   case CCC_Expression:
00039   case CCC_ObjCMessageReceiver:
00040   case CCC_ParenthesizedExpression:
00041     return true;
00042     
00043   case CCC_TopLevel:
00044   case CCC_ObjCInterface:
00045   case CCC_ObjCImplementation:
00046   case CCC_ObjCIvarList:
00047   case CCC_ClassStructUnion:
00048   case CCC_DotMemberAccess:
00049   case CCC_ArrowMemberAccess:
00050   case CCC_ObjCPropertyAccess:
00051   case CCC_EnumTag:
00052   case CCC_UnionTag:
00053   case CCC_ClassOrStructTag:
00054   case CCC_ObjCProtocolName:
00055   case CCC_Namespace:
00056   case CCC_Type:
00057   case CCC_Name:
00058   case CCC_PotentiallyQualifiedName:
00059   case CCC_MacroName:
00060   case CCC_MacroNameUse:
00061   case CCC_PreprocessorExpression:
00062   case CCC_PreprocessorDirective:
00063   case CCC_NaturalLanguage:
00064   case CCC_SelectorName:
00065   case CCC_TypeQualifiers:
00066   case CCC_Other:
00067   case CCC_OtherWithMacros:
00068   case CCC_ObjCInstanceMessage:
00069   case CCC_ObjCClassMessage:
00070   case CCC_ObjCInterfaceName:
00071   case CCC_ObjCCategoryName:
00072     return false;
00073   }
00074 
00075   llvm_unreachable("Invalid CodeCompletionContext::Kind!");
00076 }
00077 
00078 //===----------------------------------------------------------------------===//
00079 // Code completion string implementation
00080 //===----------------------------------------------------------------------===//
00081 CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text) 
00082   : Kind(Kind), Text("")
00083 {
00084   switch (Kind) {
00085   case CK_TypedText:
00086   case CK_Text:
00087   case CK_Placeholder:
00088   case CK_Informative:
00089   case CK_ResultType:
00090   case CK_CurrentParameter:
00091     this->Text = Text;
00092     break;
00093 
00094   case CK_Optional:
00095     llvm_unreachable("Optional strings cannot be created from text");
00096       
00097   case CK_LeftParen:
00098     this->Text = "(";
00099     break;
00100 
00101   case CK_RightParen:
00102     this->Text = ")";
00103     break;
00104 
00105   case CK_LeftBracket:
00106     this->Text = "[";
00107     break;
00108     
00109   case CK_RightBracket:
00110     this->Text = "]";
00111     break;
00112     
00113   case CK_LeftBrace:
00114     this->Text = "{";
00115     break;
00116 
00117   case CK_RightBrace:
00118     this->Text = "}";
00119     break;
00120 
00121   case CK_LeftAngle:
00122     this->Text = "<";
00123     break;
00124     
00125   case CK_RightAngle:
00126     this->Text = ">";
00127     break;
00128       
00129   case CK_Comma:
00130     this->Text = ", ";
00131     break;
00132 
00133   case CK_Colon:
00134     this->Text = ":";
00135     break;
00136 
00137   case CK_SemiColon:
00138     this->Text = ";";
00139     break;
00140 
00141   case CK_Equal:
00142     this->Text = " = ";
00143     break;
00144 
00145   case CK_HorizontalSpace:
00146     this->Text = " ";
00147     break;
00148 
00149   case CK_VerticalSpace:
00150     this->Text = "\n";
00151     break;
00152   }
00153 }
00154 
00155 CodeCompletionString::Chunk
00156 CodeCompletionString::Chunk::CreateText(const char *Text) {
00157   return Chunk(CK_Text, Text);
00158 }
00159 
00160 CodeCompletionString::Chunk 
00161 CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
00162   Chunk Result;
00163   Result.Kind = CK_Optional;
00164   Result.Optional = Optional;
00165   return Result;
00166 }
00167 
00168 CodeCompletionString::Chunk 
00169 CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
00170   return Chunk(CK_Placeholder, Placeholder);
00171 }
00172 
00173 CodeCompletionString::Chunk 
00174 CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
00175   return Chunk(CK_Informative, Informative);
00176 }
00177 
00178 CodeCompletionString::Chunk 
00179 CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
00180   return Chunk(CK_ResultType, ResultType);
00181 }
00182 
00183 CodeCompletionString::Chunk 
00184 CodeCompletionString::Chunk::CreateCurrentParameter(
00185                                                 const char *CurrentParameter) {
00186   return Chunk(CK_CurrentParameter, CurrentParameter);
00187 }
00188 
00189 CodeCompletionString::CodeCompletionString(const Chunk *Chunks, 
00190                                            unsigned NumChunks,
00191                                            unsigned Priority, 
00192                                            CXAvailabilityKind Availability,
00193                                            const char **Annotations,
00194                                            unsigned NumAnnotations,
00195                                            StringRef ParentName,
00196                                            const char *BriefComment)
00197   : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
00198     Priority(Priority), Availability(Availability),
00199     ParentName(ParentName), BriefComment(BriefComment)
00200 { 
00201   assert(NumChunks <= 0xffff);
00202   assert(NumAnnotations <= 0xffff);
00203 
00204   Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
00205   for (unsigned I = 0; I != NumChunks; ++I)
00206     StoredChunks[I] = Chunks[I];
00207 
00208   const char **StoredAnnotations = reinterpret_cast<const char **>(StoredChunks + NumChunks);
00209   for (unsigned I = 0; I != NumAnnotations; ++I)
00210     StoredAnnotations[I] = Annotations[I];
00211 }
00212 
00213 unsigned CodeCompletionString::getAnnotationCount() const {
00214   return NumAnnotations;
00215 }
00216 
00217 const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
00218   if (AnnotationNr < NumAnnotations)
00219     return reinterpret_cast<const char * const*>(end())[AnnotationNr];
00220   else
00221     return nullptr;
00222 }
00223 
00224 
00225 std::string CodeCompletionString::getAsString() const {
00226   std::string Result;
00227   llvm::raw_string_ostream OS(Result);
00228                           
00229   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
00230     switch (C->Kind) {
00231     case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
00232     case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
00233         
00234     case CK_Informative: 
00235     case CK_ResultType:
00236       OS << "[#" << C->Text << "#]"; 
00237       break;
00238         
00239     case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
00240     default: OS << C->Text; break;
00241     }
00242   }
00243   return OS.str();
00244 }
00245 
00246 const char *CodeCompletionString::getTypedText() const {
00247   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
00248     if (C->Kind == CK_TypedText)
00249       return C->Text;
00250 
00251   return nullptr;
00252 }
00253 
00254 const char *CodeCompletionAllocator::CopyString(StringRef String) {
00255   char *Mem = (char *)Allocate(String.size() + 1, 1);
00256   std::copy(String.begin(), String.end(), Mem);
00257   Mem[String.size()] = 0;
00258   return Mem;
00259 }
00260 
00261 const char *CodeCompletionAllocator::CopyString(Twine String) {
00262   // FIXME: It would be more efficient to teach Twine to tell us its size and
00263   // then add a routine there to fill in an allocated char* with the contents
00264   // of the string.
00265   SmallString<128> Data;
00266   return CopyString(String.toStringRef(Data));
00267 }
00268 
00269 StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
00270   const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
00271   if (!ND)
00272     return StringRef();
00273   
00274   // Check whether we've already cached the parent name.
00275   StringRef &CachedParentName = ParentNames[DC];
00276   if (!CachedParentName.empty())
00277     return CachedParentName;
00278 
00279   // If we already processed this DeclContext and assigned empty to it, the
00280   // data pointer will be non-null.
00281   if (CachedParentName.data() != nullptr)
00282     return StringRef();
00283 
00284   // Find the interesting names.
00285   SmallVector<const DeclContext *, 2> Contexts;
00286   while (DC && !DC->isFunctionOrMethod()) {
00287     if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
00288       if (ND->getIdentifier())
00289         Contexts.push_back(DC);
00290     }
00291     
00292     DC = DC->getParent();
00293   }
00294 
00295   {
00296     SmallString<128> S;
00297     llvm::raw_svector_ostream OS(S);
00298     bool First = true;
00299     for (unsigned I = Contexts.size(); I != 0; --I) {
00300       if (First)
00301         First = false;
00302       else {
00303         OS << "::";
00304       }
00305       
00306       const DeclContext *CurDC = Contexts[I-1];
00307       if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
00308         CurDC = CatImpl->getCategoryDecl();
00309       
00310       if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
00311         const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
00312         if (!Interface) {
00313           // Assign an empty StringRef but with non-null data to distinguish
00314           // between empty because we didn't process the DeclContext yet.
00315           CachedParentName = StringRef((const char *)~0U, 0);
00316           return StringRef();
00317         }
00318         
00319         OS << Interface->getName() << '(' << Cat->getName() << ')';
00320       } else {
00321         OS << cast<NamedDecl>(CurDC)->getName();
00322       }
00323     }
00324     
00325     CachedParentName = AllocatorRef->CopyString(OS.str());
00326   }
00327 
00328   return CachedParentName;
00329 }
00330 
00331 CodeCompletionString *CodeCompletionBuilder::TakeString() {
00332   void *Mem = getAllocator().Allocate(
00333                   sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size()
00334                                     + sizeof(const char *) * Annotations.size(),
00335                                  llvm::alignOf<CodeCompletionString>());
00336   CodeCompletionString *Result 
00337     = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
00338                                      Priority, Availability,
00339                                      Annotations.data(), Annotations.size(),
00340                                      ParentName, BriefComment);
00341   Chunks.clear();
00342   return Result;
00343 }
00344 
00345 void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
00346   Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
00347 }
00348 
00349 void CodeCompletionBuilder::AddTextChunk(const char *Text) {
00350   Chunks.push_back(Chunk::CreateText(Text));
00351 }
00352 
00353 void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
00354   Chunks.push_back(Chunk::CreateOptional(Optional));
00355 }
00356 
00357 void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
00358   Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
00359 }
00360 
00361 void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
00362   Chunks.push_back(Chunk::CreateInformative(Text));
00363 }
00364 
00365 void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
00366   Chunks.push_back(Chunk::CreateResultType(ResultType));
00367 }
00368 
00369 void
00370 CodeCompletionBuilder::AddCurrentParameterChunk(const char *CurrentParameter) {
00371   Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
00372 }
00373 
00374 void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
00375                                      const char *Text) {
00376   Chunks.push_back(Chunk(CK, Text));
00377 }
00378 
00379 void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
00380   if (DC->isTranslationUnit()) {
00381     return;
00382   }
00383   
00384   if (DC->isFunctionOrMethod())
00385     return;
00386   
00387   const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
00388   if (!ND)
00389     return;
00390   
00391   ParentName = getCodeCompletionTUInfo().getParentName(DC);
00392 }
00393 
00394 void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
00395   BriefComment = Allocator.CopyString(Comment);
00396 }
00397 
00398 //===----------------------------------------------------------------------===//
00399 // Code completion overload candidate implementation
00400 //===----------------------------------------------------------------------===//
00401 FunctionDecl *
00402 CodeCompleteConsumer::OverloadCandidate::getFunction() const {
00403   if (getKind() == CK_Function)
00404     return Function;
00405   else if (getKind() == CK_FunctionTemplate)
00406     return FunctionTemplate->getTemplatedDecl();
00407   else
00408     return nullptr;
00409 }
00410 
00411 const FunctionType *
00412 CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
00413   switch (Kind) {
00414   case CK_Function:
00415     return Function->getType()->getAs<FunctionType>();
00416       
00417   case CK_FunctionTemplate:
00418     return FunctionTemplate->getTemplatedDecl()->getType()
00419              ->getAs<FunctionType>();
00420       
00421   case CK_FunctionType:
00422     return Type;
00423   }
00424 
00425   llvm_unreachable("Invalid CandidateKind!");
00426 }
00427 
00428 //===----------------------------------------------------------------------===//
00429 // Code completion consumer implementation
00430 //===----------------------------------------------------------------------===//
00431 
00432 CodeCompleteConsumer::~CodeCompleteConsumer() { }
00433 
00434 void 
00435 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
00436                                                  CodeCompletionContext Context,
00437                                                  CodeCompletionResult *Results,
00438                                                          unsigned NumResults) {
00439   std::stable_sort(Results, Results + NumResults);
00440   
00441   // Print the results.
00442   for (unsigned I = 0; I != NumResults; ++I) {
00443     OS << "COMPLETION: ";
00444     switch (Results[I].Kind) {
00445     case CodeCompletionResult::RK_Declaration:
00446       OS << *Results[I].Declaration;
00447       if (Results[I].Hidden)
00448         OS << " (Hidden)";
00449       if (CodeCompletionString *CCS 
00450             = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
00451                                                     CCTUInfo,
00452                                                     includeBriefComments())) {
00453         OS << " : " << CCS->getAsString();
00454         if (const char *BriefComment = CCS->getBriefComment())
00455           OS << " : " << BriefComment;
00456       }
00457         
00458       OS << '\n';
00459       break;
00460       
00461     case CodeCompletionResult::RK_Keyword:
00462       OS << Results[I].Keyword << '\n';
00463       break;
00464         
00465     case CodeCompletionResult::RK_Macro: {
00466       OS << Results[I].Macro->getName();
00467       if (CodeCompletionString *CCS 
00468             = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
00469                                                     CCTUInfo,
00470                                                     includeBriefComments())) {
00471         OS << " : " << CCS->getAsString();
00472       }
00473       OS << '\n';
00474       break;
00475     }
00476         
00477     case CodeCompletionResult::RK_Pattern: {
00478       OS << "Pattern : " 
00479          << Results[I].Pattern->getAsString() << '\n';
00480       break;
00481     }
00482     }
00483   }
00484 }
00485 
00486 void 
00487 PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
00488                                                         unsigned CurrentArg,
00489                                               OverloadCandidate *Candidates,
00490                                                      unsigned NumCandidates) {
00491   for (unsigned I = 0; I != NumCandidates; ++I) {
00492     if (CodeCompletionString *CCS
00493           = Candidates[I].CreateSignatureString(CurrentArg, SemaRef,
00494                                                 getAllocator(), CCTUInfo)) {
00495       OS << "OVERLOAD: " << CCS->getAsString() << "\n";
00496     }
00497   }
00498 }
00499 
00500 /// \brief Retrieve the effective availability of the given declaration.
00501 static AvailabilityResult getDeclAvailability(const Decl *D) {
00502   AvailabilityResult AR = D->getAvailability();
00503   if (isa<EnumConstantDecl>(D))
00504     AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
00505   return AR;
00506 }
00507 
00508 void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
00509   switch (Kind) {
00510   case RK_Pattern:
00511     if (!Declaration) {
00512       // Do nothing: Patterns can come with cursor kinds!
00513       break;
00514     }
00515     // Fall through
00516       
00517   case RK_Declaration: {
00518     // Set the availability based on attributes.
00519     switch (getDeclAvailability(Declaration)) {
00520     case AR_Available:
00521     case AR_NotYetIntroduced:
00522       Availability = CXAvailability_Available;      
00523       break;
00524       
00525     case AR_Deprecated:
00526       Availability = CXAvailability_Deprecated;
00527       break;
00528       
00529     case AR_Unavailable:
00530       Availability = CXAvailability_NotAvailable;
00531       break;
00532     }
00533 
00534     if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
00535       if (Function->isDeleted())
00536         Availability = CXAvailability_NotAvailable;
00537       
00538     CursorKind = getCursorKindForDecl(Declaration);
00539     if (CursorKind == CXCursor_UnexposedDecl) {
00540       // FIXME: Forward declarations of Objective-C classes and protocols 
00541       // are not directly exposed, but we want code completion to treat them 
00542       // like a definition.
00543       if (isa<ObjCInterfaceDecl>(Declaration))
00544         CursorKind = CXCursor_ObjCInterfaceDecl;
00545       else if (isa<ObjCProtocolDecl>(Declaration))
00546         CursorKind = CXCursor_ObjCProtocolDecl;
00547       else
00548         CursorKind = CXCursor_NotImplemented;
00549     }
00550     break;
00551   }
00552 
00553   case RK_Macro:
00554   case RK_Keyword:
00555     llvm_unreachable("Macro and keyword kinds are handled by the constructors");
00556   }
00557 
00558   if (!Accessible)
00559     Availability = CXAvailability_NotAccessible;
00560 }
00561 
00562 /// \brief Retrieve the name that should be used to order a result.
00563 ///
00564 /// If the name needs to be constructed as a string, that string will be
00565 /// saved into Saved and the returned StringRef will refer to it.
00566 static StringRef getOrderedName(const CodeCompletionResult &R,
00567                                     std::string &Saved) {
00568   switch (R.Kind) {
00569     case CodeCompletionResult::RK_Keyword:
00570       return R.Keyword;
00571       
00572     case CodeCompletionResult::RK_Pattern:
00573       return R.Pattern->getTypedText();
00574       
00575     case CodeCompletionResult::RK_Macro:
00576       return R.Macro->getName();
00577       
00578     case CodeCompletionResult::RK_Declaration:
00579       // Handle declarations below.
00580       break;
00581   }
00582   
00583   DeclarationName Name = R.Declaration->getDeclName();
00584   
00585   // If the name is a simple identifier (by far the common case), or a
00586   // zero-argument selector, just return a reference to that identifier.
00587   if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
00588     return Id->getName();
00589   if (Name.isObjCZeroArgSelector())
00590     if (IdentifierInfo *Id
00591         = Name.getObjCSelector().getIdentifierInfoForSlot(0))
00592       return Id->getName();
00593   
00594   Saved = Name.getAsString();
00595   return Saved;
00596 }
00597     
00598 bool clang::operator<(const CodeCompletionResult &X, 
00599                       const CodeCompletionResult &Y) {
00600   std::string XSaved, YSaved;
00601   StringRef XStr = getOrderedName(X, XSaved);
00602   StringRef YStr = getOrderedName(Y, YSaved);
00603   int cmp = XStr.compare_lower(YStr);
00604   if (cmp)
00605     return cmp < 0;
00606   
00607   // If case-insensitive comparison fails, try case-sensitive comparison.
00608   cmp = XStr.compare(YStr);
00609   if (cmp)
00610     return cmp < 0;
00611   
00612   return false;
00613 }