diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/CodeCompleteConsumer.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 36 |
2 files changed, 52 insertions, 1 deletions
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp index d8ed8949cb..b9b85dfb80 100644 --- a/lib/Sema/CodeCompleteConsumer.cpp +++ b/lib/Sema/CodeCompleteConsumer.cpp @@ -37,6 +37,7 @@ CodeCompletionString::Chunk::Chunk(ChunkKind Kind, llvm::StringRef Text) case CK_Text: case CK_Placeholder: case CK_Informative: + case CK_ResultType: case CK_CurrentParameter: { char *New = new char [Text.size() + 1]; std::memcpy(New, Text.data(), Text.size()); @@ -112,6 +113,11 @@ CodeCompletionString::Chunk::CreateInformative(StringRef Informative) { } CodeCompletionString::Chunk +CodeCompletionString::Chunk::CreateResultType(StringRef ResultType) { + return Chunk(CK_ResultType, ResultType); +} + +CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter( StringRef CurrentParameter) { return Chunk(CK_CurrentParameter, CurrentParameter); @@ -123,6 +129,7 @@ CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const { case CK_Text: case CK_Placeholder: case CK_Informative: + case CK_ResultType: case CK_CurrentParameter: case CK_LeftParen: case CK_RightParen: @@ -156,6 +163,7 @@ CodeCompletionString::Chunk::Destroy() { case CK_Text: case CK_Placeholder: case CK_Informative: + case CK_ResultType: case CK_CurrentParameter: delete [] Text; break; @@ -186,7 +194,12 @@ std::string CodeCompletionString::getAsString() const { switch (C->Kind) { case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break; case CK_Placeholder: OS << "<#" << C->Text << "#>"; break; - case CK_Informative: OS << "[#" << C->Text << "#]"; break; + + case CK_Informative: + case CK_ResultType: + OS << "[#" << C->Text << "#]"; + break; + case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break; default: OS << C->Text; break; } @@ -236,6 +249,7 @@ void CodeCompletionString::Serialize(llvm::raw_ostream &OS) const { case CK_Text: case CK_Placeholder: case CK_Informative: + case CK_ResultType: case CK_CurrentParameter: { const char *Text = C->Text; unsigned StrLen = strlen(Text); @@ -286,6 +300,7 @@ CodeCompletionString *CodeCompletionString::Deserialize(const char *&Str, case CK_Text: case CK_Placeholder: case CK_Informative: + case CK_ResultType: case CK_CurrentParameter: { unsigned StrLen; if (ReadUnsigned(Str, StrEnd, StrLen) || (Str + StrLen > StrEnd)) diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 6b485ba7a9..1391adfd48 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -829,6 +829,39 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank, } } +/// \brief If the given declaration has an associated type, add it as a result +/// type chunk. +static void AddResultTypeChunk(ASTContext &Context, + NamedDecl *ND, + CodeCompletionString *Result) { + if (!ND) + return; + + // Determine the type of the declaration (if it has a type). + QualType T; + if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) + T = Function->getResultType(); + else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) + T = Method->getResultType(); + else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) + T = FunTmpl->getTemplatedDecl()->getResultType(); + else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) + T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); + else if (isa<UnresolvedUsingValueDecl>(ND)) { + /* Do nothing: ignore unresolved using declarations*/ + } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND)) + T = Value->getType(); + else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND)) + T = Property->getType(); + + if (T.isNull() || Context.hasSameType(T, Context.DependentTy)) + return; + + std::string TypeStr; + T.getAsStringInternal(TypeStr, Context.PrintingPolicy); + Result->AddResultTypeChunk(TypeStr); +} + /// \brief Add function parameter chunks to the given code completion string. static void AddFunctionParameterChunks(ASTContext &Context, FunctionDecl *Function, @@ -1042,6 +1075,8 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) { return Result; } + AddResultTypeChunk(S.Context, ND, Result); + if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) { AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative, S.Context); @@ -1189,6 +1224,7 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString( CodeCompletionString *Result = new CodeCompletionString; FunctionDecl *FDecl = getFunction(); + AddResultTypeChunk(S.Context, FDecl, Result); const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(getFunctionType()); if (!FDecl && !Proto) { |