@@ -43,16 +43,28 @@ StringRef ExpressionFormat::toString() const {
4343 llvm_unreachable (" unknown expression format" );
4444}
4545
46- Expected<StringRef> ExpressionFormat::getWildcardRegex () const {
46+ Expected<std::string> ExpressionFormat::getWildcardRegex () const {
47+ auto CreatePrecisionRegex = [this ](StringRef S) {
48+ return (S + Twine (' {' ) + Twine (Precision) + " }" ).str ();
49+ };
50+
4751 switch (Value) {
4852 case Kind::Unsigned:
49- return StringRef (" [0-9]+" );
53+ if (Precision)
54+ return CreatePrecisionRegex (" ([1-9][0-9]*)?[0-9]" );
55+ return std::string (" [0-9]+" );
5056 case Kind::Signed:
51- return StringRef (" -?[0-9]+" );
57+ if (Precision)
58+ return CreatePrecisionRegex (" -?([1-9][0-9]*)?[0-9]" );
59+ return std::string (" -?[0-9]+" );
5260 case Kind::HexUpper:
53- return StringRef (" [0-9A-F]+" );
61+ if (Precision)
62+ return CreatePrecisionRegex (" ([1-9A-F][0-9A-F]*)?[0-9A-F]" );
63+ return std::string (" [0-9A-F]+" );
5464 case Kind::HexLower:
55- return StringRef (" [0-9a-f]+" );
65+ if (Precision)
66+ return CreatePrecisionRegex (" ([1-9a-f][0-9a-f]*)?[0-9a-f]" );
67+ return std::string (" [0-9a-f]+" );
5668 default :
5769 return createStringError (std::errc::invalid_argument,
5870 " trying to match value with invalid format" );
@@ -61,27 +73,47 @@ Expected<StringRef> ExpressionFormat::getWildcardRegex() const {
6173
6274Expected<std::string>
6375ExpressionFormat::getMatchingString (ExpressionValue IntegerValue) const {
76+ uint64_t AbsoluteValue;
77+ StringRef SignPrefix = IntegerValue.isNegative () ? " -" : " " ;
78+
6479 if (Value == Kind::Signed) {
6580 Expected<int64_t > SignedValue = IntegerValue.getSignedValue ();
6681 if (!SignedValue)
6782 return SignedValue.takeError ();
68- return itostr (*SignedValue);
83+ if (*SignedValue < 0 )
84+ AbsoluteValue = cantFail (IntegerValue.getAbsolute ().getUnsignedValue ());
85+ else
86+ AbsoluteValue = *SignedValue;
87+ } else {
88+ Expected<uint64_t > UnsignedValue = IntegerValue.getUnsignedValue ();
89+ if (!UnsignedValue)
90+ return UnsignedValue.takeError ();
91+ AbsoluteValue = *UnsignedValue;
6992 }
7093
71- Expected<uint64_t > UnsignedValue = IntegerValue.getUnsignedValue ();
72- if (!UnsignedValue)
73- return UnsignedValue.takeError ();
94+ std::string AbsoluteValueStr;
7495 switch (Value) {
7596 case Kind::Unsigned:
76- return utostr (*UnsignedValue);
97+ case Kind::Signed:
98+ AbsoluteValueStr = utostr (AbsoluteValue);
99+ break ;
77100 case Kind::HexUpper:
78- return utohexstr (*UnsignedValue, /* LowerCase=*/ false );
79101 case Kind::HexLower:
80- return utohexstr (*UnsignedValue, /* LowerCase=*/ true );
102+ AbsoluteValueStr = utohexstr (AbsoluteValue, Value == Kind::HexLower);
103+ break ;
81104 default :
82105 return createStringError (std::errc::invalid_argument,
83106 " trying to match value with invalid format" );
84107 }
108+
109+ if (Precision > AbsoluteValueStr.size ()) {
110+ unsigned LeadingZeros = Precision - AbsoluteValueStr.size ();
111+ return (Twine (SignPrefix) + std::string (LeadingZeros, ' 0' ) +
112+ AbsoluteValueStr)
113+ .str ();
114+ }
115+
116+ return (Twine (SignPrefix) + AbsoluteValueStr).str ();
85117}
86118
87119Expected<ExpressionValue>
@@ -720,41 +752,59 @@ Expected<std::unique_ptr<Expression>> Pattern::parseNumericSubstitutionBlock(
720752 StringRef DefExpr = StringRef ();
721753 DefinedNumericVariable = None;
722754 ExpressionFormat ExplicitFormat = ExpressionFormat ();
755+ unsigned Precision = 0 ;
723756
724757 // Parse format specifier (NOTE: ',' is also an argument seperator).
725758 size_t FormatSpecEnd = Expr.find (' ,' );
726759 size_t FunctionStart = Expr.find (' (' );
727760 if (FormatSpecEnd != StringRef::npos && FormatSpecEnd < FunctionStart) {
728- Expr = Expr.ltrim (SpaceChars);
729- if (!Expr.consume_front (" %" ))
761+ StringRef FormatExpr = Expr.take_front (FormatSpecEnd);
762+ Expr = Expr.drop_front (FormatSpecEnd + 1 );
763+ FormatExpr = FormatExpr.trim (SpaceChars);
764+ if (!FormatExpr.consume_front (" %" ))
730765 return ErrorDiagnostic::get (
731- SM, Expr, " invalid matching format specification in expression" );
732-
733- // Check for unknown matching format specifier and set matching format in
734- // class instance representing this expression.
735- SMLoc fmtloc = SMLoc::getFromPointer (Expr.data ());
736- switch (popFront (Expr)) {
737- case ' u' :
738- ExplicitFormat = ExpressionFormat (ExpressionFormat::Kind::Unsigned);
739- break ;
740- case ' d' :
741- ExplicitFormat = ExpressionFormat (ExpressionFormat::Kind::Signed);
742- break ;
743- case ' x' :
744- ExplicitFormat = ExpressionFormat (ExpressionFormat::Kind::HexLower);
745- break ;
746- case ' X' :
747- ExplicitFormat = ExpressionFormat (ExpressionFormat::Kind::HexUpper);
748- break ;
749- default :
750- return ErrorDiagnostic::get (SM, fmtloc,
751- " invalid format specifier in expression" );
766+ SM, FormatExpr,
767+ " invalid matching format specification in expression" );
768+
769+ // Parse precision.
770+ if (FormatExpr.consume_front (" ." )) {
771+ if (FormatExpr.consumeInteger (10 , Precision))
772+ return ErrorDiagnostic::get (SM, FormatExpr,
773+ " invalid precision in format specifier" );
752774 }
753775
754- Expr = Expr.ltrim (SpaceChars);
755- if (!Expr.consume_front (" ," ))
776+ if (!FormatExpr.empty ()) {
777+ // Check for unknown matching format specifier and set matching format in
778+ // class instance representing this expression.
779+ SMLoc FmtLoc = SMLoc::getFromPointer (FormatExpr.data ());
780+ switch (popFront (FormatExpr)) {
781+ case ' u' :
782+ ExplicitFormat =
783+ ExpressionFormat (ExpressionFormat::Kind::Unsigned, Precision);
784+ break ;
785+ case ' d' :
786+ ExplicitFormat =
787+ ExpressionFormat (ExpressionFormat::Kind::Signed, Precision);
788+ break ;
789+ case ' x' :
790+ ExplicitFormat =
791+ ExpressionFormat (ExpressionFormat::Kind::HexLower, Precision);
792+ break ;
793+ case ' X' :
794+ ExplicitFormat =
795+ ExpressionFormat (ExpressionFormat::Kind::HexUpper, Precision);
796+ break ;
797+ default :
798+ return ErrorDiagnostic::get (SM, FmtLoc,
799+ " invalid format specifier in expression" );
800+ }
801+ }
802+
803+ FormatExpr = FormatExpr.ltrim (SpaceChars);
804+ if (!FormatExpr.empty ())
756805 return ErrorDiagnostic::get (
757- SM, Expr, " invalid matching format specification in expression" );
806+ SM, FormatExpr,
807+ " invalid matching format specification in expression" );
758808 }
759809
760810 // Save variable definition expression if any.
@@ -814,7 +864,7 @@ Expected<std::unique_ptr<Expression>> Pattern::parseNumericSubstitutionBlock(
814864 Format = *ImplicitFormat;
815865 }
816866 if (!Format)
817- Format = ExpressionFormat (ExpressionFormat::Kind::Unsigned);
867+ Format = ExpressionFormat (ExpressionFormat::Kind::Unsigned, Precision );
818868
819869 std::unique_ptr<Expression> ExpressionPointer =
820870 std::make_unique<Expression>(std::move (ExpressionASTPointer), Format);
@@ -948,7 +998,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
948998 bool IsLegacyLineExpr = false ;
949999 StringRef DefName;
9501000 StringRef SubstStr;
951- StringRef MatchRegexp;
1001+ std::string MatchRegexp;
9521002 size_t SubstInsertIdx = RegExStr.size ();
9531003
9541004 // Parse string variable or legacy @LINE expression.
@@ -992,7 +1042,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix,
9921042 return true ;
9931043 }
9941044 DefName = Name;
995- MatchRegexp = MatchStr;
1045+ MatchRegexp = MatchStr. str () ;
9961046 } else {
9971047 if (IsPseudo) {
9981048 MatchStr = OrigMatchStr;
0 commit comments