@@ -219,26 +219,7 @@ class Hideset {
219219 std::set<std::string_view> names_;
220220};
221221
222- struct SystemInclude {
223- std::string fileName;
224-
225- SystemInclude () = default ;
226-
227- explicit SystemInclude (std::string fileName)
228- : fileName(std::move(fileName)) {}
229- };
230-
231- struct QuoteInclude {
232- std::string fileName;
233-
234- QuoteInclude () = default ;
235-
236- explicit QuoteInclude (std::string fileName) : fileName(std::move(fileName)) {}
237- };
238-
239- using Include = std::variant<SystemInclude, QuoteInclude>;
240-
241- inline auto getHeaderName (const Include &include) -> std::string {
222+ inline auto getHeaderName (const cxx::Include &include) -> std::string {
242223 return std::visit ([](const auto &include) { return include.fileName ; },
243224 include);
244225}
@@ -1053,7 +1034,7 @@ struct Preprocessor::Private {
10531034 Resolve (const Private *d, bool next) : d(d), wantNextInlude(next) {}
10541035
10551036 [[nodiscard]] auto search (auto view, const std::string &headerName)
1056- -> std::optional<fs::path > {
1037+ -> std::optional<std::string > {
10571038 auto transformToIncludePath = std::views::transform (
10581039 [&](const fs::path &path) { return path / headerName; });
10591040
@@ -1073,14 +1054,14 @@ struct Preprocessor::Private {
10731054 continue ;
10741055 }
10751056
1076- return path;
1057+ return path. string () ;
10771058 }
10781059
10791060 return std::nullopt ;
10801061 }
10811062
10821063 [[nodiscard]] auto operator ()(const QuoteInclude &include)
1083- -> std::optional<fs::path > {
1064+ -> std::optional<std::string > {
10841065 const auto &headerName = include.fileName ;
10851066
10861067 // search in the current path
@@ -1099,28 +1080,28 @@ struct Preprocessor::Private {
10991080 }
11001081
11011082 if (wantNextInlude && !didFindCurrentPath) {
1102- return firstMatch;
1083+ return firstMatch-> string () ;
11031084 }
11041085
11051086 return std::nullopt ;
11061087 }
11071088
11081089 [[nodiscard]] auto operator ()(const SystemInclude &include)
1109- -> std::optional<fs::path > {
1090+ -> std::optional<std::string > {
11101091 if (auto p = search (d->systemIncludePaths_ , include.fileName )) {
11111092 return p;
11121093 }
11131094
11141095 if (wantNextInlude && !didFindCurrentPath) {
1115- return firstMatch;
1096+ return firstMatch-> string () ;
11161097 }
11171098
11181099 return std::nullopt ;
11191100 }
11201101 };
11211102
11221103 [[nodiscard]] auto resolve (const Include &include, bool next) const
1123- -> std::optional<fs::path > {
1104+ -> std::optional<std::string > {
11241105 if (!canResolveFiles_) return std::nullopt ;
11251106
11261107 return std::visit (Resolve{this , next}, include);
@@ -1192,8 +1173,11 @@ struct Preprocessor::Private {
11921173 [[nodiscard]] auto parseIncludeDirective (TokList *directive, TokList *ts)
11931174 -> std::optional<ParsedIncludeDirective>;
11941175
1195- [[nodiscard]] auto resolveIncludeDirective (
1196- const ParsedIncludeDirective &directive) -> SourceFile *;
1176+ [[nodiscard]] auto findOrCreateSourceFile (const Include &include,
1177+ bool isIncludeNext) -> SourceFile *;
1178+
1179+ [[nodiscard]] auto findOrCreateSourceFile (const std::string &fileName)
1180+ -> SourceFile *;
11971181
11981182 [[nodiscard]] auto parseHeaderName (TokList *ts)
11991183 -> std::tuple<TokList *, std::optional<Include>>;
@@ -1691,9 +1675,7 @@ auto Preprocessor::Private::expand(
16911675 if (auto parsedInclude = parseDirective (source, start.toTokList ())) {
16921676 NeedToResolveInclude status{
16931677 .preprocessor = *preprocessor_,
1694- .fileName = getHeaderName (parsedInclude->header ),
1695- .isQuoted =
1696- std::holds_alternative<QuoteInclude>(parsedInclude->header ),
1678+ .include = parsedInclude->header ,
16971679 .isIncludeNext = parsedInclude->includeNext ,
16981680 .loc = parsedInclude->loc ,
16991681 };
@@ -1946,31 +1928,33 @@ auto Preprocessor::Private::parseIncludeDirective(TokList *directive,
19461928 return std::nullopt ;
19471929}
19481930
1949- auto Preprocessor::Private::resolveIncludeDirective (
1950- const ParsedIncludeDirective &directive) -> SourceFile * {
1951- const auto path = resolve (directive.header , directive.includeNext );
1952-
1953- if (!path) {
1954- const auto file = getHeaderName (directive.header );
1955- error (directive.loc , std::format (" file '{}' not found" , file));
1956- return nullptr ;
1931+ auto Preprocessor::Private::findOrCreateSourceFile (const Include &include,
1932+ bool isIncludeNext)
1933+ -> SourceFile * {
1934+ if (auto path = resolve (include, isIncludeNext)) {
1935+ auto sourceFile = findOrCreateSourceFile (path.value ());
1936+ return sourceFile;
19571937 }
19581938
1959- std::string currentFileName = path->string ();
1939+ return nullptr ;
1940+ }
19601941
1961- if (auto it = ifndefProtectedFiles_.find (currentFileName);
1942+ auto Preprocessor::Private::findOrCreateSourceFile (const std::string &fileName)
1943+ -> SourceFile * {
1944+ if (auto it = ifndefProtectedFiles_.find (fileName);
19621945 it != ifndefProtectedFiles_.end () && macros_.contains (it->second )) {
19631946 return nullptr ;
19641947 }
19651948
1966- auto sourceFile = findSourceFile (currentFileName );
1949+ auto sourceFile = findSourceFile (fileName );
19671950
19681951 if (sourceFile && sourceFile->pragmaOnceProtected ) {
1952+ // nothing to do
19691953 return nullptr ;
19701954 }
19711955
19721956 if (!sourceFile) {
1973- sourceFile = createSourceFile (path-> string () , readFile (*path ));
1957+ sourceFile = createSourceFile (fileName , readFile (fileName ));
19741958
19751959 sourceFile->pragmaOnceProtected =
19761960 checkPragmaOnceProtected (sourceFile->tokens );
@@ -1986,7 +1970,7 @@ auto Preprocessor::Private::resolveIncludeDirective(
19861970 }
19871971
19881972 if (willIncludeHeader_) {
1989- willIncludeHeader_ (currentFileName , includeDepth_ + 1 );
1973+ willIncludeHeader_ (fileName , includeDepth_ + 1 );
19901974 }
19911975
19921976 return sourceFile;
@@ -2879,34 +2863,19 @@ void Preprocessor::preprocess(std::string source, std::string fileName,
28792863 }
28802864
28812865 void operator ()(const NeedToResolveInclude &status) {
2882- // the header file resolution may be asynchronous
2883- Include header;
2866+ auto d = self.d .get ();
28842867
2885- if (status. isQuoted ) {
2886- header = QuoteInclude (status.fileName );
2887- } else {
2888- header = SystemInclude (status. fileName ) ;
2868+ if (auto resolvedInclude =
2869+ d-> resolve (status.include , status. isIncludeNext )) {
2870+ status. continueWith (resolvedInclude. value ());
2871+ return ;
28892872 }
28902873
2891- Private::ParsedIncludeDirective parsedInclude{
2892- .header = header,
2893- .includeNext = status.isIncludeNext ,
2894- .loc = static_cast <TokList *>(const_cast <void *>(status.loc )),
2895- };
2896-
2897- auto continuation = self.d ->resolveIncludeDirective (parsedInclude);
2898- if (!continuation) return ;
2874+ auto loc = static_cast <TokList *>(status.loc );
28992875
2900- // make the continuation the current file
2901- fs::path dirpath = fs::path (continuation->fileName );
2902- dirpath.remove_filename ();
2876+ const auto file = getHeaderName (status.include );
29032877
2904- self.d ->buffers_ .push_back (Private::Buffer{
2905- .source = continuation,
2906- .currentPath = dirpath,
2907- .ts = continuation->tokens ,
2908- .includeDepth = self.d ->includeDepth_ + 1 ,
2909- });
2878+ d->error (loc, std::format (" file '{}' not found" , file));
29102879 }
29112880
29122881 void operator ()(const NeedToKnowIfFileExists &status) {
@@ -2929,6 +2898,25 @@ void Preprocessor::preprocess(std::string source, std::string fileName,
29292898 endPreprocessing (tokens);
29302899}
29312900
2901+ void Preprocessor::NeedToResolveInclude::continueWith (
2902+ std::string fileName) const {
2903+ auto d = preprocessor.d .get ();
2904+
2905+ auto continuation = d->findOrCreateSourceFile (fileName);
2906+ if (!continuation) return ;
2907+
2908+ // make the continuation the current file
2909+ fs::path dirpath = fs::path (continuation->fileName );
2910+ dirpath.remove_filename ();
2911+
2912+ d->buffers_ .push_back (Private::Buffer{
2913+ .source = continuation,
2914+ .currentPath = dirpath,
2915+ .ts = continuation->tokens ,
2916+ .includeDepth = d->includeDepth_ + 1 ,
2917+ });
2918+ }
2919+
29322920void Preprocessor::NeedToKnowIfFileExists::setFileExists (bool exists) const {}
29332921
29342922void Preprocessor::NeedToReadFile::setContents (std::string contents) const {}
@@ -3165,4 +3153,9 @@ auto Preprocessor::getTokenText(const Token &token) const -> std::string_view {
31653153 return source.substr (token.offset (), token.length ());
31663154}
31673155
3156+ auto Preprocessor::resolve (const Include &include, bool isIncludeNext) const
3157+ -> std::optional<std::string> {
3158+ return d->resolve (include, isIncludeNext);
3159+ }
3160+
31683161} // namespace cxx
0 commit comments