diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-20 00:15:49 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-20 00:15:49 +0000 |
commit | 25d50758f3078f56677f50b8f789dff76c90ed4c (patch) | |
tree | 83f4c9111a856ddfe96a2de2d1c2418d8946f1a8 /clang/lib/Lex/PPMacroExpansion.cpp | |
parent | b5f4c32830f851c9211762b528dccdacfda5fd7a (diff) | |
download | bcm5719-llvm-25d50758f3078f56677f50b8f789dff76c90ed4c.tar.gz bcm5719-llvm-25d50758f3078f56677f50b8f789dff76c90ed4c.zip |
[modules] Add support for #include_next.
#include_next interacts poorly with modules: it depends on where in the list of
include paths the current file was found. Files covered by module maps are not
found in include search paths when building the module (and are not found in
include search paths when @importing the module either), so this isn't really
meaningful. Instead, we fake up the result that #include_next *should* have
given: find the first path that would have resulted in the given file being
picked, and search from there onwards.
llvm-svn: 220177
Diffstat (limited to 'clang/lib/Lex/PPMacroExpansion.cpp')
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index e875860f820..48e83ed12e8 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1053,7 +1053,8 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) { /// Returns true if successful. static bool EvaluateHasIncludeCommon(Token &Tok, IdentifierInfo *II, Preprocessor &PP, - const DirectoryLookup *LookupFrom) { + const DirectoryLookup *LookupFrom, + const FileEntry *LookupFromFile) { // Save the location of the current token. If a '(' is later found, use // that location. If not, use the end of this location instead. SourceLocation LParenLoc = Tok.getLocation(); @@ -1148,8 +1149,8 @@ static bool EvaluateHasIncludeCommon(Token &Tok, // Search include directories. const DirectoryLookup *CurDir; const FileEntry *File = - PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, CurDir, - nullptr, nullptr, nullptr); + PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile, + CurDir, nullptr, nullptr, nullptr); // Get the result value. A result of true means the file exists. return File != nullptr; @@ -1159,7 +1160,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok, /// Returns true if successful. static bool EvaluateHasInclude(Token &Tok, IdentifierInfo *II, Preprocessor &PP) { - return EvaluateHasIncludeCommon(Tok, II, PP, nullptr); + return EvaluateHasIncludeCommon(Tok, II, PP, nullptr, nullptr); } /// EvaluateHasIncludeNext - Process '__has_include_next("path")' expression. @@ -1169,10 +1170,19 @@ static bool EvaluateHasIncludeNext(Token &Tok, // __has_include_next is like __has_include, except that we start // searching after the current found directory. If we can't do this, // issue a diagnostic. + // FIXME: Factor out duplication wiht + // Preprocessor::HandleIncludeNextDirective. const DirectoryLookup *Lookup = PP.GetCurDirLookup(); + const FileEntry *LookupFromFile = nullptr; if (PP.isInPrimaryFile()) { Lookup = nullptr; PP.Diag(Tok, diag::pp_include_next_in_primary); + } else if (PP.getCurrentSubmodule()) { + // Start looking up in the directory *after* the one in which the current + // file would be found, if any. + assert(PP.getCurrentLexer() && "#include_next directive in macro?"); + LookupFromFile = PP.getCurrentLexer()->getFileEntry(); + Lookup = nullptr; } else if (!Lookup) { PP.Diag(Tok, diag::pp_include_next_absolute_path); } else { @@ -1180,7 +1190,7 @@ static bool EvaluateHasIncludeNext(Token &Tok, ++Lookup; } - return EvaluateHasIncludeCommon(Tok, II, PP, Lookup); + return EvaluateHasIncludeCommon(Tok, II, PP, Lookup, LookupFromFile); } /// \brief Process __building_module(identifier) expression. |