@@ -3826,11 +3826,59 @@ inline constexpr const char *IntegerLiterals[] = {
3826
3826
" 242" , " 243" , " 244" , " 245" , " 246" , " 247" , " 248" , " 249" , " 250" , " 251" , " 252" ,
3827
3827
" 253" , " 254" , " 255" };
3828
3828
3829
- void Preprocessor::HandleEmbedDirectiveNaive (SourceLocation HashLoc,
3830
- SourceLocation FilenameLoc,
3831
- LexEmbedParametersResult &Params,
3832
- StringRef BinaryContents,
3833
- const size_t TargetCharWidth) {
3829
+ static size_t
3830
+ ComputeNaiveReserveSize (const Preprocessor::LexEmbedParametersResult &Params,
3831
+ StringRef TypeName, StringRef BinaryContents,
3832
+ SmallVectorImpl<char > &TokSpellingBuffer) {
3833
+ size_t ReserveSize = 0 ;
3834
+ if (BinaryContents.empty ()) {
3835
+ if (Params.MaybeIfEmptyParam ) {
3836
+ for (const auto &Tok : Params.MaybeIfEmptyParam ->Tokens ) {
3837
+ const size_t TokLen = Tok.getLength ();
3838
+ if (TokLen > TokSpellingBuffer.size ()) {
3839
+ TokSpellingBuffer.resize (TokLen);
3840
+ }
3841
+ ReserveSize += TokLen;
3842
+ }
3843
+ }
3844
+ } else {
3845
+ if (Params.MaybePrefixParam ) {
3846
+ for (const auto &Tok : Params.MaybePrefixParam ->Tokens ) {
3847
+ const size_t TokLen = Tok.getLength ();
3848
+ if (TokLen > TokSpellingBuffer.size ()) {
3849
+ TokSpellingBuffer.resize (TokLen);
3850
+ }
3851
+ ReserveSize += TokLen;
3852
+ }
3853
+ }
3854
+ for (const auto &Byte : BinaryContents) {
3855
+ ReserveSize += 3 + TypeName.size (); // ((type-name)
3856
+ if (Byte > 99 ) {
3857
+ ReserveSize += 3 ; // ###
3858
+ } else if (Byte > 9 ) {
3859
+ ReserveSize += 2 ; // ##
3860
+ } else {
3861
+ ReserveSize += 1 ; // #
3862
+ }
3863
+ ReserveSize += 2 ; // ),
3864
+ }
3865
+ if (Params.MaybePrefixParam ) {
3866
+ for (const auto &Tok : Params.MaybePrefixParam ->Tokens ) {
3867
+ const size_t TokLen = Tok.getLength ();
3868
+ if (TokLen > TokSpellingBuffer.size ()) {
3869
+ TokSpellingBuffer.resize (TokLen);
3870
+ }
3871
+ ReserveSize += TokLen;
3872
+ }
3873
+ }
3874
+ }
3875
+ return ReserveSize;
3876
+ }
3877
+
3878
+ void Preprocessor::HandleEmbedDirectiveNaive (
3879
+ SourceLocation HashLoc, SourceLocation FilenameLoc,
3880
+ const LexEmbedParametersResult &Params, StringRef BinaryContents,
3881
+ const size_t TargetCharWidth) {
3834
3882
// Load up a new embed buffer for this file and set of parameters in
3835
3883
// particular.
3836
3884
EmbedBuffers.push_back (" " );
@@ -3841,30 +3889,37 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3841
3889
return PrefixNumber.concat (" >" );
3842
3890
}(EmbedBufferNumberVal);
3843
3891
std::string &TargetEmbedBuffer = EmbedBuffers.back ();
3892
+ const size_t TotalSize = BinaryContents.size ();
3893
+ // In the future, this might change/improve.
3894
+ const StringRef TypeName = " unsigned char" ;
3844
3895
3845
- // In the future, this might improve.
3846
- const StringRef SmallestType = " unsigned char" ;
3896
+ SmallVector<char , 32 > TokSpellingBuffer (32 , 0 );
3897
+ const size_t ReserveSize = ComputeNaiveReserveSize (
3898
+ Params, TypeName, BinaryContents, TokSpellingBuffer);
3899
+ TargetEmbedBuffer.reserve (ReserveSize);
3847
3900
3848
3901
// Generate the look-alike source file
3849
3902
if (BinaryContents.empty ()) {
3850
3903
if (Params.MaybeIfEmptyParam ) {
3851
- PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam ;
3904
+ const PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam ;
3852
3905
for (const auto &Tok : EmptyParam.Tokens ) {
3853
- TargetEmbedBuffer.append (this ->getSpelling (Tok));
3906
+ StringRef Spelling = this ->getSpelling (Tok, TokSpellingBuffer);
3907
+ TargetEmbedBuffer.append (Spelling.data (), Spelling.size ());
3854
3908
}
3855
3909
}
3856
3910
} else {
3857
3911
if (Params.MaybePrefixParam ) {
3858
- PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
3912
+ const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
3859
3913
for (const auto &Tok : PrefixParam.Tokens ) {
3860
- TargetEmbedBuffer.append (this ->getSpelling (Tok));
3914
+ StringRef Spelling = this ->getSpelling (Tok, TokSpellingBuffer);
3915
+ TargetEmbedBuffer.append (Spelling.data (), Spelling.size ());
3861
3916
}
3862
3917
}
3863
3918
for (size_t I = 0 ; I < BinaryContents.size (); ++I) {
3864
3919
unsigned char ByteValue = BinaryContents[I];
3865
3920
StringRef ByteRepresentation = IntegerLiterals[ByteValue];
3866
3921
TargetEmbedBuffer.append (2 , ' (' );
3867
- TargetEmbedBuffer.append (SmallestType .data (), SmallestType .size ());
3922
+ TargetEmbedBuffer.append (TypeName .data (), TypeName .size ());
3868
3923
TargetEmbedBuffer.append (1 , ' )' );
3869
3924
TargetEmbedBuffer.append (ByteRepresentation.data (),
3870
3925
ByteRepresentation.size ());
@@ -3875,9 +3930,10 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3875
3930
}
3876
3931
}
3877
3932
if (Params.MaybeSuffixParam ) {
3878
- PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
3933
+ const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
3879
3934
for (const auto &Tok : SuffixParam.Tokens ) {
3880
- TargetEmbedBuffer.append (this ->getSpelling (Tok));
3935
+ StringRef Spelling = this ->getSpelling (Tok, TokSpellingBuffer);
3936
+ TargetEmbedBuffer.append (Spelling.data (), Spelling.size ());
3881
3937
}
3882
3938
}
3883
3939
}
@@ -3898,7 +3954,7 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3898
3954
static bool TokenListIsCharacterArray (Preprocessor &PP,
3899
3955
const size_t TargetCharWidth,
3900
3956
bool IsPrefix,
3901
- SmallVectorImpl<Token> &Tokens,
3957
+ const SmallVectorImpl<Token> &Tokens,
3902
3958
llvm::SmallVectorImpl<char > &Output) {
3903
3959
const bool IsSuffix = !IsPrefix;
3904
3960
size_t MaxValue =
@@ -4004,7 +4060,7 @@ static void TripleEncodeBase64(StringRef Bytes0, StringRef Bytes1,
4004
4060
void Preprocessor::HandleEmbedDirectiveBuiltin (
4005
4061
SourceLocation HashLoc, const Token &FilenameTok,
4006
4062
StringRef ResolvedFilename, StringRef SearchPath, StringRef RelativePath,
4007
- LexEmbedParametersResult &Params, StringRef BinaryContents,
4063
+ const LexEmbedParametersResult &Params, StringRef BinaryContents,
4008
4064
const size_t TargetCharWidth) {
4009
4065
// if it's empty, just process it like a normal expanded token stream
4010
4066
if (BinaryContents.empty ()) {
@@ -4017,7 +4073,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
4017
4073
if (Params.MaybePrefixParam ) {
4018
4074
// If we ahve a prefix, validate that it's a good fit for direct data
4019
4075
// embedded (and prepare to prepend it)
4020
- PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
4076
+ const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
4021
4077
if (!TokenListIsCharacterArray (*this , TargetCharWidth, true ,
4022
4078
PrefixParam.Tokens , BinaryPrefix)) {
4023
4079
HandleEmbedDirectiveNaive (HashLoc, FilenameTok.getLocation (), Params,
@@ -4028,7 +4084,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
4028
4084
if (Params.MaybeSuffixParam ) {
4029
4085
// If we ahve a prefix, validate that it's a good fit for direct data
4030
4086
// embedding (and prepare to append it)
4031
- PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
4087
+ const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
4032
4088
if (!TokenListIsCharacterArray (*this , TargetCharWidth, false ,
4033
4089
SuffixParam.Tokens , BinarySuffix)) {
4034
4090
HandleEmbedDirectiveNaive (HashLoc, FilenameTok.getLocation (), Params,
@@ -4047,9 +4103,25 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
4047
4103
return PrefixNumber.concat (" >" );
4048
4104
}(EmbedBufferNumberVal);
4049
4105
std::string &TargetEmbedBuffer = EmbedBuffers.back ();
4106
+ StringRef TypeName = " unsigned char" ;
4107
+ const size_t TotalSize =
4108
+ BinaryPrefix.size () + BinaryContents.size () + BinarySuffix.size ();
4109
+ const size_t ReserveSize = // add up for necessary size:
4110
+ 19 // __builtin_pp_embed(
4111
+ + TypeName.size () // type-name
4112
+ + 2 // ,"
4113
+ + ResolvedFilename.size () // file-name
4114
+ + 3 // ","
4115
+ + (((TotalSize + 2 ) / 3 ) * 4 ) // base64-string
4116
+ + 2 // ");
4117
+ ;
4118
+ // Reserve appropriate size
4119
+ TargetEmbedBuffer.reserve (ReserveSize);
4050
4120
4051
4121
// Generate the look-alike source file
4052
- TargetEmbedBuffer.append (" __builtin_pp_embed(unsigned char,\" " );
4122
+ TargetEmbedBuffer.append (" __builtin_pp_embed(" );
4123
+ TargetEmbedBuffer.append (TypeName.data (), TypeName.size ());
4124
+ TargetEmbedBuffer.append (" ,\" " );
4053
4125
TargetEmbedBuffer.append (ResolvedFilename.data (), ResolvedFilename.size ());
4054
4126
TargetEmbedBuffer.append (" \" ,\" " );
4055
4127
// include the prefix(...) and suffix(...) binary data in the total contents
0 commit comments