summaryrefslogtreecommitdiffstats
path: root/lib/Lex
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2017-03-17 21:56:06 +0000
committerEric Christopher <echristo@gmail.com>2017-03-17 21:56:06 +0000
commitcd1b175aa96d9d675c09fc54dfd96ba41e3f2279 (patch)
treec5afffa40132841f21991cc97e1ddca43b73ce01 /lib/Lex
parent36ea15616c2f6c425e2716bdb2f709323de33131 (diff)
parent7ff3eba83e0e1e0a9cb30d84974d5e1066fd5f39 (diff)
Updating branches/google/testing to r297704
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/testing@298143 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/HeaderSearch.cpp90
-rw-r--r--lib/Lex/Lexer.cpp6
-rw-r--r--lib/Lex/LiteralSupport.cpp9
-rw-r--r--lib/Lex/ModuleMap.cpp70
-rw-r--r--lib/Lex/PPCaching.cpp30
-rw-r--r--lib/Lex/PPDirectives.cpp29
-rw-r--r--lib/Lex/PPMacroExpansion.cpp30
-rw-r--r--lib/Lex/Pragma.cpp11
-rw-r--r--lib/Lex/Preprocessor.cpp2
9 files changed, 244 insertions, 33 deletions
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 0aef7ff5c4..4ee3871928 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -54,7 +54,7 @@ HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
ExternalHeaderFileInfoSource::~ExternalHeaderFileInfoSource() {}
-HeaderSearch::HeaderSearch(IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts,
+HeaderSearch::HeaderSearch(std::shared_ptr<HeaderSearchOptions> HSOpts,
SourceManager &SourceMgr, DiagnosticsEngine &Diags,
const LangOptions &LangOpts,
const TargetInfo *Target)
@@ -121,6 +121,13 @@ const HeaderMap *HeaderSearch::CreateHeaderMap(const FileEntry *FE) {
return nullptr;
}
+/// \brief Get filenames for all registered header maps.
+void HeaderSearch::getHeaderMapFileNames(
+ SmallVectorImpl<std::string> &Names) const {
+ for (auto &HM : HeaderMaps)
+ Names.push_back(HM.first->getName());
+}
+
std::string HeaderSearch::getModuleFileName(Module *Module) {
const FileEntry *ModuleMap =
getModuleMap().getModuleMapFileForUniquing(Module);
@@ -165,8 +172,10 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
//
// To avoid false-negatives, we form as canonical a path as we can, and map
// to lower-case in case we're on a case-insensitive file system.
- auto *Dir =
- FileMgr.getDirectory(llvm::sys::path::parent_path(ModuleMapPath));
+ std::string Parent = llvm::sys::path::parent_path(ModuleMapPath);
+ if (Parent.empty())
+ Parent = ".";
+ auto *Dir = FileMgr.getDirectory(Parent);
if (!Dir)
return std::string();
auto DirName = FileMgr.getCanonicalName(Dir);
@@ -187,16 +196,36 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
Module *Module = ModMap.findModule(ModuleName);
if (Module || !AllowSearch || !HSOpts->ImplicitModuleMaps)
return Module;
-
+
+ StringRef SearchName = ModuleName;
+ Module = lookupModule(ModuleName, SearchName);
+
+ // The facility for "private modules" -- adjacent, optional module maps named
+ // module.private.modulemap that are supposed to define private submodules --
+ // is sometimes misused by frameworks that name their associated private
+ // module FooPrivate, rather than as a submodule named Foo.Private as
+ // intended. Here we compensate for such cases by looking in directories named
+ // Foo.framework, when we previously looked and failed to find a
+ // FooPrivate.framework.
+ if (!Module && SearchName.consume_back("Private"))
+ Module = lookupModule(ModuleName, SearchName);
+ return Module;
+}
+
+Module *HeaderSearch::lookupModule(StringRef ModuleName, StringRef SearchName) {
+ Module *Module = nullptr;
+
// Look through the various header search paths to load any available module
// maps, searching for a module map that describes this module.
for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
if (SearchDirs[Idx].isFramework()) {
- // Search for or infer a module map for a framework.
+ // Search for or infer a module map for a framework. Here we use
+ // SearchName rather than ModuleName, to permit finding private modules
+ // named FooPrivate in buggy frameworks named Foo.
SmallString<128> FrameworkDirName;
FrameworkDirName += SearchDirs[Idx].getFrameworkDir()->getName();
- llvm::sys::path::append(FrameworkDirName, ModuleName + ".framework");
- if (const DirectoryEntry *FrameworkDir
+ llvm::sys::path::append(FrameworkDirName, SearchName + ".framework");
+ if (const DirectoryEntry *FrameworkDir
= FileMgr.getDirectory(FrameworkDirName)) {
bool IsSystem
= SearchDirs[Idx].getDirCharacteristic() != SrcMgr::C_User;
@@ -1065,13 +1094,51 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
}
bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
- const FileEntry *File,
- bool isImport, Module *M) {
+ const FileEntry *File, bool isImport,
+ bool ModulesEnabled, Module *M) {
++NumIncluded; // Count # of attempted #includes.
// Get information about this file.
HeaderFileInfo &FileInfo = getFileInfo(File);
+ // FIXME: this is a workaround for the lack of proper modules-aware support
+ // for #import / #pragma once
+ auto TryEnterImported = [&](void) -> bool {
+ if (!ModulesEnabled)
+ return false;
+ // Modules with builtins are special; multiple modules use builtins as
+ // modular headers, example:
+ //
+ // module stddef { header "stddef.h" export * }
+ //
+ // After module map parsing, this expands to:
+ //
+ // module stddef {
+ // header "/path_to_builtin_dirs/stddef.h"
+ // textual "stddef.h"
+ // }
+ //
+ // It's common that libc++ and system modules will both define such
+ // submodules. Make sure cached results for a builtin header won't
+ // prevent other builtin modules to potentially enter the builtin header.
+ // Note that builtins are header guarded and the decision to actually
+ // enter them is postponed to the controlling macros logic below.
+ bool TryEnterHdr = false;
+ if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
+ TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
+ ModuleMap::isBuiltinHeader(
+ llvm::sys::path::filename(File->getName()));
+
+ // Textual headers can be #imported from different modules. Since ObjC
+ // headers find in the wild might rely only on #import and do not contain
+ // controlling macros, be conservative and only try to enter textual headers
+ // if such macro is present.
+ if (!FileInfo.isModuleHeader &&
+ FileInfo.getControllingMacro(ExternalLookup))
+ TryEnterHdr = true;
+ return TryEnterHdr;
+ };
+
// If this is a #import directive, check that we have not already imported
// this header.
if (isImport) {
@@ -1079,11 +1146,12 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
FileInfo.isImport = true;
// Has this already been #import'ed or #include'd?
- if (FileInfo.NumIncludes) return false;
+ if (FileInfo.NumIncludes && !TryEnterImported())
+ return false;
} else {
// Otherwise, if this is a #include of a file that was previously #import'd
// or if this is the second #include of a #pragma once file, ignore it.
- if (FileInfo.isImport)
+ if (FileInfo.isImport && !TryEnterImported())
return false;
}
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 37c7aa4c57..6025a66751 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1713,9 +1713,9 @@ const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr,
getLangOpts());
if (!isIdentifierBody(Next)) {
// End of suffix. Check whether this is on the whitelist.
- IsUDSuffix = (Chars == 1 && Buffer[0] == 's') ||
- NumericLiteralParser::isValidUDSuffix(
- getLangOpts(), StringRef(Buffer, Chars));
+ const StringRef CompleteSuffix(Buffer, Chars);
+ IsUDSuffix = StringLiteralParser::isValidUDSuffix(getLangOpts(),
+ CompleteSuffix);
break;
}
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 582ed3ff47..fbfd3fe5cc 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -1708,3 +1708,12 @@ unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
return SpellingPtr-SpellingStart;
}
+
+/// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved
+/// suffixes as ud-suffixes, because the diagnostic experience is better if we
+/// treat it as an invalid suffix.
+bool StringLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
+ StringRef Suffix) {
+ return NumericLiteralParser::isValidUDSuffix(LangOpts, Suffix) ||
+ Suffix == "sv";
+}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index c1b7b33c31..384e5707dc 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -91,6 +91,7 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
SourceModule(nullptr), NumCreatedModules(0) {
MMapLangOpts.LineComment = true;
+ MMapLangOpts.ModularCodegen = LangOpts.ModularCodegen;
}
ModuleMap::~ModuleMap() {
@@ -144,7 +145,7 @@ static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
/// \brief Determine whether the given file name is the name of a builtin
/// header, supplied by Clang to replace, override, or augment existing system
/// headers.
-static bool isBuiltinHeader(StringRef FileName) {
+bool ModuleMap::isBuiltinHeader(StringRef FileName) {
return llvm::StringSwitch<bool>(FileName)
.Case("float.h", true)
.Case("iso646.h", true)
@@ -165,7 +166,7 @@ ModuleMap::findKnownHeader(const FileEntry *File) {
HeadersMap::iterator Known = Headers.find(File);
if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
- isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+ ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
HeaderInfo.loadTopLevelSystemModules();
return Headers.find(File);
}
@@ -446,9 +447,19 @@ ModuleMap::isHeaderUnavailableInModule(const FileEntry *Header,
I = Known->second.begin(),
E = Known->second.end();
I != E; ++I) {
- if (I->isAvailable() && (!RequestingModule ||
- I->getModule()->isSubModuleOf(RequestingModule)))
+
+ if (I->isAvailable() &&
+ (!RequestingModule ||
+ I->getModule()->isSubModuleOf(RequestingModule))) {
+ // When no requesting module is available, the caller is looking if a
+ // header is part a module by only looking into the module map. This is
+ // done by warn_uncovered_module_header checks; don't consider textual
+ // headers part of it in this mode, otherwise we get misleading warnings
+ // that a umbrella header is not including a textual header.
+ if (!RequestingModule && I->getRole() == ModuleMap::TextualHeader)
+ continue;
return false;
+ }
}
return true;
}
@@ -544,16 +555,17 @@ Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{
return Context->findSubmodule(Name);
}
-std::pair<Module *, bool>
-ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
- bool IsExplicit) {
+std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name,
+ Module *Parent,
+ bool IsFramework,
+ bool IsExplicit) {
// Try to find an existing module with this name.
if (Module *Sub = lookupModuleQualified(Name, Parent))
return std::make_pair(Sub, false);
// Create a new module with this name.
- Module *Result = new Module(Name, SourceLocation(), Parent,
- IsFramework, IsExplicit, NumCreatedModules++);
+ Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,
+ IsExplicit, NumCreatedModules++);
if (!Parent) {
if (LangOpts.CurrentModule == Name)
SourceModule = Result;
@@ -827,7 +839,7 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
return;
HeaderList.push_back(KH);
- Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
+ Mod->Headers[headerRoleToKind(Role)].push_back(Header);
bool isCompilingModuleHeader =
LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
@@ -1490,6 +1502,42 @@ void ModuleMapParser::parseModuleDecl() {
ActiveModule->NoUndeclaredIncludes = true;
ActiveModule->Directory = Directory;
+ if (!ActiveModule->Parent) {
+ StringRef MapFileName(ModuleMapFile->getName());
+ if (MapFileName.endswith("module.private.modulemap") ||
+ MapFileName.endswith("module_private.map")) {
+ // Adding a top-level module from a private modulemap is likely a
+ // user error; we check to see if there's another top-level module
+ // defined in the non-private map in the same dir, and if so emit a
+ // warning.
+ for (auto E = Map.module_begin(); E != Map.module_end(); ++E) {
+ auto const *M = E->getValue();
+ if (!M->Parent &&
+ M->Directory == ActiveModule->Directory &&
+ M->Name != ActiveModule->Name) {
+ Diags.Report(ActiveModule->DefinitionLoc,
+ diag::warn_mmap_mismatched_top_level_private)
+ << ActiveModule->Name << M->Name;
+ // The pattern we're defending against here is typically due to
+ // a module named FooPrivate which is supposed to be a submodule
+ // called Foo.Private. Emit a fixit in that case.
+ auto D =
+ Diags.Report(ActiveModule->DefinitionLoc,
+ diag::note_mmap_rename_top_level_private_as_submodule);
+ D << ActiveModule->Name << M->Name;
+ StringRef Bad(ActiveModule->Name);
+ if (Bad.consume_back("Private")) {
+ SmallString<128> Fixed = Bad;
+ Fixed.append(".Private");
+ D << FixItHint::CreateReplacement(ActiveModule->DefinitionLoc,
+ Fixed);
+ }
+ break;
+ }
+ }
+ }
+ }
+
bool Done = false;
do {
switch (Tok.Kind) {
@@ -1843,7 +1891,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// supplied by Clang. Find that builtin header.
if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
- isBuiltinHeader(Header.FileName)) {
+ ModuleMap::isBuiltinHeader(Header.FileName)) {
SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
llvm::sys::path::append(BuiltinPathName, Header.FileName);
BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 45bdce3206..f5e8cdc25d 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -35,6 +35,29 @@ void Preprocessor::CommitBacktrackedTokens() {
BacktrackPositions.pop_back();
}
+Preprocessor::CachedTokensRange Preprocessor::LastCachedTokenRange() {
+ assert(isBacktrackEnabled());
+ auto PrevCachedLexPos = BacktrackPositions.back();
+ return CachedTokensRange{PrevCachedLexPos, CachedLexPos};
+}
+
+void Preprocessor::EraseCachedTokens(CachedTokensRange TokenRange) {
+ assert(TokenRange.Begin <= TokenRange.End);
+ if (CachedLexPos == TokenRange.Begin && TokenRange.Begin != TokenRange.End) {
+ // We have backtracked to the start of the token range as we want to consume
+ // them again. Erase the tokens only after consuming then.
+ assert(!CachedTokenRangeToErase);
+ CachedTokenRangeToErase = TokenRange;
+ return;
+ }
+ // The cached tokens were committed, so they should be erased now.
+ assert(TokenRange.End == CachedLexPos);
+ CachedTokens.erase(CachedTokens.begin() + TokenRange.Begin,
+ CachedTokens.begin() + TokenRange.End);
+ CachedLexPos = TokenRange.Begin;
+ ExitCachingLexMode();
+}
+
// Make Preprocessor re-lex the tokens that were lexed since
// EnableBacktrackAtThisPos() was previously called.
void Preprocessor::Backtrack() {
@@ -51,6 +74,13 @@ void Preprocessor::CachingLex(Token &Result) {
if (CachedLexPos < CachedTokens.size()) {
Result = CachedTokens[CachedLexPos++];
+ // Erase the some of the cached tokens after they are consumed when
+ // asked to do so.
+ if (CachedTokenRangeToErase &&
+ CachedTokenRangeToErase->End == CachedLexPos) {
+ EraseCachedTokens(*CachedTokenRangeToErase);
+ CachedTokenRangeToErase = None;
+ }
return;
}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 85504de3d1..8a56ddf236 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1976,30 +1976,36 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
SmallString<128> Path;
Path.reserve(Name.size()+2);
Path.push_back(isAngled ? '<' : '"');
+ bool isLeadingSeparator = llvm::sys::path::is_absolute(Name);
for (auto Component : Components) {
- Path.append(Component);
+ if (isLeadingSeparator)
+ isLeadingSeparator = false;
+ else
+ Path.append(Component);
// Append the separator the user used, or the close quote
Path.push_back(
Path.size() <= Filename.size() ? Filename[Path.size()-1] :
(isAngled ? '>' : '"'));
}
- auto Replacement = Path.str().str();
// For user files and known standard headers, by default we issue a diagnostic.
// For other system headers, we don't. They can be controlled separately.
auto DiagId = (FileCharacter == SrcMgr::C_User || warnByDefaultOnWrongCase(Name)) ?
diag::pp_nonportable_path : diag::pp_nonportable_system_path;
SourceRange Range(FilenameTok.getLocation(), CharEnd);
- Diag(FilenameTok, DiagId) << Replacement <<
- FixItHint::CreateReplacement(Range, Replacement);
+ Diag(FilenameTok, DiagId) << Path <<
+ FixItHint::CreateReplacement(Range, Path);
}
}
// Ask HeaderInfo if we should enter this #include file. If not, #including
// this file will have no effect.
+ bool SkipHeader = false;
if (ShouldEnter &&
!HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
+ getLangOpts().Modules,
SuggestedModule.getModule())) {
ShouldEnter = false;
+ SkipHeader = true;
if (Callbacks)
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
}
@@ -2008,6 +2014,14 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
if (!ShouldEnter) {
// If this is a module import, make it visible if needed.
if (auto *M = SuggestedModule.getModule()) {
+ // When building a pch, -fmodule-name tells the compiler to textually
+ // include headers in the specified module. But it is possible that
+ // ShouldEnter is false because we are skipping the header. In that
+ // case, We are not importing the specified module.
+ if (SkipHeader && getLangOpts().CompilingPCH &&
+ M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ return;
+
makeModuleVisible(M, HashLoc);
if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
@@ -2032,6 +2046,13 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// Determine if we're switching to building a new submodule, and which one.
if (auto *M = SuggestedModule.getModule()) {
+ // When building a pch, -fmodule-name tells the compiler to textually
+ // include headers in the specified module. We are not building the
+ // specified module.
+ if (getLangOpts().CompilingPCH &&
+ M->getTopLevelModuleName() == getLangOpts().CurrentModule)
+ return;
+
assert(!CurSubmodule && "should not have marked this as a module yet");
CurSubmodule = M;
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index f3a57e3348..de166c75e2 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -92,12 +92,35 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
}
void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
+ MacroDirective *ED,
MacroDirective *MD) {
+ // Normally, when a macro is defined, it goes through appendMacroDirective()
+ // above, which chains a macro to previous defines, undefs, etc.
+ // However, in a pch, the whole macro history up to the end of the pch is
+ // stored, so ASTReader goes through this function instead.
+ // However, built-in macros are already registered in the Preprocessor
+ // ctor, and ASTWriter stops writing the macro chain at built-in macros,
+ // so in that case the chain from the pch needs to be spliced to the existing
+ // built-in.
+
assert(II && MD);
MacroState &StoredMD = CurSubmoduleState->Macros[II];
- assert(!StoredMD.getLatest() &&
- "the macro history was modified before initializing it from a pch");
- StoredMD = MD;
+
+ if (auto *OldMD = StoredMD.getLatest()) {
+ // shouldIgnoreMacro() in ASTWriter also stops at macros from the
+ // predefines buffer in module builds. However, in module builds, modules
+ // are loaded completely before predefines are processed, so StoredMD
+ // will be nullptr for them when they're loaded. StoredMD should only be
+ // non-nullptr for builtins read from a pch file.
+ assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
+ "only built-ins should have an entry here");
+ assert(!OldMD->getPrevious() && "builtin should only have a single entry");
+ ED->setPrevious(OldMD);
+ StoredMD.setLatest(MD);
+ } else {
+ StoredMD = MD;
+ }
+
// Setup the identifier as having associated macro history.
II->setHasMacroDefinition(true);
if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
@@ -1160,6 +1183,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_attributes", LangOpts.CPlusPlus11)
.Case("cxx_auto_type", LangOpts.CPlusPlus11)
.Case("cxx_constexpr", LangOpts.CPlusPlus11)
+ .Case("cxx_constexpr_string_builtins", LangOpts.CPlusPlus11)
.Case("cxx_decltype", LangOpts.CPlusPlus11)
.Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
.Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 100da51414..f81eaa31e9 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -160,12 +160,23 @@ public:
~LexingFor_PragmaRAII() {
if (InMacroArgPreExpansion) {
+ // When committing/backtracking the cached pragma tokens in a macro
+ // argument pre-expansion we want to ensure that either the tokens which
+ // have been committed will be removed from the cache or that the tokens
+ // over which we just backtracked won't remain in the cache after they're
+ // consumed and that the caching will stop after consuming them.
+ // Otherwise the caching will interfere with the way macro expansion
+ // works, because we will continue to cache tokens after consuming the
+ // backtracked tokens, which shouldn't happen when we're dealing with
+ // macro argument pre-expansion.
+ auto CachedTokenRange = PP.LastCachedTokenRange();
if (Failed) {
PP.CommitBacktrackedTokens();
} else {
PP.Backtrack();
OutTok = PragmaTok;
}
+ PP.EraseCachedTokens(CachedTokenRange);
}
}
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 0f7473b8c1..91319bedd6 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -68,7 +68,7 @@ LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry)
//===----------------------------------------------------------------------===//
ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
-Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
+Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
SourceManager &SM, HeaderSearch &Headers,
ModuleLoader &TheModuleLoader,