@@ -642,27 +642,33 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
642
642
" #include: missing name of file to include" _err_en_US);
643
643
return ;
644
644
}
645
- std::string include;
646
645
std::optional<std::string> prependPath;
647
- if (dir.TokenAt (j).ToString () == " <" ) { // #include <foo>
648
- std::size_t k{j + 1 };
649
- if (k >= tokens) {
650
- prescanner.Say (dir.GetIntervalProvenanceRange (j, tokens - j),
646
+ TokenSequence path{dir, j, tokens - j};
647
+ std::string include{path.TokenAt (0 ).ToString ()};
648
+ if (include != " <" && include.substr (0 , 1 ) != " \" " &&
649
+ include.substr (0 , 1 ) != " '" ) {
650
+ path = ReplaceMacros (path, prescanner);
651
+ include = path.empty () ? " " s : path.TokenAt (0 ).ToString ();
652
+ }
653
+ auto pathTokens{path.SizeInTokens ()};
654
+ std::size_t k{0 };
655
+ if (include == " <" ) { // #include <foo>
656
+ k = 1 ;
657
+ if (k >= pathTokens) {
658
+ prescanner.Say (dir.GetIntervalProvenanceRange (j, pathTokens),
651
659
" #include: file name missing" _err_en_US);
652
660
return ;
653
661
}
654
- while (k < tokens && dir .TokenAt (k) != " >" ) {
662
+ while (k < pathTokens && path .TokenAt (k) != " >" ) {
655
663
++k;
656
664
}
657
- if (k >= tokens ) {
665
+ if (k >= pathTokens ) {
658
666
prescanner.Say (dir.GetIntervalProvenanceRange (j, tokens - j),
659
667
" #include: expected '>' at end of included file" _port_en_US);
660
668
}
661
- TokenSequence braced{dir, j + 1 , k - j - 1 };
669
+ TokenSequence braced{path, 1 , k - 1 };
662
670
include = braced.ToString ();
663
- j = k;
664
- } else if (((include = dir.TokenAt (j).ToString ()).substr (0 , 1 ) == " \" " ||
665
- include.substr (0 , 1 ) == " '" ) &&
671
+ } else if ((include.substr (0 , 1 ) == " \" " || include.substr (0 , 1 ) == " '" ) &&
666
672
include.substr (include.size () - 1 , 1 ) == include.substr (0 , 1 )) {
667
673
// #include "foo" and #include 'foo'
668
674
include = include.substr (1 , include.size () - 2 );
@@ -673,16 +679,17 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
673
679
}
674
680
} else {
675
681
prescanner.Say (dir.GetTokenProvenanceRange (j < tokens ? j : tokens - 1 ),
676
- " #include: expected name of file to include" _err_en_US);
682
+ " #include %s: expected name of file to include" _err_en_US,
683
+ path.ToString ());
677
684
return ;
678
685
}
679
686
if (include.empty ()) {
680
687
prescanner.Say (dir.GetTokenProvenanceRange (dirOffset),
681
- " #include: empty include file name" _err_en_US);
688
+ " #include %s : empty include file name" _err_en_US, path. ToString () );
682
689
return ;
683
690
}
684
- j = dir .SkipBlanks (j + 1 );
685
- if (j < tokens && dir .TokenAt (j ).ToString () != " !" ) {
691
+ k = path .SkipBlanks (k + 1 );
692
+ if (k < pathTokens && path .TokenAt (k ).ToString () != " !" ) {
686
693
prescanner.Say (dir.GetIntervalProvenanceRange (j, tokens - j),
687
694
" #include: extra stuff ignored after file name" _port_en_US);
688
695
}
@@ -691,8 +698,8 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
691
698
const SourceFile *included{
692
699
allSources_.Open (include, error, std::move (prependPath))};
693
700
if (!included) {
694
- prescanner.Say (dir.GetTokenProvenanceRange (dirOffset) ,
695
- " #include: %s " _err_en_US, error.str ());
701
+ prescanner.Say (dir.GetTokenProvenanceRange (j), " #include: %s " _err_en_US ,
702
+ error.str ());
696
703
} else if (included->bytes () > 0 ) {
697
704
ProvenanceRange fileRange{
698
705
allSources_.AddIncludedFile (*included, dir.GetProvenanceRange ())};
0 commit comments