Skip to content

Commit

Permalink
Add default values for function parameter chunks
Browse files Browse the repository at this point in the history
Append optional chunks with their default values. For example:
before - "int i", after - "int i = 10"

Patch by Ivan Donchevskii!
    
Differential Revision: https://reviews.llvm.org/D33644



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@308433 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
erikjv committed Jul 19, 2017
1 parent 2e25cff commit 239ecbc
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 16 deletions.
43 changes: 40 additions & 3 deletions lib/Sema/SemaCodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,37 @@ formatBlockPlaceholder(const PrintingPolicy &Policy, const NamedDecl *BlockDecl,
return Result;
}

static std::string GetDefaultValueString(const ParmVarDecl *Param,
const SourceManager &SM,
const LangOptions &LangOpts) {
const Expr *defaultArg = Param->getDefaultArg();
if (!defaultArg)
return "";
const SourceRange SrcRange = defaultArg->getSourceRange();
CharSourceRange CharSrcRange = CharSourceRange::getTokenRange(SrcRange);
bool Invalid = CharSrcRange.isInvalid();
if (Invalid)
return "";
StringRef srcText = Lexer::getSourceText(CharSrcRange, SM, LangOpts, &Invalid);
if (Invalid)
return "";

if (srcText.empty() || srcText == "=") {
// Lexer can't determine the value.
// This happens if the code is incorrect (for example class is forward declared).
return "";
}
std::string DefValue{srcText};
// FIXME: remove this check if the Lexer::getSourceText value is fixed and
// this value always has (or always does not have) '=' in front of it
if (DefValue.at(0) != '=') {
// If we don't have '=' in front of value.
// Lexer returns built-in types values without '=' and user-defined types values with it.
return " = " + DefValue;
}
return " " + DefValue;
}

/// \brief Add function parameter chunks to the given code completion string.
static void AddFunctionParameterChunks(Preprocessor &PP,
const PrintingPolicy &Policy,
Expand Down Expand Up @@ -2431,6 +2462,8 @@ static void AddFunctionParameterChunks(Preprocessor &PP,

// Format the placeholder string.
std::string PlaceholderStr = FormatFunctionParameter(Policy, Param);
if (Param->hasDefaultArg())
PlaceholderStr += GetDefaultValueString(Param, PP.getSourceManager(), PP.getLangOpts());

if (Function->isVariadic() && P == N - 1)
PlaceholderStr += ", ...";
Expand Down Expand Up @@ -3012,10 +3045,14 @@ static void AddOverloadParameterChunks(ASTContext &Context,

// Format the placeholder string.
std::string Placeholder;
if (Function)
Placeholder = FormatFunctionParameter(Policy, Function->getParamDecl(P));
else
if (Function) {
const ParmVarDecl *Param = Function->getParamDecl(P);
Placeholder = FormatFunctionParameter(Policy, Param);
if (Param->hasDefaultArg())
Placeholder += GetDefaultValueString(Param, Context.getSourceManager(), Context.getLangOpts());
} else {
Placeholder = Prototype->getParamType(P).getAsString(Policy);
}

if (P == CurrentArg)
Result.AddCurrentParameterChunk(
Expand Down
2 changes: 1 addition & 1 deletion test/CodeCompletion/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ void f(float x, float y...);
void test() {
::
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:5:5 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: f(<#int i#>{#, <#int j#>{#, <#int k#>#}#})
// CHECK-CC1: f(<#int i#>{#, <#int j = 2#>{#, <#int k = 5#>#}#})
// CHECK-CC1: f(<#float x#>, <#float y, ...#>)
4 changes: 2 additions & 2 deletions test/Index/code-completion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Z::operator int() const {
// CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
// CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
// CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
// CHECK-MEMBER: CXXMethod:{ResultType void}{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )}
// CHECK-MEMBER: CXXMethod:{ResultType void}{Informative Y::}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i = 17}}{RightParen )}
// CHECK-MEMBER: CXXConversion:{TypedText operator int}{LeftParen (}{RightParen )}{Informative const}
// CHECK-MEMBER: CXXMethod:{ResultType Z &}{TypedText operator=}{LeftParen (}{Placeholder const Z &}{RightParen )}
// CHECK-MEMBER: CXXMethod:{ResultType X &}{Text X::}{TypedText operator=}{LeftParen (}{Placeholder const X &}{RightParen )}
Expand Down Expand Up @@ -77,7 +77,7 @@ Z::operator int() const {
// CHECK-EXPR: FieldDecl:{ResultType double}{TypedText member} (17)
// CHECK-EXPR: FieldDecl:{ResultType int}{Text X::}{TypedText member} (9)
// CHECK-EXPR: FieldDecl:{ResultType float}{Text Y::}{TypedText member} (18)
// CHECK-EXPR: CXXMethod:{ResultType void}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i}}{RightParen )} (37)
// CHECK-EXPR: CXXMethod:{ResultType void}{TypedText memfunc}{LeftParen (}{Optional {Placeholder int i = 17}}{RightParen )} (37)
// CHECK-EXPR: Namespace:{TypedText N}{Text ::} (75)
// CHECK-EXPR: Completion contexts:
// CHECK-EXPR-NEXT: Any type
Expand Down
36 changes: 26 additions & 10 deletions test/Index/complete-optional-params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,19 @@ void bar(int a, int b = 42, int c = 42);
void baz(int a = 42, ...);
struct S{ S(int a = 42, int = 42) {} };

class Bar1 { public: Bar1() {} }; class Bar2;
void foo_2(Bar1 b1 = Bar1(), Bar2 b2 = Bar2());

int main() {
foo(42, 42);
bar(42, 42, 42);
baz(42, 42, 42);
S s(42, 42);
foo_2();
}

// RUN: c-index-test -code-completion-at=%s:10:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo}{LeftParen (}{Optional {CurrentParameter int a}{Optional {Comma , }{Placeholder int}}}{RightParen )} (1)
// RUN: c-index-test -code-completion-at=%s:13:9 %s | FileCheck -check-prefix=CHECK-CC1 %s
// CHECK-CC1: OverloadCandidate:{ResultType void}{Text foo}{LeftParen (}{Optional {CurrentParameter int a = 42}{Optional {Comma , }{Placeholder int = 42}}}{RightParen )} (1)
// CHECK-CC1: Completion contexts:
// CHECK-CC1-NEXT: Any type
// CHECK-CC1-NEXT: Any value
Expand All @@ -25,8 +29,8 @@ int main() {
// CHECK-CC1-NEXT: Nested name specifier
// CHECK-CC1-NEXT: Objective-C interface

// RUN: c-index-test -code-completion-at=%s:11:9 %s | FileCheck -check-prefix=CHECK-CC2 %s
// CHECK-CC2: OverloadCandidate:{ResultType void}{Text bar}{LeftParen (}{CurrentParameter int a}{Optional {Comma , }{Placeholder int b}{Optional {Comma , }{Placeholder int c}}}{RightParen )} (1)
// RUN: c-index-test -code-completion-at=%s:14:9 %s | FileCheck -check-prefix=CHECK-CC2 %s
// CHECK-CC2: OverloadCandidate:{ResultType void}{Text bar}{LeftParen (}{CurrentParameter int a}{Optional {Comma , }{Placeholder int b = 42}{Optional {Comma , }{Placeholder int c = 42}}}{RightParen )} (1)
// CHECK-CC2: Completion contexts:
// CHECK-CC2-NEXT: Any type
// CHECK-CC2-NEXT: Any value
Expand All @@ -37,8 +41,8 @@ int main() {
// CHECK-CC2-NEXT: Nested name specifier
// CHECK-CC2-NEXT: Objective-C interface

// RUN: c-index-test -code-completion-at=%s:11:16 %s | FileCheck -check-prefix=CHECK-CC3 %s
// CHECK-CC3: OverloadCandidate:{ResultType void}{Text bar}{LeftParen (}{Placeholder int a}{Optional {Comma , }{Placeholder int b}{Optional {Comma , }{CurrentParameter int c}}}{RightParen )} (1)
// RUN: c-index-test -code-completion-at=%s:14:16 %s | FileCheck -check-prefix=CHECK-CC3 %s
// CHECK-CC3: OverloadCandidate:{ResultType void}{Text bar}{LeftParen (}{Placeholder int a}{Optional {Comma , }{Placeholder int b = 42}{Optional {Comma , }{CurrentParameter int c = 42}}}{RightParen )} (1)
// CHECK-CC3: Completion contexts:
// CHECK-CC3-NEXT: Any type
// CHECK-CC3-NEXT: Any value
Expand All @@ -49,8 +53,8 @@ int main() {
// CHECK-CC3-NEXT: Nested name specifier
// CHECK-CC3-NEXT: Objective-C interface

// RUN: c-index-test -code-completion-at=%s:12:16 %s | FileCheck -check-prefix=CHECK-CC4 %s
// CHECK-CC4: OverloadCandidate:{ResultType void}{Text baz}{LeftParen (}{Optional {Placeholder int a}{Optional {Comma , }{CurrentParameter ...}}}{RightParen )} (1)
// RUN: c-index-test -code-completion-at=%s:15:16 %s | FileCheck -check-prefix=CHECK-CC4 %s
// CHECK-CC4: OverloadCandidate:{ResultType void}{Text baz}{LeftParen (}{Optional {Placeholder int a = 42}{Optional {Comma , }{CurrentParameter ...}}}{RightParen )} (1)
// CHECK-CC4: Completion contexts:
// CHECK-CC4-NEXT: Any type
// CHECK-CC4-NEXT: Any value
Expand All @@ -61,8 +65,8 @@ int main() {
// CHECK-CC4-NEXT: Nested name specifier
// CHECK-CC4-NEXT: Objective-C interface

// RUN: c-index-test -code-completion-at=%s:13:9 %s | FileCheck -check-prefix=CHECK-CC5 %s
// CHECK-CC5: OverloadCandidate:{Text S}{LeftParen (}{Optional {CurrentParameter int a}{Optional {Comma , }{Placeholder int}}}{RightParen )} (1)
// RUN: c-index-test -code-completion-at=%s:16:9 %s | FileCheck -check-prefix=CHECK-CC5 %s
// CHECK-CC5: OverloadCandidate:{Text S}{LeftParen (}{Optional {CurrentParameter int a = 42}{Optional {Comma , }{Placeholder int = 42}}}{RightParen )} (1)
// CHECK-CC5: OverloadCandidate:{Text S}{LeftParen (}{CurrentParameter const S &}{RightParen )} (1)
// CHECK-CC5: Completion contexts:
// CHECK-CC5-NEXT: Any type
Expand All @@ -73,3 +77,15 @@ int main() {
// CHECK-CC5-NEXT: Class name
// CHECK-CC5-NEXT: Nested name specifier
// CHECK-CC5-NEXT: Objective-C interface

// RUN: c-index-test -code-completion-at=%s:17:11 %s | FileCheck -check-prefix=CHECK-CC6 %s
// CHECK-CC6: FunctionDecl:{ResultType void}{TypedText foo_2}{LeftParen (}{Optional {Placeholder Bar1 b1 = Bar1()}{Optional {Comma , }{Placeholder Bar2 b2}}}{RightParen )} (50)
// CHECK-CC6: Completion contexts:
// CHECK-CC6-NEXT: Any type
// CHECK-CC6-NEXT: Any value
// CHECK-CC6-NEXT: Enum tag
// CHECK-CC6-NEXT: Union tag
// CHECK-CC6-NEXT: Struct tag
// CHECK-CC6-NEXT: Class name
// CHECK-CC6-NEXT: Nested name specifier
// CHECK-CC6-NEXT: Objective-C interface

0 comments on commit 239ecbc

Please sign in to comment.