aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/CodeCompleteConsumer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/CodeCompleteConsumer.cpp')
-rw-r--r--clang/lib/Sema/CodeCompleteConsumer.cpp85
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";
}
}