@@ -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}
@@ -1080,7 +1061,7 @@ struct Preprocessor::Private {
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
@@ -1106,7 +1087,7 @@ struct Preprocessor::Private {
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 }
@@ -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