@@ -3854,11 +3854,59 @@ inline constexpr const char *IntegerLiterals[] = {
3854
3854
" 242" , " 243" , " 244" , " 245" , " 246" , " 247" , " 248" , " 249" , " 250" , " 251" , " 252" ,
3855
3855
" 253" , " 254" , " 255" };
3856
3856
3857
- void Preprocessor::HandleEmbedDirectiveNaive (SourceLocation HashLoc,
3858
- SourceLocation FilenameLoc,
3859
- LexEmbedParametersResult &Params,
3860
- StringRef BinaryContents,
3861
- const size_t TargetCharWidth) {
3857
+ static size_t
3858
+ ComputeNaiveReserveSize (const Preprocessor::LexEmbedParametersResult &Params,
3859
+ StringRef TypeName, StringRef BinaryContents,
3860
+ SmallVectorImpl<char > &TokSpellingBuffer) {
3861
+ size_t ReserveSize = 0 ;
3862
+ if (BinaryContents.empty ()) {
3863
+ if (Params.MaybeIfEmptyParam ) {
3864
+ for (const auto &Tok : Params.MaybeIfEmptyParam ->Tokens ) {
3865
+ const size_t TokLen = Tok.getLength ();
3866
+ if (TokLen > TokSpellingBuffer.size ()) {
3867
+ TokSpellingBuffer.resize (TokLen);
3868
+ }
3869
+ ReserveSize += TokLen;
3870
+ }
3871
+ }
3872
+ } else {
3873
+ if (Params.MaybePrefixParam ) {
3874
+ for (const auto &Tok : Params.MaybePrefixParam ->Tokens ) {
3875
+ const size_t TokLen = Tok.getLength ();
3876
+ if (TokLen > TokSpellingBuffer.size ()) {
3877
+ TokSpellingBuffer.resize (TokLen);
3878
+ }
3879
+ ReserveSize += TokLen;
3880
+ }
3881
+ }
3882
+ for (const auto &Byte : BinaryContents) {
3883
+ ReserveSize += 3 + TypeName.size (); // ((type-name)
3884
+ if (Byte > 99 ) {
3885
+ ReserveSize += 3 ; // ###
3886
+ } else if (Byte > 9 ) {
3887
+ ReserveSize += 2 ; // ##
3888
+ } else {
3889
+ ReserveSize += 1 ; // #
3890
+ }
3891
+ ReserveSize += 2 ; // ),
3892
+ }
3893
+ if (Params.MaybePrefixParam ) {
3894
+ for (const auto &Tok : Params.MaybePrefixParam ->Tokens ) {
3895
+ const size_t TokLen = Tok.getLength ();
3896
+ if (TokLen > TokSpellingBuffer.size ()) {
3897
+ TokSpellingBuffer.resize (TokLen);
3898
+ }
3899
+ ReserveSize += TokLen;
3900
+ }
3901
+ }
3902
+ }
3903
+ return ReserveSize;
3904
+ }
3905
+
3906
+ void Preprocessor::HandleEmbedDirectiveNaive (
3907
+ SourceLocation HashLoc, SourceLocation FilenameLoc,
3908
+ const LexEmbedParametersResult &Params, StringRef BinaryContents,
3909
+ const size_t TargetCharWidth) {
3862
3910
// Load up a new embed buffer for this file and set of parameters in
3863
3911
// particular.
3864
3912
EmbedBuffers.push_back (" " );
@@ -3869,30 +3917,37 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3869
3917
return PrefixNumber.concat (" >" );
3870
3918
}(EmbedBufferNumberVal);
3871
3919
std::string &TargetEmbedBuffer = EmbedBuffers.back ();
3920
+ const size_t TotalSize = BinaryContents.size ();
3921
+ // In the future, this might change/improve.
3922
+ const StringRef TypeName = " unsigned char" ;
3872
3923
3873
- // In the future, this might improve.
3874
- const StringRef SmallestType = " unsigned char" ;
3924
+ SmallVector<char , 32 > TokSpellingBuffer (32 , 0 );
3925
+ const size_t ReserveSize = ComputeNaiveReserveSize (
3926
+ Params, TypeName, BinaryContents, TokSpellingBuffer);
3927
+ TargetEmbedBuffer.reserve (ReserveSize);
3875
3928
3876
3929
// Generate the look-alike source file
3877
3930
if (BinaryContents.empty ()) {
3878
3931
if (Params.MaybeIfEmptyParam ) {
3879
- PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam ;
3932
+ const PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam ;
3880
3933
for (const auto &Tok : EmptyParam.Tokens ) {
3881
- TargetEmbedBuffer.append (this ->getSpelling (Tok));
3934
+ StringRef Spelling = this ->getSpelling (Tok, TokSpellingBuffer);
3935
+ TargetEmbedBuffer.append (Spelling.data (), Spelling.size ());
3882
3936
}
3883
3937
}
3884
3938
} else {
3885
3939
if (Params.MaybePrefixParam ) {
3886
- PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
3940
+ const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
3887
3941
for (const auto &Tok : PrefixParam.Tokens ) {
3888
- TargetEmbedBuffer.append (this ->getSpelling (Tok));
3942
+ StringRef Spelling = this ->getSpelling (Tok, TokSpellingBuffer);
3943
+ TargetEmbedBuffer.append (Spelling.data (), Spelling.size ());
3889
3944
}
3890
3945
}
3891
3946
for (size_t I = 0 ; I < BinaryContents.size (); ++I) {
3892
3947
unsigned char ByteValue = BinaryContents[I];
3893
3948
StringRef ByteRepresentation = IntegerLiterals[ByteValue];
3894
3949
TargetEmbedBuffer.append (2 , ' (' );
3895
- TargetEmbedBuffer.append (SmallestType .data (), SmallestType .size ());
3950
+ TargetEmbedBuffer.append (TypeName .data (), TypeName .size ());
3896
3951
TargetEmbedBuffer.append (1 , ' )' );
3897
3952
TargetEmbedBuffer.append (ByteRepresentation.data (),
3898
3953
ByteRepresentation.size ());
@@ -3903,9 +3958,10 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3903
3958
}
3904
3959
}
3905
3960
if (Params.MaybeSuffixParam ) {
3906
- PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
3961
+ const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
3907
3962
for (const auto &Tok : SuffixParam.Tokens ) {
3908
- TargetEmbedBuffer.append (this ->getSpelling (Tok));
3963
+ StringRef Spelling = this ->getSpelling (Tok, TokSpellingBuffer);
3964
+ TargetEmbedBuffer.append (Spelling.data (), Spelling.size ());
3909
3965
}
3910
3966
}
3911
3967
}
@@ -3926,7 +3982,7 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
3926
3982
static bool TokenListIsCharacterArray (Preprocessor &PP,
3927
3983
const size_t TargetCharWidth,
3928
3984
bool IsPrefix,
3929
- SmallVectorImpl<Token> &Tokens,
3985
+ const SmallVectorImpl<Token> &Tokens,
3930
3986
llvm::SmallVectorImpl<char > &Output) {
3931
3987
const bool IsSuffix = !IsPrefix;
3932
3988
size_t MaxValue =
@@ -4032,7 +4088,7 @@ static void TripleEncodeBase64(StringRef Bytes0, StringRef Bytes1,
4032
4088
void Preprocessor::HandleEmbedDirectiveBuiltin (
4033
4089
SourceLocation HashLoc, const Token &FilenameTok,
4034
4090
StringRef ResolvedFilename, StringRef SearchPath, StringRef RelativePath,
4035
- LexEmbedParametersResult &Params, StringRef BinaryContents,
4091
+ const LexEmbedParametersResult &Params, StringRef BinaryContents,
4036
4092
const size_t TargetCharWidth) {
4037
4093
// if it's empty, just process it like a normal expanded token stream
4038
4094
if (BinaryContents.empty ()) {
@@ -4045,7 +4101,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
4045
4101
if (Params.MaybePrefixParam ) {
4046
4102
// If we ahve a prefix, validate that it's a good fit for direct data
4047
4103
// embedded (and prepare to prepend it)
4048
- PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
4104
+ const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
4049
4105
if (!TokenListIsCharacterArray (*this , TargetCharWidth, true ,
4050
4106
PrefixParam.Tokens , BinaryPrefix)) {
4051
4107
HandleEmbedDirectiveNaive (HashLoc, FilenameTok.getLocation (), Params,
@@ -4056,7 +4112,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
4056
4112
if (Params.MaybeSuffixParam ) {
4057
4113
// If we ahve a prefix, validate that it's a good fit for direct data
4058
4114
// embedding (and prepare to append it)
4059
- PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
4115
+ const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
4060
4116
if (!TokenListIsCharacterArray (*this , TargetCharWidth, false ,
4061
4117
SuffixParam.Tokens , BinarySuffix)) {
4062
4118
HandleEmbedDirectiveNaive (HashLoc, FilenameTok.getLocation (), Params,
@@ -4075,9 +4131,25 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
4075
4131
return PrefixNumber.concat (" >" );
4076
4132
}(EmbedBufferNumberVal);
4077
4133
std::string &TargetEmbedBuffer = EmbedBuffers.back ();
4134
+ StringRef TypeName = " unsigned char" ;
4135
+ const size_t TotalSize =
4136
+ BinaryPrefix.size () + BinaryContents.size () + BinarySuffix.size ();
4137
+ const size_t ReserveSize = // add up for necessary size:
4138
+ 19 // __builtin_pp_embed(
4139
+ + TypeName.size () // type-name
4140
+ + 2 // ,"
4141
+ + ResolvedFilename.size () // file-name
4142
+ + 3 // ","
4143
+ + (((TotalSize + 2 ) / 3 ) * 4 ) // base64-string
4144
+ + 2 // ");
4145
+ ;
4146
+ // Reserve appropriate size
4147
+ TargetEmbedBuffer.reserve (ReserveSize);
4078
4148
4079
4149
// Generate the look-alike source file
4080
- TargetEmbedBuffer.append (" __builtin_pp_embed(unsigned char,\" " );
4150
+ TargetEmbedBuffer.append (" __builtin_pp_embed(" );
4151
+ TargetEmbedBuffer.append (TypeName.data (), TypeName.size ());
4152
+ TargetEmbedBuffer.append (" ,\" " );
4081
4153
TargetEmbedBuffer.append (ResolvedFilename.data (), ResolvedFilename.size ());
4082
4154
TargetEmbedBuffer.append (" \" ,\" " );
4083
4155
// include the prefix(...) and suffix(...) binary data in the total contents
0 commit comments