diff options
Diffstat (limited to 'clang/lib/Sema/CodeCompleteConsumer.cpp')
-rw-r--r-- | clang/lib/Sema/CodeCompleteConsumer.cpp | 85 |
1 files changed, 83 insertions, 2 deletions
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 0a2ca54e244a..fefe20941f17 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -506,11 +506,92 @@ CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { case CK_FunctionType: return Type; + + case CK_Template: + case CK_Aggregate: + return nullptr; } llvm_unreachable("Invalid CandidateKind!"); } +unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const { + if (Kind == CK_Template) + return Template->getTemplateParameters()->size(); + + if (Kind == CK_Aggregate) { + unsigned Count = + std::distance(AggregateType->field_begin(), AggregateType->field_end()); + if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) + Count += CRD->getNumBases(); + return Count; + } + + if (const auto *FT = getFunctionType()) + if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) + return FPT->getNumParams(); + + return 0; +} + +QualType +CodeCompleteConsumer::OverloadCandidate::getParamType(unsigned N) const { + if (Kind == CK_Aggregate) { + if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) { + if (N < CRD->getNumBases()) + return std::next(CRD->bases_begin(), N)->getType(); + N -= CRD->getNumBases(); + } + for (const auto *Field : AggregateType->fields()) + if (N-- == 0) + return Field->getType(); + return QualType(); + } + + if (Kind == CK_Template) { + TemplateParameterList *TPL = getTemplate()->getTemplateParameters(); + if (N < TPL->size()) + if (const auto *D = dyn_cast<NonTypeTemplateParmDecl>(TPL->getParam(N))) + return D->getType(); + return QualType(); + } + + if (const auto *FT = getFunctionType()) + if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) + if (N < FPT->getNumParams()) + return FPT->getParamType(N); + return QualType(); +} + +const NamedDecl * +CodeCompleteConsumer::OverloadCandidate::getParamDecl(unsigned N) const { + if (Kind == CK_Aggregate) { + if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) { + if (N < CRD->getNumBases()) + return std::next(CRD->bases_begin(), N)->getType()->getAsTagDecl(); + N -= CRD->getNumBases(); + } + for (const auto *Field : AggregateType->fields()) + if (N-- == 0) + return Field; + return nullptr; + } + + if (Kind == CK_Template) { + TemplateParameterList *TPL = getTemplate()->getTemplateParameters(); + if (N < TPL->size()) + return TPL->getParam(N); + return nullptr; + } + + // Note that if we only have a FunctionProtoType, we don't have param decls. + if (const auto *FD = getFunction()) { + if (N < FD->param_size()) + return FD->getParamDecl(N); + } + return nullptr; +} + //===----------------------------------------------------------------------===// // Code completion consumer implementation //===----------------------------------------------------------------------===// @@ -645,7 +726,7 @@ static std::string getOverloadAsString(const CodeCompletionString &CCS) { void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates, - unsigned NumCandidates, SourceLocation OpenParLoc) { + unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced) { OS << "OPENING_PAREN_LOC: "; OpenParLoc.print(OS, SemaRef.getSourceManager()); OS << "\n"; @@ -653,7 +734,7 @@ void PrintingCodeCompleteConsumer::ProcessOverloadCandidates( for (unsigned I = 0; I != NumCandidates; ++I) { if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString( CurrentArg, SemaRef, getAllocator(), CCTUInfo, - includeBriefComments())) { + includeBriefComments(), Braced)) { OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n"; } } |