@@ -3854,11 +3854,59 @@ inline constexpr const char *IntegerLiterals[] = {
38543854 " 242" , " 243" , " 244" , " 245" , " 246" , " 247" , " 248" , " 249" , " 250" , " 251" , " 252" ,
38553855 " 253" , " 254" , " 255" };
38563856
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) {
38623910 // Load up a new embed buffer for this file and set of parameters in
38633911 // particular.
38643912 EmbedBuffers.push_back (" " );
@@ -3869,30 +3917,37 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
38693917 return PrefixNumber.concat (" >" );
38703918 }(EmbedBufferNumberVal);
38713919 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" ;
38723923
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);
38753928
38763929 // Generate the look-alike source file
38773930 if (BinaryContents.empty ()) {
38783931 if (Params.MaybeIfEmptyParam ) {
3879- PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam ;
3932+ const PPEmbedParameterIfEmpty &EmptyParam = *Params.MaybeIfEmptyParam ;
38803933 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 ());
38823936 }
38833937 }
38843938 } else {
38853939 if (Params.MaybePrefixParam ) {
3886- PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
3940+ const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
38873941 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 ());
38893944 }
38903945 }
38913946 for (size_t I = 0 ; I < BinaryContents.size (); ++I) {
38923947 unsigned char ByteValue = BinaryContents[I];
38933948 StringRef ByteRepresentation = IntegerLiterals[ByteValue];
38943949 TargetEmbedBuffer.append (2 , ' (' );
3895- TargetEmbedBuffer.append (SmallestType .data (), SmallestType .size ());
3950+ TargetEmbedBuffer.append (TypeName .data (), TypeName .size ());
38963951 TargetEmbedBuffer.append (1 , ' )' );
38973952 TargetEmbedBuffer.append (ByteRepresentation.data (),
38983953 ByteRepresentation.size ());
@@ -3903,9 +3958,10 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
39033958 }
39043959 }
39053960 if (Params.MaybeSuffixParam ) {
3906- PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
3961+ const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
39073962 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 ());
39093965 }
39103966 }
39113967 }
@@ -3926,7 +3982,7 @@ void Preprocessor::HandleEmbedDirectiveNaive(SourceLocation HashLoc,
39263982static bool TokenListIsCharacterArray (Preprocessor &PP,
39273983 const size_t TargetCharWidth,
39283984 bool IsPrefix,
3929- SmallVectorImpl<Token> &Tokens,
3985+ const SmallVectorImpl<Token> &Tokens,
39303986 llvm::SmallVectorImpl<char > &Output) {
39313987 const bool IsSuffix = !IsPrefix;
39323988 size_t MaxValue =
@@ -4032,7 +4088,7 @@ static void TripleEncodeBase64(StringRef Bytes0, StringRef Bytes1,
40324088void Preprocessor::HandleEmbedDirectiveBuiltin (
40334089 SourceLocation HashLoc, const Token &FilenameTok,
40344090 StringRef ResolvedFilename, StringRef SearchPath, StringRef RelativePath,
4035- LexEmbedParametersResult &Params, StringRef BinaryContents,
4091+ const LexEmbedParametersResult &Params, StringRef BinaryContents,
40364092 const size_t TargetCharWidth) {
40374093 // if it's empty, just process it like a normal expanded token stream
40384094 if (BinaryContents.empty ()) {
@@ -4045,7 +4101,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
40454101 if (Params.MaybePrefixParam ) {
40464102 // If we ahve a prefix, validate that it's a good fit for direct data
40474103 // embedded (and prepare to prepend it)
4048- PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
4104+ const PPEmbedParameterPrefix &PrefixParam = *Params.MaybePrefixParam ;
40494105 if (!TokenListIsCharacterArray (*this , TargetCharWidth, true ,
40504106 PrefixParam.Tokens , BinaryPrefix)) {
40514107 HandleEmbedDirectiveNaive (HashLoc, FilenameTok.getLocation (), Params,
@@ -4056,7 +4112,7 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
40564112 if (Params.MaybeSuffixParam ) {
40574113 // If we ahve a prefix, validate that it's a good fit for direct data
40584114 // embedding (and prepare to append it)
4059- PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
4115+ const PPEmbedParameterSuffix &SuffixParam = *Params.MaybeSuffixParam ;
40604116 if (!TokenListIsCharacterArray (*this , TargetCharWidth, false ,
40614117 SuffixParam.Tokens , BinarySuffix)) {
40624118 HandleEmbedDirectiveNaive (HashLoc, FilenameTok.getLocation (), Params,
@@ -4075,9 +4131,25 @@ void Preprocessor::HandleEmbedDirectiveBuiltin(
40754131 return PrefixNumber.concat (" >" );
40764132 }(EmbedBufferNumberVal);
40774133 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);
40784148
40794149 // 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 (" ,\" " );
40814153 TargetEmbedBuffer.append (ResolvedFilename.data (), ResolvedFilename.size ());
40824154 TargetEmbedBuffer.append (" \" ,\" " );
40834155 // include the prefix(...) and suffix(...) binary data in the total contents
0 commit comments