summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/PPMacroExpansion.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-10-20 00:15:49 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-10-20 00:15:49 +0000
commit25d50758f3078f56677f50b8f789dff76c90ed4c (patch)
tree83f4c9111a856ddfe96a2de2d1c2418d8946f1a8 /clang/lib/Lex/PPMacroExpansion.cpp
parentb5f4c32830f851c9211762b528dccdacfda5fd7a (diff)
downloadbcm5719-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.cpp20
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.
OpenPOWER on IntegriCloud