6
6
//
7
7
// ===----------------------------------------------------------------------===//
8
8
9
+ #include < float.h>
10
+
9
11
#include " clang/Parse/ParseHLSLRootSignature.h"
10
12
11
13
#include " clang/Lex/LiteralSupport.h"
@@ -734,7 +736,8 @@ std::optional<float> RootSignatureParser::parseFloatParam() {
734
736
assert (CurToken.TokKind == TokenKind::pu_equal &&
735
737
" Expects to only be invoked starting at given keyword" );
736
738
// Consume sign modifier
737
- bool Signed = tryConsumeExpectedToken ({TokenKind::pu_plus, TokenKind::pu_minus});
739
+ bool Signed =
740
+ tryConsumeExpectedToken ({TokenKind::pu_plus, TokenKind::pu_minus});
738
741
bool Negated = Signed && CurToken.TokKind == TokenKind::pu_minus;
739
742
740
743
// Handle an uint and interpret it as a float
@@ -747,8 +750,12 @@ std::optional<float> RootSignatureParser::parseFloatParam() {
747
750
auto Int = handleIntLiteral (Negated);
748
751
if (!Int.has_value ())
749
752
return std::nullopt;
750
-
751
753
return (float )Int.value ();
754
+ } else if (tryConsumeExpectedToken (TokenKind::float_literal)) {
755
+ auto Float = handleFloatLiteral (Negated);
756
+ if (!Float.has_value ())
757
+ return std::nullopt;
758
+ return Float.value ();
752
759
}
753
760
754
761
return std::nullopt;
@@ -864,9 +871,10 @@ std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
864
871
PP.getSourceManager (), PP.getLangOpts (),
865
872
PP.getTargetInfo (), PP.getDiagnostics ());
866
873
if (Literal.hadError )
867
- return true ; // Error has already been reported so just return
874
+ return std::nullopt ; // Error has already been reported so just return
868
875
869
- assert (Literal.isIntegerLiteral () && " IsNumberChar will only support digits" );
876
+ assert (Literal.isIntegerLiteral () &&
877
+ " NumSpelling can only consist of digits" );
870
878
871
879
llvm::APSInt Val = llvm::APSInt (32 , false );
872
880
if (Literal.GetIntegerValue (Val)) {
@@ -886,9 +894,10 @@ std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) {
886
894
PP.getSourceManager (), PP.getLangOpts (),
887
895
PP.getTargetInfo (), PP.getDiagnostics ());
888
896
if (Literal.hadError )
889
- return true ; // Error has already been reported so just return
897
+ return std::nullopt ; // Error has already been reported so just return
890
898
891
- assert (Literal.isIntegerLiteral () && " IsNumberChar will only support digits" );
899
+ assert (Literal.isIntegerLiteral () &&
900
+ " NumSpelling can only consist of digits" );
892
901
893
902
llvm::APSInt Val = llvm::APSInt (32 , true );
894
903
if (Literal.GetIntegerValue (Val) || INT32_MAX < Val.getExtValue ()) {
@@ -900,11 +909,48 @@ std::optional<int32_t> RootSignatureParser::handleIntLiteral(bool Negated) {
900
909
}
901
910
902
911
if (Negated)
903
- return static_cast < int32_t >(( -Val). getExtValue ()) ;
912
+ Val = -Val;
904
913
905
914
return static_cast <int32_t >(Val.getExtValue ());
906
915
}
907
916
917
+ std::optional<float > RootSignatureParser::handleFloatLiteral (bool Negated) {
918
+ // Parse the numeric value and do semantic checks on its specification
919
+ clang::NumericLiteralParser Literal (CurToken.NumSpelling , CurToken.TokLoc ,
920
+ PP.getSourceManager (), PP.getLangOpts (),
921
+ PP.getTargetInfo (), PP.getDiagnostics ());
922
+ if (Literal.hadError )
923
+ return std::nullopt; // Error has already been reported so just return
924
+
925
+ assert (Literal.isFloatingLiteral () &&
926
+ " NumSpelling is consistent with isNumberChar in "
927
+ " LexHLSLRootSignature.cpp" );
928
+
929
+ // DXC used `strtod` to convert the token string to a float which corresponds
930
+ // to:
931
+ auto DXCSemantics = llvm::APFloat::Semantics::S_IEEEdouble;
932
+ auto DXCRoundingMode = llvm::RoundingMode::NearestTiesToEven;
933
+
934
+ llvm::APFloat Val =
935
+ llvm::APFloat (llvm::APFloat::EnumToSemantics (DXCSemantics));
936
+ llvm::APFloat::opStatus Status = Literal.GetFloatValue (Val, DXCRoundingMode);
937
+
938
+ // The float is valid with opInexect as this just denotes if rounding occured
939
+ if (Status != llvm::APFloat::opStatus::opOK &&
940
+ Status != llvm::APFloat::opStatus::opInexact)
941
+ return std::nullopt;
942
+
943
+ if (Negated)
944
+ Val = -Val;
945
+
946
+ double DoubleVal = Val.convertToDouble ();
947
+ if (FLT_MAX < DoubleVal || DoubleVal < -FLT_MAX) {
948
+ return std::nullopt;
949
+ }
950
+
951
+ return static_cast <float >(DoubleVal);
952
+ }
953
+
908
954
bool RootSignatureParser::verifyZeroFlag () {
909
955
assert (CurToken.TokKind == TokenKind::int_literal);
910
956
auto X = handleUIntLiteral ();
0 commit comments