11
11
#include " Config.h"
12
12
#include " HeuristicResolver.h"
13
13
#include " ParsedAST.h"
14
+ #include " Protocol.h"
14
15
#include " SourceCode.h"
15
16
#include " clang/AST/ASTDiagnostic.h"
16
17
#include " clang/AST/Decl.h"
18
+ #include " clang/AST/DeclBase.h"
17
19
#include " clang/AST/DeclarationName.h"
18
20
#include " clang/AST/Expr.h"
19
21
#include " clang/AST/ExprCXX.h"
23
25
#include " clang/AST/Type.h"
24
26
#include " clang/Basic/Builtins.h"
25
27
#include " clang/Basic/OperatorKinds.h"
28
+ #include " clang/Basic/SourceLocation.h"
26
29
#include " clang/Basic/SourceManager.h"
27
30
#include " llvm/ADT/DenseSet.h"
31
+ #include " llvm/ADT/STLExtras.h"
32
+ #include " llvm/ADT/SmallVector.h"
28
33
#include " llvm/ADT/StringExtras.h"
29
34
#include " llvm/ADT/StringRef.h"
30
35
#include " llvm/ADT/Twine.h"
31
36
#include " llvm/Support/Casting.h"
37
+ #include " llvm/Support/ErrorHandling.h"
38
+ #include " llvm/Support/FormatVariadic.h"
32
39
#include " llvm/Support/SaveAndRestore.h"
33
40
#include " llvm/Support/ScopedPrinter.h"
34
41
#include " llvm/Support/raw_ostream.h"
42
+ #include < algorithm>
43
+ #include < iterator>
35
44
#include < optional>
36
45
#include < string>
37
46
@@ -372,6 +381,25 @@ maybeDropCxxExplicitObjectParameters(ArrayRef<const ParmVarDecl *> Params) {
372
381
return Params;
373
382
}
374
383
384
+ template <typename R, typename P>
385
+ std::string joinAndTruncate (R &&Range, size_t MaxLength,
386
+ P &&GetAsStringFunction) {
387
+ std::string Out;
388
+ llvm::raw_string_ostream OS (Out);
389
+ llvm::ListSeparator Sep (" , " );
390
+ for (auto &&Element : Range) {
391
+ OS << Sep;
392
+ auto AsString = GetAsStringFunction (Element);
393
+ if (Out.size () + AsString.size () >= MaxLength) {
394
+ OS << " ..." ;
395
+ break ;
396
+ }
397
+ OS << AsString;
398
+ }
399
+ OS.flush ();
400
+ return Out;
401
+ }
402
+
375
403
struct Callee {
376
404
// Only one of Decl or Loc is set.
377
405
// Loc is for calls through function pointers.
@@ -422,7 +450,8 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
422
450
Callee.Decl = E->getConstructor ();
423
451
if (!Callee.Decl )
424
452
return true ;
425
- processCall (Callee, {E->getArgs (), E->getNumArgs ()});
453
+ processCall (Callee, E->getParenOrBraceRange ().getEnd (),
454
+ {E->getArgs (), E->getNumArgs ()});
426
455
return true ;
427
456
}
428
457
@@ -495,7 +524,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
495
524
dyn_cast_or_null<CXXMethodDecl>(Callee.Decl ))
496
525
if (IsFunctor || Method->hasCXXExplicitFunctionObjectParameter ())
497
526
Args = Args.drop_front (1 );
498
- processCall (Callee, Args);
527
+ processCall (Callee, E-> getRParenLoc (), Args);
499
528
return true ;
500
529
}
501
530
@@ -709,7 +738,8 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
709
738
private:
710
739
using NameVec = SmallVector<StringRef, 8 >;
711
740
712
- void processCall (Callee Callee, llvm::ArrayRef<const Expr *> Args) {
741
+ void processCall (Callee Callee, SourceRange LParenOrBraceRange,
742
+ llvm::ArrayRef<const Expr *> Args) {
713
743
assert (Callee.Decl || Callee.Loc );
714
744
715
745
if (!Cfg.InlayHints .Parameters || Args.size () == 0 )
@@ -721,6 +751,9 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
721
751
if (Ctor->isCopyOrMoveConstructor ())
722
752
return ;
723
753
754
+ SmallVector<std::string> FormattedDefaultArgs;
755
+ bool HasNonDefaultArgs = false ;
756
+
724
757
ArrayRef<const ParmVarDecl *> Params, ForwardedParams;
725
758
// Resolve parameter packs to their forwarded parameter
726
759
SmallVector<const ParmVarDecl *> ForwardedParamsStorage;
@@ -755,12 +788,33 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
755
788
bool NameHint = shouldHintName (Args[I], Name);
756
789
bool ReferenceHint = shouldHintReference (Params[I], ForwardedParams[I]);
757
790
791
+ bool IsDefault = isa<CXXDefaultArgExpr>(Args[I]);
792
+ HasNonDefaultArgs |= !IsDefault;
793
+ if (Cfg.InlayHints .DefaultArguments && IsDefault) {
794
+ auto SourceText = Lexer::getSourceText (
795
+ CharSourceRange::getTokenRange (Params[I]->getDefaultArgRange ()),
796
+ AST.getSourceManager (), AST.getLangOpts ());
797
+ FormattedDefaultArgs.emplace_back (llvm::formatv (
798
+ " {0}: {1}" , Name,
799
+ SourceText.size () > Cfg.InlayHints .TypeNameLimit ? " ..."
800
+ : SourceText));
801
+ }
802
+
758
803
if (NameHint || ReferenceHint) {
759
804
addInlayHint (Args[I]->getSourceRange (), HintSide::Left,
760
805
InlayHintKind::Parameter, ReferenceHint ? " &" : " " ,
761
806
NameHint ? Name : " " , " : " );
762
807
}
763
808
}
809
+
810
+ if (!FormattedDefaultArgs.empty ()) {
811
+ std::string Hint =
812
+ joinAndTruncate (FormattedDefaultArgs, Cfg.InlayHints .TypeNameLimit ,
813
+ [](const auto &E) { return E; });
814
+ addInlayHint (LParenOrBraceRange, HintSide::Left,
815
+ InlayHintKind::DefaultArgument,
816
+ HasNonDefaultArgs ? " , " : " " , Hint, " " );
817
+ }
764
818
}
765
819
766
820
static bool isSetter (const FunctionDecl *Callee, const NameVec &ParamNames) {
@@ -968,6 +1022,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> {
968
1022
CHECK_KIND (Type, DeducedTypes);
969
1023
CHECK_KIND (Designator, Designators);
970
1024
CHECK_KIND (BlockEnd, BlockEnd);
1025
+ CHECK_KIND (DefaultArgument, DefaultArguments);
971
1026
#undef CHECK_KIND
972
1027
}
973
1028
0 commit comments