@@ -45,7 +45,7 @@ template <class E> class Added {
45
45
E Contents;
46
46
public:
47
47
Added () { }
48
- Added (E && NewContents) { Contents = NewContents; }
48
+ Added (E NewContents) { Contents = NewContents; }
49
49
const Added<E> &operator =(const Added<E> &rhs) {
50
50
Contents = rhs.Contents ;
51
51
return *this ;
@@ -472,13 +472,17 @@ class Instrumenter {
472
472
}
473
473
};
474
474
475
- bool doTypeCheck (ASTContext &Ctx, DeclContext *DC,
476
- Added<Expr *> &parsedExpr) {
475
+ template <class T > bool doTypeCheck (ASTContext &Ctx,
476
+ DeclContext *DC,
477
+ Added<T*> &parsedExpr) {
477
478
DiagnosticEngine diags (Ctx.SourceMgr );
478
479
ErrorGatherer errorGatherer (diags);
479
480
480
481
TypeChecker TC (Ctx, diags);
481
- TC.typeCheckExpression (*parsedExpr, DC);
482
+
483
+ Expr *E = *parsedExpr;
484
+ TC.typeCheckExpression (E, DC);
485
+ parsedExpr = Added<T*>(dyn_cast<T>(E));
482
486
483
487
if (*parsedExpr) {
484
488
ErrorFinder errorFinder;
@@ -515,7 +519,7 @@ class Instrumenter {
515
519
std::tie (Base_RE, BaseVD) = digForVariable (MRE->getBase ());
516
520
517
521
if (*Base_RE) {
518
- Added <Expr *> Log = logDeclOrMemberRef (Base_RE);
522
+ Added<Stmt *> Log = logDeclOrMemberRef (Base_RE);
519
523
if (*Log) {
520
524
Elements.insert (Elements.begin () + (EI + 1 ), *Log);
521
525
++EI;
@@ -538,7 +542,7 @@ class Instrumenter {
538
542
AE->setImplicit (true );
539
543
std::string Name = digForName (AE->getDest ());
540
544
541
- Added<Expr *> Log (buildLoggerCall (
545
+ Added<Stmt *> Log (buildLoggerCall (
542
546
new (Context) DeclRefExpr (ConcreteDeclRef (PV.second ),
543
547
SourceLoc (),
544
548
true , // implicit
@@ -563,41 +567,19 @@ class Instrumenter {
563
567
StringRef FnName = FnD->getNameStr ();
564
568
if (FnName.equals (" print" ) || FnName.equals (" debugPrint" )) {
565
569
const bool isDebugPrint = FnName.equals (" debugPrint" );
566
- Expr *object = nullptr ;
567
- Expr *appendNewline = nullptr ;
568
- if (ParenExpr *PE = dyn_cast<ParenExpr>(AE->getArg ())) {
569
- object = PE->getSubExpr ();
570
- Added<Expr *> appendNewlineAdded (
571
- new (Context) BooleanLiteralExpr (true , SourceLoc (), true ));
572
- doTypeCheck (Context, TypeCheckDC, appendNewlineAdded);
573
- appendNewline = *appendNewlineAdded;
574
- } else if (TupleExpr *TE = dyn_cast<TupleExpr>(AE->getArg ())) {
575
- if (TE->getNumElements () == 2 ) {
576
- object = TE->getElement (0 );
577
- appendNewline = TE->getElement (1 );
578
- }
579
- }
580
- if (object && !object->getType ()->is <InOutType>() &&
581
- appendNewline && !appendNewline->getType ()->is <InOutType>()) {
582
- std::pair<PatternBindingDecl *, VarDecl *> objectPV =
583
- buildPatternAndVariable (object);
584
- std::pair<PatternBindingDecl *, VarDecl *> appendNewlinePV =
585
- buildPatternAndVariable (appendNewline);
586
- Added<Expr *> Log = logPrint (isDebugPrint,
587
- objectPV.second ,
588
- appendNewlinePV.second ,
589
- AE->getSourceRange ());
590
- if (*Log) {
591
- Elements[EI] = objectPV.first ;
592
- Elements.insert (Elements.begin () + (EI + 1 ),
593
- objectPV.second );
594
- Elements.insert (Elements.begin () + (EI + 2 ),
595
- appendNewlinePV.first );
596
- Elements.insert (Elements.begin () + (EI + 3 ),
597
- appendNewlinePV.second );
598
- Elements.insert (Elements.begin () + (EI + 4 ),
599
- *Log);
600
- EI += 4 ;
570
+ PatternBindingDecl *ArgPattern = nullptr ;
571
+ VarDecl *ArgVariable = nullptr ;
572
+ Added<Stmt *> Log = logPrint (isDebugPrint, AE,
573
+ ArgPattern, ArgVariable);
574
+ if (*Log) {
575
+ if (ArgPattern) {
576
+ assert (ArgVariable);
577
+ Elements[EI] = ArgPattern;
578
+ Elements.insert (Elements.begin () + (EI + 1 ), ArgVariable);
579
+ Elements.insert (Elements.begin () + (EI + 2 ), *Log);
580
+ EI += 2 ;
581
+ } else {
582
+ Elements[EI] = *Log;
601
583
}
602
584
}
603
585
Handled = true ;
@@ -615,14 +597,14 @@ class Instrumenter {
615
597
std::tie (Target_RE, TargetVD) = digForVariable (TargetExpr);
616
598
617
599
if (TargetVD) {
618
- Added<Expr *> Log = logDeclOrMemberRef (Target_RE);
600
+ Added<Stmt *> Log = logDeclOrMemberRef (Target_RE);
619
601
if (*Log) {
620
602
Elements.insert (Elements.begin () + (EI + 1 ), *Log);
621
603
++EI;
622
604
}
623
605
}
624
606
} else if (DeclRefExpr *DRE = digForInoutDeclRef (AE->getArg ())) {
625
- Added<Expr *> Log = logDeclOrMemberRef (DRE);
607
+ Added<Stmt *> Log = logDeclOrMemberRef (DRE);
626
608
if (*Log) {
627
609
Elements.insert (Elements.begin () + (EI + 1 ), *Log);
628
610
++EI;
@@ -634,7 +616,7 @@ class Instrumenter {
634
616
// do the same as for all other expressions
635
617
std::pair<PatternBindingDecl *, VarDecl *> PV =
636
618
buildPatternAndVariable (E);
637
- Added<Expr *> Log = buildLoggerCall (
619
+ Added<Stmt *> Log = buildLoggerCall (
638
620
new (Context) DeclRefExpr (ConcreteDeclRef (PV.second ),
639
621
SourceLoc (),
640
622
true , // implicit
@@ -654,7 +636,7 @@ class Instrumenter {
654
636
Context.TheEmptyTupleType ) {
655
637
std::pair<PatternBindingDecl *, VarDecl *> PV =
656
638
buildPatternAndVariable (E);
657
- Added <Expr *> Log = buildLoggerCall (
639
+ Added<Stmt *> Log = buildLoggerCall (
658
640
new (Context) DeclRefExpr (ConcreteDeclRef (PV.second ),
659
641
SourceLoc (),
660
642
true , // implicit
@@ -684,7 +666,7 @@ class Instrumenter {
684
666
ReturnStmt *NRS = new (Context) ReturnStmt (SourceLoc (),
685
667
DRE,
686
668
true ); // implicit
687
- Added <Expr *> Log = buildLoggerCall (
669
+ Added<Stmt *> Log = buildLoggerCall (
688
670
new (Context) DeclRefExpr (ConcreteDeclRef (PV.second ),
689
671
SourceLoc (),
690
672
true , // implicit
@@ -717,7 +699,7 @@ class Instrumenter {
717
699
if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
718
700
if (VarDecl *VD = PBD->getSingleVar ()) {
719
701
if (VD->getParentInitializer ()) {
720
- Added<Expr *> Log = logVarDecl (VD);
702
+ Added<Stmt *> Log = logVarDecl (VD);
721
703
if (*Log) {
722
704
Elements.insert (Elements.begin () + (EI + 1 ), *Log);
723
705
++EI;
@@ -753,7 +735,7 @@ class Instrumenter {
753
735
// log*() functions return a newly-created log expression to be inserted
754
736
// after or instead of the expression they're looking at. Only call this
755
737
// if the variable has an initializer.
756
- Added<Expr *> logVarDecl (VarDecl *VD) {
738
+ Added<Stmt *> logVarDecl (VarDecl *VD) {
757
739
if (isa<ConstructorDecl>(TypeCheckDC) && VD->getNameStr ().equals (" self" )) {
758
740
// Don't log "self" in a constructor
759
741
return nullptr ;
@@ -768,7 +750,7 @@ class Instrumenter {
768
750
VD->getSourceRange (), VD->getName ().str ().str ().c_str ());
769
751
}
770
752
771
- Added <Expr *> logDeclOrMemberRef (Added<Expr *> RE) {
753
+ Added<Stmt *> logDeclOrMemberRef (Added<Expr *> RE) {
772
754
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(*RE)) {
773
755
VarDecl *VD = cast<VarDecl>(DRE->getDecl ());
774
756
@@ -807,24 +789,87 @@ class Instrumenter {
807
789
}
808
790
}
809
791
810
- Added<Expr *> logPrint (bool isDebugPrint, VarDecl *object,
811
- VarDecl *appendNewline, SourceRange SR) {
792
+ std::pair<PatternBindingDecl*, VarDecl*>
793
+ maybeFixupPrintArgument (ApplyExpr *Print) {
794
+ Expr *ArgTuple = Print->getArg ();
795
+ if (ParenExpr *PE = dyn_cast<ParenExpr>(ArgTuple)) {
796
+ std::pair<PatternBindingDecl*, VarDecl*> PV =
797
+ buildPatternAndVariable (PE->getSubExpr ());
798
+ PE->setSubExpr (new (Context) DeclRefExpr (ConcreteDeclRef (PV.second ),
799
+ SourceLoc (),
800
+ true , // implicit
801
+ AccessSemantics::Ordinary,
802
+ PE->getSubExpr ()->getType ()));
803
+ return PV;
804
+ } else if (TupleExpr *TE = dyn_cast<TupleExpr>(ArgTuple)) {
805
+ if (TE->getNumElements () == 0 ) {
806
+ return std::make_pair (nullptr , nullptr );
807
+ } else {
808
+ // Are we using print() specialized to handle a single argument,
809
+ // or is actually only the first argument of interest and the rest are
810
+ // extra information for print()?
811
+ bool useJustFirst = false ;
812
+ if (TE->hasElementNames ()) {
813
+ useJustFirst = true ;
814
+ } else {
815
+ for (Expr *Arg : TE->getElements ()) {
816
+ if (Arg->getType ()->getAs <InOutType>()) {
817
+ useJustFirst = true ;
818
+ break ;
819
+ }
820
+ }
821
+ }
822
+ if (useJustFirst) {
823
+ std::pair<PatternBindingDecl*, VarDecl*> PV =
824
+ buildPatternAndVariable (TE->getElement (0 ));
825
+ TE->setElement (0 ,
826
+ new (Context) DeclRefExpr (
827
+ ConcreteDeclRef (PV.second ),
828
+ SourceLoc (),
829
+ true , // implicit
830
+ AccessSemantics::Ordinary,
831
+ TE->getElement (0 )->getType ()));
832
+ return PV;
833
+ } else {
834
+ std::pair<PatternBindingDecl*, VarDecl*> PV =
835
+ buildPatternAndVariable (TE);
836
+ Print->setArg (new (Context) DeclRefExpr (
837
+ ConcreteDeclRef (PV.second ),
838
+ SourceLoc (),
839
+ true , // implicit
840
+ AccessSemantics::Ordinary,
841
+ TE->getType ()));
842
+ return PV;
843
+ }
844
+ }
845
+ } else {
846
+ return std::make_pair (nullptr , nullptr );
847
+ }
848
+ }
849
+
850
+ Added<Stmt *> logPrint (bool isDebugPrint, ApplyExpr *AE,
851
+ PatternBindingDecl *&ArgPattern,
852
+ VarDecl *&ArgVariable) {
812
853
const char *LoggerName = isDebugPrint ? " $builtin_debugPrint" :
813
854
" $builtin_print" ;
814
- DeclRefExpr *object_DRE =
815
- new (Context) DeclRefExpr (ConcreteDeclRef (object),
816
- SourceLoc (),
817
- true , // implicit
818
- AccessSemantics::Ordinary,
819
- Type ());
820
- DeclRefExpr *appendNewline_DRE =
821
- new (Context) DeclRefExpr (ConcreteDeclRef (appendNewline),
822
- SourceLoc (),
823
- true , // implicit
824
- AccessSemantics::Ordinary,
825
- Type ());
826
- Expr *Args[] = { object_DRE, appendNewline_DRE };
827
- return buildLoggerCallWithArgs (LoggerName, Args, SR);
855
+
856
+ UnresolvedDeclRefExpr *LoggerRef =
857
+ new (Context) UnresolvedDeclRefExpr (
858
+ Context.getIdentifier (LoggerName),
859
+ DeclRefKind::Ordinary,
860
+ AE->getSourceRange ().End );
861
+
862
+ std::tie (ArgPattern, ArgVariable) =
863
+ maybeFixupPrintArgument (AE);
864
+
865
+ AE->setFn (LoggerRef);
866
+ Added<ApplyExpr*> AddedApply (AE); // safe because we've fixed up the args
867
+
868
+ if (!doTypeCheck (Context, TypeCheckDC, AddedApply)) {
869
+ return nullptr ;
870
+ }
871
+
872
+ return buildLoggerCallWithApply (AddedApply, AE->getSourceRange ());
828
873
}
829
874
830
875
std::pair<PatternBindingDecl*, VarDecl*>
@@ -863,7 +908,7 @@ class Instrumenter {
863
908
return std::make_pair (PBD, VD);
864
909
}
865
910
866
- Added<Expr *> buildLoggerCall (Added<Expr *> E, SourceRange SR,
911
+ Added<Stmt *> buildLoggerCall (Added<Expr *> E, SourceRange SR,
867
912
const char *Name) {
868
913
assert (Name);
869
914
std::string *NameInContext = Context.AllocateObjectCopy (std::string (Name));
@@ -891,15 +936,15 @@ class Instrumenter {
891
936
SR);
892
937
}
893
938
894
- Added <Expr *> buildScopeEntry (SourceRange SR) {
939
+ Added<Stmt *> buildScopeEntry (SourceRange SR) {
895
940
return buildScopeCall (SR, false );
896
941
}
897
942
898
- Added <Expr *> buildScopeExit (SourceRange SR) {
943
+ Added<Stmt *> buildScopeExit (SourceRange SR) {
899
944
return buildScopeCall (SR, true );
900
945
}
901
946
902
- Added<Expr *> buildScopeCall (SourceRange SR, bool IsExit) {
947
+ Added<Stmt *> buildScopeCall (SourceRange SR, bool IsExit) {
903
948
const char *LoggerName = IsExit ? " $builtin_log_scope_exit"
904
949
: " $builtin_log_scope_entry" ;
905
950
@@ -908,7 +953,7 @@ class Instrumenter {
908
953
SR);
909
954
}
910
955
911
- Added<Expr *> buildLoggerCallWithArgs (const char *LoggerName,
956
+ Added<Stmt *> buildLoggerCallWithArgs (const char *LoggerName,
912
957
MutableArrayRef<Expr *> Args,
913
958
SourceRange SR) {
914
959
Expr *LoggerArgs = nullptr ;
@@ -930,9 +975,20 @@ class Instrumenter {
930
975
931
976
LoggerRef->setImplicit (true );
932
977
933
- Expr *LoggerCall = new (Context) CallExpr (LoggerRef, LoggerArgs, true ,
934
- Type ());
978
+ ApplyExpr *LoggerCall = new (Context) CallExpr (LoggerRef, LoggerArgs, true ,
979
+ Type ());
980
+ Added<ApplyExpr*> AddedLogger (LoggerCall);
981
+
982
+ if (!doTypeCheck (Context, TypeCheckDC, AddedLogger)) {
983
+ return nullptr ;
984
+ }
985
+
986
+ return buildLoggerCallWithApply (AddedLogger, SR);
987
+ }
935
988
989
+ // Assumes Apply has already been type-checked.
990
+ Added<Stmt *> buildLoggerCallWithApply (Added<ApplyExpr*> Apply,
991
+ SourceRange SR) {
936
992
std::pair<unsigned , unsigned > StartLC =
937
993
Context.SourceMgr .getLineAndColumn (SR.Start );
938
994
@@ -961,8 +1017,17 @@ class Instrumenter {
961
1017
Expr *EndColumn = new (Context) IntegerLiteralExpr (end_column_buf,
962
1018
SR.End , true );
963
1019
1020
+ std::pair<PatternBindingDecl *, VarDecl *> PV =
1021
+ buildPatternAndVariable (*Apply);
1022
+
1023
+ DeclRefExpr *DRE = new (Context) DeclRefExpr (ConcreteDeclRef (PV.second ),
1024
+ SourceLoc (),
1025
+ true , // implicit
1026
+ AccessSemantics::Ordinary,
1027
+ Apply->getType ());
1028
+
964
1029
Expr *SendDataArgExprs[] = {
965
- LoggerCall ,
1030
+ DRE ,
966
1031
StartLine,
967
1032
EndLine,
968
1033
StartColumn,
@@ -979,15 +1044,25 @@ class Instrumenter {
979
1044
980
1045
SendDataRef->setImplicit (true );
981
1046
982
- Added<Expr *> SendDataCall = new (Context) CallExpr (SendDataRef,
983
- SendDataArgs, true ,
984
- Type ());
1047
+ Expr * SendDataCall = new (Context) CallExpr (SendDataRef,
1048
+ SendDataArgs, true ,
1049
+ Type ());
1050
+ Added<Expr *> AddedSendData (SendDataCall);
985
1051
986
- if (!doTypeCheck (Context, TypeCheckDC, SendDataCall )) {
1052
+ if (!doTypeCheck (Context, TypeCheckDC, AddedSendData )) {
987
1053
return nullptr ;
988
1054
}
989
1055
990
- return SendDataCall;
1056
+ ASTNode Elements[] = {
1057
+ PV.first ,
1058
+ PV.second ,
1059
+ SendDataCall
1060
+ };
1061
+
1062
+ BraceStmt *BS = BraceStmt::create (Context, SourceLoc (), Elements,
1063
+ SourceLoc (), true );
1064
+
1065
+ return BS;
991
1066
}
992
1067
};
993
1068
0 commit comments