summaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:18:08 +0000
commitbab175ec4b075c8076ba14c762900392533f6ee4 (patch)
tree01f4f29419a2cb10abe13c1e63cd2a66068b0137 /lib/Lex
parent8b7a8012d223fac5d17d16a66bb39168a9a1dfc0 (diff)
Notes
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/HeaderMap.cpp2
-rw-r--r--lib/Lex/HeaderSearch.cpp128
-rw-r--r--lib/Lex/Lexer.cpp82
-rw-r--r--lib/Lex/LiteralSupport.cpp52
-rw-r--r--lib/Lex/MacroInfo.cpp2
-rw-r--r--lib/Lex/ModuleMap.cpp119
-rw-r--r--lib/Lex/PPCaching.cpp4
-rw-r--r--lib/Lex/PPDirectives.cpp87
-rw-r--r--lib/Lex/PPExpressions.cpp17
-rw-r--r--lib/Lex/PPLexerChange.cpp16
-rw-r--r--lib/Lex/PPMacroExpansion.cpp95
-rw-r--r--lib/Lex/PTHLexer.cpp17
-rw-r--r--lib/Lex/Pragma.cpp66
-rw-r--r--lib/Lex/PreprocessingRecord.cpp15
-rw-r--r--lib/Lex/Preprocessor.cpp73
-rw-r--r--lib/Lex/TokenConcatenation.cpp2
-rw-r--r--lib/Lex/TokenLexer.cpp11
17 files changed, 550 insertions, 238 deletions
diff --git a/lib/Lex/HeaderMap.cpp b/lib/Lex/HeaderMap.cpp
index 4cace5b002450..24a14b6cdb573 100644
--- a/lib/Lex/HeaderMap.cpp
+++ b/lib/Lex/HeaderMap.cpp
@@ -106,7 +106,7 @@ bool HeaderMapImpl::checkHeader(const llvm::MemoryBuffer &File,
/// getFileName - Return the filename of the headermap.
-const char *HeaderMapImpl::getFileName() const {
+StringRef HeaderMapImpl::getFileName() const {
return FileBuffer->getBufferIdentifier();
}
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index e5cc30e41c573..b5228fc6c8cbd 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -26,7 +26,6 @@
#include "llvm/Support/Capacity.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <utility>
#if defined(LLVM_ON_UNIX)
@@ -37,9 +36,12 @@ using namespace clang;
const IdentifierInfo *
HeaderFileInfo::getControllingMacro(ExternalPreprocessorSource *External) {
if (ControllingMacro) {
- if (ControllingMacro->isOutOfDate())
+ if (ControllingMacro->isOutOfDate()) {
+ assert(External && "We must have an external source if we have a "
+ "controlling macro that is out of date.");
External->updateOutOfDateIdentifier(
*const_cast<IdentifierInfo *>(ControllingMacro));
+ }
return ControllingMacro;
}
@@ -119,14 +121,39 @@ 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);
- return getModuleFileName(Module->Name, ModuleMap->getName());
+ return getModuleFileName(Module->Name, ModuleMap->getName(),
+ /*UsePrebuiltPath*/false);
}
std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
- StringRef ModuleMapPath) {
+ StringRef ModuleMapPath,
+ bool UsePrebuiltPath) {
+ if (UsePrebuiltPath) {
+ if (HSOpts->PrebuiltModulePaths.empty())
+ return std::string();
+
+ // Go though each prebuilt module path and try to find the pcm file.
+ for (const std::string &Dir : HSOpts->PrebuiltModulePaths) {
+ SmallString<256> Result(Dir);
+ llvm::sys::fs::make_absolute(Result);
+
+ llvm::sys::path::append(Result, ModuleName + ".pcm");
+ if (getFileMgr().getFile(Result.str()))
+ return Result.str().str();
+ }
+ return std::string();
+ }
+
// If we don't have a module cache path or aren't supposed to use one, we
// can't do anything.
if (getModuleCachePath().empty())
@@ -167,16 +194,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;
@@ -240,7 +287,7 @@ Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) {
/// getName - Return the directory or filename corresponding to this lookup
/// object.
-const char *DirectoryLookup::getName() const {
+StringRef DirectoryLookup::getName() const {
if (isNormalDir())
return getDir()->getName();
if (isFramework())
@@ -396,6 +443,12 @@ getTopFrameworkDir(FileManager &FileMgr, StringRef DirName,
return TopFrameworkDir;
}
+static bool needModuleLookup(Module *RequestingModule,
+ bool HasSuggestedModule) {
+ return HasSuggestedModule ||
+ (RequestingModule && RequestingModule->NoUndeclaredIncludes);
+}
+
/// DoFrameworkLookup - Do a lookup of the specified file in the current
/// DirectoryLookup, which is a framework directory.
const FileEntry *DirectoryLookup::DoFrameworkLookup(
@@ -491,7 +544,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
}
// If we found the header and are allowed to suggest a module, do so now.
- if (FE && SuggestedModule) {
+ if (FE && needModuleLookup(RequestingModule, SuggestedModule)) {
// Find the framework in which this header occurs.
StringRef FrameworkPath = FE->getDir()->getName();
bool FoundFramework = false;
@@ -830,17 +883,19 @@ LookupSubframeworkHeader(StringRef Filename,
if (SlashPos == StringRef::npos) return nullptr;
// Look up the base framework name of the ContextFileEnt.
- const char *ContextName = ContextFileEnt->getName();
+ StringRef ContextName = ContextFileEnt->getName();
// If the context info wasn't a framework, couldn't be a subframework.
const unsigned DotFrameworkLen = 10;
- const char *FrameworkPos = strstr(ContextName, ".framework");
- if (FrameworkPos == nullptr ||
- (FrameworkPos[DotFrameworkLen] != '/' &&
- FrameworkPos[DotFrameworkLen] != '\\'))
+ auto FrameworkPos = ContextName.find(".framework");
+ if (FrameworkPos == StringRef::npos ||
+ (ContextName[FrameworkPos + DotFrameworkLen] != '/' &&
+ ContextName[FrameworkPos + DotFrameworkLen] != '\\'))
return nullptr;
- SmallString<1024> FrameworkName(ContextName, FrameworkPos+DotFrameworkLen+1);
+ SmallString<1024> FrameworkName(ContextName.data(), ContextName.data() +
+ FrameworkPos +
+ DotFrameworkLen + 1);
// Append Frameworks/HIToolbox.framework/
FrameworkName += "Frameworks/";
@@ -1139,22 +1194,45 @@ bool HeaderSearch::hasModuleMap(StringRef FileName,
}
ModuleMap::KnownHeader
-HeaderSearch::findModuleForHeader(const FileEntry *File) const {
+HeaderSearch::findModuleForHeader(const FileEntry *File,
+ bool AllowTextual) const {
if (ExternalSource) {
// Make sure the external source has handled header info about this file,
// which includes whether the file is part of a module.
(void)getExistingFileInfo(File);
}
- return ModMap.findModuleForHeader(File);
+ return ModMap.findModuleForHeader(File, AllowTextual);
+}
+
+static bool suggestModule(HeaderSearch &HS, const FileEntry *File,
+ Module *RequestingModule,
+ ModuleMap::KnownHeader *SuggestedModule) {
+ ModuleMap::KnownHeader Module =
+ HS.findModuleForHeader(File, /*AllowTextual*/true);
+ if (SuggestedModule)
+ *SuggestedModule = (Module.getRole() & ModuleMap::TextualHeader)
+ ? ModuleMap::KnownHeader()
+ : Module;
+
+ // If this module specifies [no_undeclared_includes], we cannot find any
+ // file that's in a non-dependency module.
+ if (RequestingModule && Module && RequestingModule->NoUndeclaredIncludes) {
+ HS.getModuleMap().resolveUses(RequestingModule, /*Complain*/false);
+ if (!RequestingModule->directlyUses(Module.getModule())) {
+ return false;
+ }
+ }
+
+ return true;
}
bool HeaderSearch::findUsableModuleForHeader(
const FileEntry *File, const DirectoryEntry *Root, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemHeaderDir) {
- if (File && SuggestedModule) {
+ if (File && needModuleLookup(RequestingModule, SuggestedModule)) {
// If there is a module that corresponds to this header, suggest it.
hasModuleMap(File->getName(), Root, IsSystemHeaderDir);
- *SuggestedModule = findModuleForHeader(File);
+ return suggestModule(*this, File, RequestingModule, SuggestedModule);
}
return true;
}
@@ -1163,7 +1241,7 @@ bool HeaderSearch::findUsableModuleForFrameworkHeader(
const FileEntry *File, StringRef FrameworkName, Module *RequestingModule,
ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework) {
// If we're supposed to suggest a module, look for one now.
- if (SuggestedModule) {
+ if (needModuleLookup(RequestingModule, SuggestedModule)) {
// Find the top-level framework based on this framework.
SmallVector<std::string, 4> SubmodulePath;
const DirectoryEntry *TopFrameworkDir
@@ -1180,7 +1258,7 @@ bool HeaderSearch::findUsableModuleForFrameworkHeader(
// important so that we're consistent about whether this header
// corresponds to a module. Possibly we should lock down framework modules
// so that this is not possible.
- *SuggestedModule = findModuleForHeader(File);
+ return suggestModule(*this, File, RequestingModule, SuggestedModule);
}
return true;
}
@@ -1432,7 +1510,7 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(const FileEntry *File,
// FIXME: We assume that the path name currently cached in the FileEntry is
// the most appropriate one for this analysis (and that it's spelled the same
// way as the corresponding header search path).
- const char *Name = File->getName();
+ StringRef Name = File->getName();
unsigned BestPrefixLength = 0;
unsigned BestSearchDir;
@@ -1442,7 +1520,7 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(const FileEntry *File,
if (!SearchDirs[I].isNormalDir())
continue;
- const char *Dir = SearchDirs[I].getDir()->getName();
+ StringRef Dir = SearchDirs[I].getDir()->getName();
for (auto NI = llvm::sys::path::begin(Name),
NE = llvm::sys::path::end(Name),
DI = llvm::sys::path::begin(Dir),
@@ -1475,5 +1553,5 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(const FileEntry *File,
if (IsSystem)
*IsSystem = BestPrefixLength ? BestSearchDir >= SystemDirIdx : false;
- return Name + BestPrefixLength;
+ return Name.drop_front(BestPrefixLength);
}
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 9c2a0163acead..6025a66751254 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -14,18 +14,27 @@
#include "clang/Lex/Lexer.h"
#include "UnicodeCharSets.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/UnicodeCharRanges.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <cstring>
+#include <string>
+#include <tuple>
+#include <utility>
+
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -45,7 +54,6 @@ tok::ObjCKeywordKind Token::getObjCKeywordID() const {
return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
}
-
//===----------------------------------------------------------------------===//
// Lexer Class Implementation
//===----------------------------------------------------------------------===//
@@ -196,7 +204,6 @@ Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc,
return L;
}
-
/// Stringify - Convert the specified string into a C string, with surrounding
/// ""'s, and with escaped \ and " characters.
std::string Lexer::Stringify(StringRef Str, bool Charify) {
@@ -398,7 +405,6 @@ unsigned Lexer::getSpelling(const Token &Tok, const char *&Buffer,
return getSpellingSlow(Tok, TokStart, LangOpts, const_cast<char*>(Buffer));
}
-
/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
/// includes a trigraph or an escaped newline) then this count includes bytes
@@ -526,13 +532,15 @@ SourceLocation Lexer::GetBeginningOfToken(SourceLocation Loc,
}
namespace {
+
enum PreambleDirectiveKind {
PDK_Skipped,
PDK_StartIf,
PDK_EndIf,
PDK_Unknown
};
-}
+
+} // end anonymous namespace
std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer,
const LangOptions &LangOpts,
@@ -694,7 +702,6 @@ std::pair<unsigned, bool> Lexer::ComputePreamble(StringRef Buffer,
: TheTok.isAtStartOfLine());
}
-
/// AdvanceToTokenCharacter - Given a location that specifies the start of a
/// token, return a new location that specifies a character within the token.
SourceLocation Lexer::AdvanceToTokenCharacter(SourceLocation TokStart,
@@ -961,7 +968,7 @@ StringRef Lexer::getImmediateMacroName(SourceLocation Loc,
assert(Loc.isMacroID() && "Only reasonble to call this on macros");
// Find the location of the immediate macro expansion.
- while (1) {
+ while (true) {
FileID FID = SM.getFileID(Loc);
const SrcMgr::SLocEntry *E = &SM.getSLocEntry(FID);
const SrcMgr::ExpansionInfo &Expansion = E->getExpansion();
@@ -1031,7 +1038,6 @@ bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) {
return isIdentifierBody(c, LangOpts.DollarIdents);
}
-
//===----------------------------------------------------------------------===//
// Diagnostics forwarding code.
//===----------------------------------------------------------------------===//
@@ -1157,7 +1163,7 @@ unsigned Lexer::getEscapedNewLineSize(const char *Ptr) {
/// them), skip over them and return the first non-escaped-newline found,
/// otherwise return P.
const char *Lexer::SkipEscapedNewLines(const char *P) {
- while (1) {
+ while (true) {
const char *AfterEscape;
if (*P == '\\') {
AfterEscape = P+1;
@@ -1310,7 +1316,6 @@ Slash:
return *Ptr;
}
-
/// getCharAndSizeSlowNoWarn - Handle the slow/uncommon case of the
/// getCharAndSizeNoWarn method. Here we know that we can accumulate into Size,
/// and that we have already incremented Ptr by Size bytes.
@@ -1480,13 +1485,13 @@ bool Lexer::tryConsumeIdentifierUCN(const char *&CurPtr, unsigned Size,
bool Lexer::tryConsumeIdentifierUTF8Char(const char *&CurPtr) {
const char *UnicodePtr = CurPtr;
- UTF32 CodePoint;
- ConversionResult Result =
- llvm::convertUTF8Sequence((const UTF8 **)&UnicodePtr,
- (const UTF8 *)BufferEnd,
+ llvm::UTF32 CodePoint;
+ llvm::ConversionResult Result =
+ llvm::convertUTF8Sequence((const llvm::UTF8 **)&UnicodePtr,
+ (const llvm::UTF8 *)BufferEnd,
&CodePoint,
- strictConversion);
- if (Result != conversionOK ||
+ llvm::strictConversion);
+ if (Result != llvm::conversionOK ||
!isAllowedIDChar(static_cast<uint32_t>(CodePoint), LangOpts))
return false;
@@ -1533,14 +1538,22 @@ FinishIdentifier:
// preprocessor, which may macro expand it or something.
if (II->isHandleIdentifierCase())
return PP->HandleIdentifier(Result);
-
+
+ if (II->getTokenID() == tok::identifier && isCodeCompletionPoint(CurPtr)
+ && II->getPPKeywordID() == tok::pp_not_keyword
+ && II->getObjCKeywordID() == tok::objc_not_keyword) {
+ // Return the code-completion token.
+ Result.setKind(tok::code_completion);
+ cutOffLexing();
+ return true;
+ }
return true;
}
// Otherwise, $,\,? in identifier found. Enter slower path.
C = getCharAndSize(CurPtr, Size);
- while (1) {
+ while (true) {
if (C == '$') {
// If we hit a $ and they are not supported in identifiers, we are done.
if (!LangOpts.DollarIdents) goto FinishIdentifier;
@@ -1700,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;
}
@@ -1829,7 +1842,7 @@ bool Lexer::LexRawStringLiteral(Token &Result, const char *CurPtr,
// Search for the next '"' in hopes of salvaging the lexer. Unfortunately,
// it's possible the '"' was intended to be part of the raw string, but
// there's not much we can do about that.
- while (1) {
+ while (true) {
char C = *CurPtr++;
if (C == '"')
@@ -1848,7 +1861,7 @@ bool Lexer::LexRawStringLiteral(Token &Result, const char *CurPtr,
const char *Prefix = CurPtr;
CurPtr += PrefixLen + 1; // skip over prefix and '('
- while (1) {
+ while (true) {
char C = *CurPtr++;
if (C == ')') {
@@ -1913,7 +1926,6 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
return true;
}
-
/// LexCharConstant - Lex the remainder of a character constant, after having
/// lexed either ' or L' or u8' or u' or U'.
bool Lexer::LexCharConstant(Token &Result, const char *CurPtr,
@@ -1992,7 +2004,7 @@ bool Lexer::SkipWhitespace(Token &Result, const char *CurPtr,
unsigned char Char = *CurPtr;
// Skip consecutive spaces efficiently.
- while (1) {
+ while (true) {
// Skip horizontal whitespace very aggressively.
while (isHorizontalWhitespace(Char))
Char = *++CurPtr;
@@ -2315,7 +2327,7 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr,
if (C == '/')
C = *CurPtr++;
- while (1) {
+ while (true) {
// Skip over all non-interesting characters until we find end of buffer or a
// (probably ending) '/' character.
if (CurPtr + 24 < BufferEnd &&
@@ -2456,7 +2468,7 @@ void Lexer::ReadToEndOfLine(SmallVectorImpl<char> *Result) {
// CurPtr - Cache BufferPtr in an automatic variable.
const char *CurPtr = BufferPtr;
- while (1) {
+ while (true) {
char Char = getAndAdvanceChar(CurPtr, Tmp);
switch (Char) {
default:
@@ -2669,7 +2681,6 @@ bool Lexer::IsStartOfConflictMarker(const char *CurPtr) {
return false;
}
-
/// HandleEndOfConflictMarker - If this is a '====' or '||||' or '>>>>', or if
/// it is '<<<<' and the conflict marker started with a '>>>>' marker, then it
/// is the end of a conflict marker. Handle it by ignoring up until the end of
@@ -3498,7 +3509,6 @@ LexNextToken:
CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
Kind = tok::greatergreater;
}
-
} else {
Kind = tok::greater;
}
@@ -3615,17 +3625,17 @@ LexNextToken:
break;
}
- UTF32 CodePoint;
+ llvm::UTF32 CodePoint;
// We can't just reset CurPtr to BufferPtr because BufferPtr may point to
// an escaped newline.
--CurPtr;
- ConversionResult Status =
- llvm::convertUTF8Sequence((const UTF8 **)&CurPtr,
- (const UTF8 *)BufferEnd,
+ llvm::ConversionResult Status =
+ llvm::convertUTF8Sequence((const llvm::UTF8 **)&CurPtr,
+ (const llvm::UTF8 *)BufferEnd,
&CodePoint,
- strictConversion);
- if (Status == conversionOK) {
+ llvm::strictConversion);
+ if (Status == llvm::conversionOK) {
if (CheckUnicodeWhitespace(Result, CodePoint, CurPtr)) {
if (SkipWhitespace(Result, CurPtr, TokAtPhysicalStartOfLine))
return true; // KeepWhitespaceMode
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index e68b82fb499af..fbfd3fe5cce0f 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -14,12 +14,25 @@
#include "clang/Lex/LiteralSupport.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
+#include <string>
using namespace clang;
@@ -134,7 +147,7 @@ static unsigned ProcessCharEscape(const char *ThisTokBegin,
if (Diags)
Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
diag::err_hex_escape_no_digits) << "x";
- HadError = 1;
+ HadError = true;
break;
}
@@ -389,7 +402,7 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
if (CharByteWidth == 4) {
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
- UTF32 *ResultPtr = reinterpret_cast<UTF32*>(ResultBuf);
+ llvm::UTF32 *ResultPtr = reinterpret_cast<llvm::UTF32*>(ResultBuf);
*ResultPtr = UcnVal;
ResultBuf += 4;
return;
@@ -398,7 +411,7 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
if (CharByteWidth == 2) {
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
- UTF16 *ResultPtr = reinterpret_cast<UTF16*>(ResultBuf);
+ llvm::UTF16 *ResultPtr = reinterpret_cast<llvm::UTF16*>(ResultBuf);
if (UcnVal <= (UTF32)0xFFFF) {
*ResultPtr = UcnVal;
@@ -452,7 +465,6 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
ResultBuf += bytesToWrite;
}
-
/// integer-constant: [C99 6.4.4.1]
/// decimal-constant integer-suffix
/// octal-constant integer-suffix
@@ -985,7 +997,6 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) {
return Result.convertFromString(Str, APFloat::rmNearestTiesToEven);
}
-
/// \verbatim
/// user-defined-character-literal: [C++11 lex.ext]
/// character-literal ud-suffix
@@ -1103,11 +1114,11 @@ CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
char const *tmp_in_start = start;
uint32_t *tmp_out_start = buffer_begin;
- ConversionResult res =
- ConvertUTF8toUTF32(reinterpret_cast<UTF8 const **>(&start),
- reinterpret_cast<UTF8 const *>(begin),
- &buffer_begin, buffer_end, strictConversion);
- if (res != conversionOK) {
+ llvm::ConversionResult res =
+ llvm::ConvertUTF8toUTF32(reinterpret_cast<llvm::UTF8 const **>(&start),
+ reinterpret_cast<llvm::UTF8 const *>(begin),
+ &buffer_begin, buffer_end, llvm::strictConversion);
+ if (res != llvm::conversionOK) {
// If we see bad encoding for unprefixed character literals, warn and
// simply copy the byte values, for compatibility with gcc and
// older versions of clang.
@@ -1499,13 +1510,13 @@ void StringLiteralParser::init(ArrayRef<Token> StringToks){
if (CharByteWidth == 4) {
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
- UTF32 *ResultWidePtr = reinterpret_cast<UTF32*>(ResultPtr);
+ llvm::UTF32 *ResultWidePtr = reinterpret_cast<llvm::UTF32*>(ResultPtr);
*ResultWidePtr = ResultChar;
ResultPtr += 4;
} else if (CharByteWidth == 2) {
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
- UTF16 *ResultWidePtr = reinterpret_cast<UTF16*>(ResultPtr);
+ llvm::UTF16 *ResultWidePtr = reinterpret_cast<llvm::UTF16*>(ResultPtr);
*ResultWidePtr = ResultChar & 0xFFFF;
ResultPtr += 2;
} else {
@@ -1520,12 +1531,12 @@ void StringLiteralParser::init(ArrayRef<Token> StringToks){
if (CharByteWidth == 4) {
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
- UTF32 *ResultWidePtr = reinterpret_cast<UTF32*>(ResultBuf.data());
+ llvm::UTF32 *ResultWidePtr = reinterpret_cast<llvm::UTF32*>(ResultBuf.data());
ResultWidePtr[0] = GetNumStringChars() - 1;
} else if (CharByteWidth == 2) {
// FIXME: Make the type of the result buffer correct instead of
// using reinterpret_cast.
- UTF16 *ResultWidePtr = reinterpret_cast<UTF16*>(ResultBuf.data());
+ llvm::UTF16 *ResultWidePtr = reinterpret_cast<llvm::UTF16*>(ResultBuf.data());
ResultWidePtr[0] = GetNumStringChars() - 1;
} else {
assert(CharByteWidth == 1 && "Unexpected char width");
@@ -1559,7 +1570,7 @@ void StringLiteralParser::init(ArrayRef<Token> StringToks){
static const char *resyncUTF8(const char *Err, const char *End) {
if (Err == End)
return End;
- End = Err + std::min<unsigned>(getNumBytesForUTF8(*Err), End-Err);
+ End = Err + std::min<unsigned>(llvm::getNumBytesForUTF8(*Err), End-Err);
while (++Err != End && (*Err & 0xC0) == 0x80)
;
return Err;
@@ -1571,7 +1582,7 @@ static const char *resyncUTF8(const char *Err, const char *End) {
bool StringLiteralParser::CopyStringFragment(const Token &Tok,
const char *TokBegin,
StringRef Fragment) {
- const UTF8 *ErrorPtrTmp;
+ const llvm::UTF8 *ErrorPtrTmp;
if (ConvertUTF8toWide(CharByteWidth, Fragment, ResultPtr, ErrorPtrTmp))
return false;
@@ -1697,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/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 2ef4387b99ba0..924613dcb8405 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -240,6 +240,6 @@ ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule,
ArrayRef<ModuleMacro *> Overrides) {
void *Mem = PP.getPreprocessorAllocator().Allocate(
sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
- llvm::alignOf<ModuleMacro>());
+ alignof(ModuleMacro));
return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 3e3215dee82a8..9d0f2eb2fa79f 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -297,11 +297,14 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (LangOpts.ModulesStrictDeclUse) {
Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
<< RequestingModule->getFullModuleName() << Filename;
- } else if (RequestingModule && RequestingModuleIsModuleInterface) {
+ } else if (RequestingModule && RequestingModuleIsModuleInterface &&
+ LangOpts.isCompilingModule()) {
+ // Do not diagnose when we are not compiling a module.
diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
diag::warn_non_modular_include_in_framework_module :
diag::warn_non_modular_include_in_module;
- Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName();
+ Diags.Report(FilenameLoc, DiagID) << RequestingModule->getFullModuleName()
+ << File->getName();
}
}
@@ -325,9 +328,10 @@ static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
return false;
}
-ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File) {
+ModuleMap::KnownHeader ModuleMap::findModuleForHeader(const FileEntry *File,
+ bool AllowTextual) {
auto MakeResult = [&](ModuleMap::KnownHeader R) -> ModuleMap::KnownHeader {
- if (R.getRole() & ModuleMap::TextualHeader)
+ if (!AllowTextual && R.getRole() & ModuleMap::TextualHeader)
return ModuleMap::KnownHeader();
return R;
};
@@ -558,6 +562,25 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
return std::make_pair(Result, true);
}
+Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
+ StringRef Name) {
+ assert(LangOpts.CurrentModule == Name && "module name mismatch");
+ assert(!Modules[Name] && "redefining existing module");
+
+ auto *Result =
+ new Module(Name, Loc, nullptr, /*IsFramework*/ false,
+ /*IsExplicit*/ false, NumCreatedModules++);
+ Modules[Name] = SourceModule = Result;
+
+ // Mark the main source file as being within the newly-created module so that
+ // declarations and macros are properly visibility-restricted to it.
+ auto *MainFile = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID());
+ assert(MainFile && "no input file for module interface");
+ Headers[MainFile].push_back(KnownHeader(Result, PrivateHeader));
+
+ return Result;
+}
+
/// \brief For a framework module, infer the framework against which we
/// should link.
static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
@@ -573,8 +596,7 @@ static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir,
// The library name of a framework has more than one possible extension since
// the introduction of the text-based dynamic library format. We need to check
// for both before we give up.
- static const char *frameworkExtensions[] = {"", ".tbd"};
- for (const auto *extension : frameworkExtensions) {
+ for (const char *extension : {"", ".tbd"}) {
llvm::sys::path::replace_extension(LibName, extension);
if (FileMgr.getFile(LibName)) {
Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name,
@@ -653,6 +675,8 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Attrs.IsSystem |= inferred->second.Attrs.IsSystem;
Attrs.IsExternC |= inferred->second.Attrs.IsExternC;
Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
+ Attrs.NoUndeclaredIncludes |=
+ inferred->second.Attrs.NoUndeclaredIncludes;
ModuleMapFile = inferred->second.ModuleMapFile;
}
}
@@ -690,6 +714,7 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir,
Result->IsSystem |= Attrs.IsSystem;
Result->IsExternC |= Attrs.IsExternC;
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
+ Result->NoUndeclaredIncludes |= Attrs.NoUndeclaredIncludes;
Result->Directory = FrameworkDir;
// umbrella header "umbrella-header-name"
@@ -802,10 +827,10 @@ 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.CompilingModule && Mod->getTopLevelModule() == SourceModule;
+ LangOpts.isCompilingModule() && Mod->getTopLevelModule() == SourceModule;
if (!Imported || isCompilingModuleHeader) {
// When we import HeaderFileInfo, the external source is expected to
// set the isModuleHeader flag itself.
@@ -1288,7 +1313,9 @@ namespace {
/// \brief The 'extern_c' attribute.
AT_extern_c,
/// \brief The 'exhaustive' attribute.
- AT_exhaustive
+ AT_exhaustive,
+ /// \brief The 'no_undeclared_includes' attribute.
+ AT_no_undeclared_includes
};
}
@@ -1458,8 +1485,47 @@ void ModuleMapParser::parseModuleDecl() {
ActiveModule->IsSystem = true;
if (Attrs.IsExternC)
ActiveModule->IsExternC = true;
+ if (Attrs.NoUndeclaredIncludes ||
+ (!ActiveModule->Parent && ModuleName == "Darwin"))
+ 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) {
@@ -1624,15 +1690,12 @@ void ModuleMapParser::parseExternModuleDecl() {
/// was never correct and causes issues now that we check it, so drop it.
static bool shouldAddRequirement(Module *M, StringRef Feature,
bool &IsRequiresExcludedHack) {
- static const StringRef DarwinCExcluded[] = {"Darwin", "C", "excluded"};
- static const StringRef TclPrivate[] = {"Tcl", "Private"};
- static const StringRef IOKitAVC[] = {"IOKit", "avc"};
-
- if (Feature == "excluded" && (M->fullModuleNameIs(DarwinCExcluded) ||
- M->fullModuleNameIs(TclPrivate))) {
+ if (Feature == "excluded" &&
+ (M->fullModuleNameIs({"Darwin", "C", "excluded"}) ||
+ M->fullModuleNameIs({"Tcl", "Private"}))) {
IsRequiresExcludedHack = true;
return false;
- } else if (Feature == "cplusplus" && M->fullModuleNameIs(IOKitAVC)) {
+ } else if (Feature == "cplusplus" && M->fullModuleNameIs({"IOKit", "avc"})) {
return false;
}
@@ -1824,13 +1887,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// If Clang supplies this header but the underlying system does not,
// just silently swap in our builtin version. Otherwise, we'll end
// up adding both (later).
- //
- // For local visibility, entirely replace the system file with our
- // one and textually include the system one. We need to pass macros
- // from our header to the system one if we #include_next it.
- //
- // FIXME: Can we do this in all cases?
- if (BuiltinFile && (!File || Map.LangOpts.ModulesLocalVisibility)) {
+ if (BuiltinFile && !File) {
File = BuiltinFile;
RelativePathName = BuiltinPathName;
BuiltinFile = nullptr;
@@ -1856,15 +1913,20 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
Module::Header H = {RelativePathName.str(), File};
Map.excludeHeader(ActiveModule, H);
} else {
- // If there is a builtin counterpart to this file, add it now, before
- // the "real" header, so we build the built-in one first when building
- // the module.
+ // If there is a builtin counterpart to this file, add it now so it can
+ // wrap the system header.
if (BuiltinFile) {
// FIXME: Taking the name from the FileEntry is unstable and can give
// different results depending on how we've previously named that file
// in this build.
Module::Header H = { BuiltinFile->getName(), BuiltinFile };
Map.addHeader(ActiveModule, H, Role);
+
+ // If we have both a builtin and system version of the file, the
+ // builtin version may want to inject macros into the system header, so
+ // force the system header to be treated as a textual header in this
+ // case.
+ Role = ModuleMap::ModuleHeaderRole(Role | ModuleMap::TextualHeader);
}
// Record this header.
@@ -2354,6 +2416,7 @@ bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
= llvm::StringSwitch<AttributeKind>(Tok.getString())
.Case("exhaustive", AT_exhaustive)
.Case("extern_c", AT_extern_c)
+ .Case("no_undeclared_includes", AT_no_undeclared_includes)
.Case("system", AT_system)
.Default(AT_unknown);
switch (Attribute) {
@@ -2373,6 +2436,10 @@ bool ModuleMapParser::parseOptionalAttributes(Attributes &Attrs) {
case AT_exhaustive:
Attrs.IsExhaustive = true;
break;
+
+ case AT_no_undeclared_includes:
+ Attrs.NoUndeclaredIncludes = true;
+ break;
}
consumeToken();
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 4742aae5c1230..45bdce32062ab 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -86,7 +86,7 @@ void Preprocessor::EnterCachingLexMode() {
const Token &Preprocessor::PeekAhead(unsigned N) {
assert(CachedLexPos + N > CachedTokens.size() && "Confused caching.");
ExitCachingLexMode();
- for (unsigned C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
+ for (size_t C = CachedLexPos + N - CachedTokens.size(); C > 0; --C) {
CachedTokens.push_back(Token());
Lex(CachedTokens.back());
}
@@ -105,7 +105,7 @@ void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) {
for (CachedTokensTy::size_type i = CachedLexPos; i != 0; --i) {
CachedTokensTy::iterator AnnotBegin = CachedTokens.begin() + i-1;
if (AnnotBegin->getLocation() == Tok.getLocation()) {
- assert((BacktrackPositions.empty() || BacktrackPositions.back() < i) &&
+ assert((BacktrackPositions.empty() || BacktrackPositions.back() <= i) &&
"The backtrack pos points inside the annotated tokens!");
// Replace the cached tokens with the single annotation token.
if (i < CachedLexPos)
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 77f118fd3ccb7..85504de3d15d8 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -12,25 +12,41 @@
///
//===----------------------------------------------------------------------===//
-#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/CharInfo.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/HeaderSearch.h"
-#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/ModuleLoader.h"
+#include "clang/Lex/ModuleMap.h"
+#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Pragma.h"
-#include "llvm/ADT/APInt.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/SaveAndRestore.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <new>
+#include <string>
+#include <utility>
using namespace clang;
@@ -53,7 +69,7 @@ MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L,
unsigned SubModuleID) {
- static_assert(llvm::AlignOf<MacroInfo>::Alignment >= sizeof(SubModuleID),
+ static_assert(alignof(MacroInfo) >= sizeof(SubModuleID),
"alignment for MacroInfo is less than the ID");
DeserializedMacroInfoChain *MIChain =
BP.Allocate<DeserializedMacroInfoChain>();
@@ -268,7 +284,7 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
if (ShadowFlag)
*ShadowFlag = false;
if (!SourceMgr.isInSystemHeader(MacroNameLoc) &&
- (strcmp(SourceMgr.getBufferName(MacroNameLoc), "<built-in>") != 0)) {
+ (SourceMgr.getBufferName(MacroNameLoc) != "<built-in>")) {
MacroDiag D = MD_NoWarn;
if (isDefineUndef == MU_Define) {
D = shouldWarnOnMacroDef(*this, II);
@@ -382,7 +398,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
// disabling warnings, etc.
CurPPLexer->LexingRawMode = true;
Token Tok;
- while (1) {
+ while (true) {
CurLexer->Lex(Tok);
if (Tok.is(tok::code_completion)) {
@@ -455,7 +471,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
Directive = RI;
} else {
std::string DirectiveStr = getSpelling(Tok);
- unsigned IdLen = DirectiveStr.size();
+ size_t IdLen = DirectiveStr.size();
if (IdLen >= 20) {
CurPPLexer->ParsingPreprocessorDirective = false;
// Restore comment saving mode.
@@ -578,7 +594,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
}
void Preprocessor::PTHSkipExcludedConditionalBlock() {
- while (1) {
+ while (true) {
assert(CurPTHLexer);
assert(CurPTHLexer->LexingRawMode == false);
@@ -785,8 +801,7 @@ const FileEntry *Preprocessor::LookupFile(
// headers included by quoted include directives.
// See: http://msdn.microsoft.com/en-us/library/36k2cdd4.aspx
if (LangOpts.MSVCCompat && !isAngled) {
- for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
- IncludeStackInfo &ISEntry = IncludeMacroStack[e - i - 1];
+ for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
if (IsFileLexer(ISEntry))
if ((FileEnt = ISEntry.ThePPLexer->getFileEntry()))
Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir()));
@@ -849,8 +864,7 @@ const FileEntry *Preprocessor::LookupFile(
}
}
- for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
- IncludeStackInfo &ISEntry = IncludeMacroStack[e-i-1];
+ for (IncludeStackInfo &ISEntry : llvm::reverse(IncludeMacroStack)) {
if (IsFileLexer(ISEntry)) {
if ((CurFileEnt = ISEntry.ThePPLexer->getFileEntry())) {
if ((FE = HeaderInfo.LookupSubframeworkHeader(
@@ -998,11 +1012,11 @@ void Preprocessor::HandleDirective(Token &Result) {
case tok::pp_define:
return HandleDefineDirective(Result, ImmediatelyAfterTopLevelIfndef);
case tok::pp_undef:
- return HandleUndefDirective(Result);
+ return HandleUndefDirective();
// C99 6.10.4 - Line Control.
case tok::pp_line:
- return HandleLineDirective(Result);
+ return HandleLineDirective();
// C99 6.10.5 - Error Directive.
case tok::pp_error:
@@ -1039,7 +1053,7 @@ void Preprocessor::HandleDirective(Token &Result) {
case tok::pp___private_macro:
if (getLangOpts().Modules)
- return HandleMacroPrivateDirective(Result);
+ return HandleMacroPrivateDirective();
break;
}
break;
@@ -1137,7 +1151,7 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
/// # line digit-sequence
/// # line digit-sequence "s-char-sequence"
/// \endverbatim
-void Preprocessor::HandleLineDirective(Token &Tok) {
+void Preprocessor::HandleLineDirective() {
// Read the line # and string argument. Per C99 6.10.4p5, these tokens are
// expanded.
Token DigitTok;
@@ -1442,7 +1456,7 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) {
}
/// \brief Handle a #private directive.
-void Preprocessor::HandleMacroPrivateDirective(Token &Tok) {
+void Preprocessor::HandleMacroPrivateDirective() {
Token MacroNameTok;
ReadMacroName(MacroNameTok, MU_Undef);
@@ -1551,7 +1565,7 @@ bool Preprocessor::ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
FilenameBuffer.push_back(' ');
// Get the spelling of the token, directly into FilenameBuffer if possible.
- unsigned PreAppendSize = FilenameBuffer.size();
+ size_t PreAppendSize = FilenameBuffer.size();
FilenameBuffer.resize(PreAppendSize+CurTok.getLength());
const char *BufPtr = &FilenameBuffer[PreAppendSize];
@@ -1602,7 +1616,7 @@ static void diagnoseAutoModuleImport(
assert(PP.getLangOpts().ObjC2 && "no import syntax available");
SmallString<128> PathString;
- for (unsigned I = 0, N = Path.size(); I != N; ++I) {
+ for (size_t I = 0, N = Path.size(); I != N; ++I) {
if (I)
PathString += '.';
PathString += Path[I].first->getName();
@@ -1831,7 +1845,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// If the file is still not found, just go with the vanilla diagnostic
if (!File)
- Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
+ Diag(FilenameTok, diag::err_pp_file_not_found) << Filename
+ << FilenameRange;
}
}
@@ -1851,12 +1866,9 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
// unavailable, diagnose the situation and bail out.
// FIXME: Remove this; loadModule does the same check (but produces
// slightly worse diagnostics).
- if (!SuggestedModule.getModule()->isAvailable() &&
- !SuggestedModule.getModule()
- ->getTopLevelModule()
- ->HasIncompatibleModuleFile) {
- clang::Module::Requirement Requirement;
- clang::Module::UnresolvedHeaderDirective MissingHeader;
+ if (!SuggestedModule.getModule()->isAvailable()) {
+ Module::Requirement Requirement;
+ Module::UnresolvedHeaderDirective MissingHeader;
Module *M = SuggestedModule.getModule();
// Identify the cause.
(void)M->isAvailable(getLangOpts(), getTargetInfo(), Requirement,
@@ -1903,9 +1915,12 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
else if (Imported.isMissingExpected()) {
// We failed to find a submodule that we assumed would exist (because it
// was in the directory of an umbrella header, for instance), but no
- // actual module exists for it (because the umbrella header is
+ // actual module containing it exists (because the umbrella header is
// incomplete). Treat this as a textual inclusion.
SuggestedModule = ModuleMap::KnownHeader();
+ } else if (Imported.isConfigMismatch()) {
+ // On a configuration mismatch, enter the header textually. We still know
+ // that it's part of the corresponding module.
} else {
// We hit an error processing the import. Bail out.
if (hadModuleLoaderFatalFailure()) {
@@ -2043,7 +2058,11 @@ void Preprocessor::HandleIncludeNextDirective(SourceLocation HashLoc,
// diagnostic.
const DirectoryLookup *Lookup = CurDirLookup;
const FileEntry *LookupFromFile = nullptr;
- if (isInPrimaryFile()) {
+ if (isInPrimaryFile() && LangOpts.IsHeaderFile) {
+ // If the main file is a header, then it's either for PCH/AST generation,
+ // or libclang opened it. Either way, handle it as a normal include below
+ // and do not complain about include_next.
+ } else if (isInPrimaryFile()) {
Lookup = nullptr;
Diag(IncludeNextTok, diag::pp_include_next_in_primary);
} else if (CurSubmodule) {
@@ -2098,7 +2117,7 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc,
// This directive should only occur in the predefines buffer. If not, emit an
// error and reject it.
SourceLocation Loc = IncludeMacrosTok.getLocation();
- if (strcmp(SourceMgr.getBufferName(Loc), "<built-in>") != 0) {
+ if (SourceMgr.getBufferName(Loc) != "<built-in>") {
Diag(IncludeMacrosTok.getLocation(),
diag::pp_include_macros_out_of_predefines);
DiscardUntilEndOfDirective();
@@ -2127,7 +2146,7 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc,
bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
SmallVector<IdentifierInfo*, 32> Arguments;
- while (1) {
+ while (true) {
LexUnexpandedToken(Tok);
switch (Tok.getKind()) {
case tok::r_paren:
@@ -2536,7 +2555,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
/// HandleUndefDirective - Implements \#undef.
///
-void Preprocessor::HandleUndefDirective(Token &UndefTok) {
+void Preprocessor::HandleUndefDirective() {
++NumUndefined;
Token MacroNameTok;
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 94075ece35cac..862a4713e4bca 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -17,14 +17,24 @@
//===----------------------------------------------------------------------===//
#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/Token.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SaveAndRestore.h"
+#include <cassert>
+
using namespace clang;
namespace {
@@ -34,6 +44,7 @@ namespace {
class PPValue {
SourceRange Range;
IdentifierInfo *II;
+
public:
llvm::APSInt Val;
@@ -58,7 +69,7 @@ public:
void setEnd(SourceLocation L) { Range.setEnd(L); }
};
-}
+} // end anonymous namespace
static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
Token &PeekTok, bool ValueLive,
@@ -469,8 +480,6 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
}
}
-
-
/// getPrecedence - Return the precedence of the specified binary operator
/// token. This returns:
/// ~0 - Invalid token.
@@ -531,7 +540,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
return true;
}
- while (1) {
+ while (true) {
// If this token has a lower precedence than we are allowed to parse, return
// it so that higher levels of the recursion can parse it.
if (PeekPrec < MinPrec)
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index e2eceafd983b8..4db17c344b677 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -40,10 +40,10 @@ bool Preprocessor::isInPrimaryFile() const {
// If there are any stacked lexers, we're in a #include.
assert(IsFileLexer(IncludeMacroStack[0]) &&
"Top level include stack isn't our primary lexer?");
- for (unsigned i = 1, e = IncludeMacroStack.size(); i != e; ++i)
- if (IsFileLexer(IncludeMacroStack[i]))
- return false;
- return true;
+ return std::none_of(IncludeMacroStack.begin() + 1, IncludeMacroStack.end(),
+ [this](const IncludeStackInfo &ISI) -> bool {
+ return IsFileLexer(ISI);
+ });
}
/// getCurrentLexer - Return the current file lexer being lexed from. Note
@@ -54,8 +54,7 @@ PreprocessorLexer *Preprocessor::getCurrentFileLexer() const {
return CurPPLexer;
// Look for a stacked lexer.
- for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
- const IncludeStackInfo& ISI = IncludeMacroStack[i-1];
+ for (const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {
if (IsFileLexer(ISI))
return ISI.ThePPLexer;
}
@@ -566,8 +565,7 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
// explicit EOD token.
PreprocessorLexer *FoundLexer = nullptr;
bool LexerWasInPPMode = false;
- for (unsigned i = 0, e = IncludeMacroStack.size(); i != e; ++i) {
- IncludeStackInfo &ISI = *(IncludeMacroStack.end()-i-1);
+ for (const IncludeStackInfo &ISI : llvm::reverse(IncludeMacroStack)) {
if (ISI.ThePPLexer == nullptr) continue; // Scan for a real lexer.
// Once we find a real lexer, mark it as raw mode (disabling macro
@@ -685,7 +683,7 @@ bool Preprocessor::needModuleMacros() const {
return true;
// Otherwise, we only need module macros if we're actually compiling a module
// interface.
- return getLangOpts().CompilingModule;
+ return getLangOpts().isCompilingModule();
}
void Preprocessor::LeaveSubmodule() {
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 2ade6df9456a6..aebebaac46ac0 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -12,25 +12,49 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/MacroInfo.h"
-#include "llvm/ADT/STLExtras.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
#include <ctime>
+#include <string>
+#include <tuple>
+#include <utility>
+
using namespace clang;
MacroDirective *
@@ -68,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())
@@ -286,7 +333,6 @@ static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
return Id;
}
-
/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
/// identifier table.
void Preprocessor::RegisterBuiltinMacros() {
@@ -367,10 +413,8 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
// If this is a function-like macro invocation, it's safe to trivially expand
// as long as the identifier is not a macro argument.
return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end();
-
}
-
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
/// method should have no observable side-effect on the lexed tokens.
@@ -390,8 +434,7 @@ bool Preprocessor::isNextPPTokenLParen() {
// macro stack.
if (CurPPLexer)
return false;
- for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
- IncludeStackInfo &Entry = IncludeMacroStack[i-1];
+ for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
if (Entry.TheLexer)
Val = Entry.TheLexer->isNextPPTokenLParen();
else if (Entry.ThePTHLexer)
@@ -480,8 +523,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
} else {
Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
if (!DelayedMacroExpandsCallbacks.empty()) {
- for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
- MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
+ for (const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
// FIXME: We lose macro args info with delayed callback.
Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
/*Args=*/nullptr);
@@ -735,14 +777,14 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
assert(Tok.isOneOf(tok::l_paren, tok::comma) &&
"only expect argument separators here");
- unsigned ArgTokenStart = ArgTokens.size();
+ size_t ArgTokenStart = ArgTokens.size();
SourceLocation ArgStartLoc = Tok.getLocation();
// C99 6.10.3p11: Keep track of the number of l_parens we have seen. Note
// that we already consumed the first one.
unsigned NumParens = 0;
- while (1) {
+ while (true) {
// Read arguments as unexpanded tokens. This avoids issues, e.g., where
// an argument value in a macro could expand to ',' or '(' or ')'.
LexUnexpandedToken(Tok);
@@ -987,10 +1029,10 @@ Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,
if (cacheNeedsToGrow) {
// Go through all the TokenLexers whose 'Tokens' pointer points in the
// buffer and update the pointers to the (potential) new buffer array.
- for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) {
+ for (const auto &Lexer : MacroExpandingLexersStack) {
TokenLexer *prevLexer;
size_t tokIndex;
- std::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
+ std::tie(prevLexer, tokIndex) = Lexer;
prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
}
}
@@ -1043,7 +1085,6 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
}
}
-
/// HasFeature - Return true if we recognize and implement the feature
/// specified by the identifier as a standard language feature.
static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
@@ -1090,6 +1131,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData)
.Case("enumerator_attributes", true)
.Case("nullability", true)
+ .Case("nullability_on_arrays", true)
.Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
.Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread))
.Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow))
@@ -1171,7 +1213,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
.Case("cxx_user_literals", LangOpts.CPlusPlus11)
.Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
- // C++1y features
+ // C++14 features
.Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14)
.Case("cxx_binary_literals", LangOpts.CPlusPlus14)
.Case("cxx_contextual_conversions", LangOpts.CPlusPlus14)
@@ -1181,6 +1223,9 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
.Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
.Case("cxx_variable_templates", LangOpts.CPlusPlus14)
+ // NOTE: For features covered by SD-6, it is preferable to provide *only*
+ // the SD-6 macro and not a __has_feature check.
+
// C++ TSes
//.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
//.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
@@ -1264,7 +1309,7 @@ static bool HasExtension(const Preprocessor &PP, StringRef Extension) {
.Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
.Case("cxx_rvalue_references", LangOpts.CPlusPlus)
.Case("cxx_variadic_templates", LangOpts.CPlusPlus)
- // C++1y features supported by other languages as extensions.
+ // C++14 features supported by other languages as extensions.
.Case("cxx_binary_literals", true)
.Case("cxx_init_captures", LangOpts.CPlusPlus11)
.Case("cxx_variable_templates", LangOpts.CPlusPlus)
@@ -1400,7 +1445,11 @@ static bool EvaluateHasIncludeNext(Token &Tok,
// Preprocessor::HandleIncludeNextDirective.
const DirectoryLookup *Lookup = PP.GetCurDirLookup();
const FileEntry *LookupFromFile = nullptr;
- if (PP.isInPrimaryFile()) {
+ if (PP.isInPrimaryFile() && PP.getLangOpts().IsHeaderFile) {
+ // If the main file is a header, then it's either for PCH/AST generation,
+ // or libclang opened it. Either way, handle it as a normal include below
+ // and do not complain about __has_include_next.
+ } else if (PP.isInPrimaryFile()) {
Lookup = nullptr;
PP.Diag(Tok, diag::pp_include_next_in_primary);
} else if (PP.getCurrentSubmodule()) {
@@ -1796,7 +1845,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
[this](Token &Tok, bool &HasLexedNextToken) -> int {
IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this,
diag::err_expected_id_building_module);
- return getLangOpts().CompilingModule && II &&
+ return getLangOpts().isCompilingModule() && II &&
(II->getName() == getLangOpts().CurrentModule);
});
} else if (II == Ident__MODULE__) {
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index 5f63d35c5be74..ec806e8445311 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -21,7 +21,6 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
@@ -318,7 +317,7 @@ public:
class PTHFileLookupCommonTrait {
public:
- typedef std::pair<unsigned char, const char*> internal_key_type;
+ typedef std::pair<unsigned char, StringRef> internal_key_type;
typedef unsigned hash_value_type;
typedef unsigned offset_type;
@@ -353,7 +352,7 @@ public:
}
static bool EqualKey(internal_key_type a, internal_key_type b) {
- return a.first == b.first && strcmp(a.second, b.second) == 0;
+ return a.first == b.first && a.second == b.second;
}
static PTHFileData ReadData(const internal_key_type& k,
@@ -629,15 +628,15 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) {
namespace {
class PTHStatData {
public:
- const bool HasData;
uint64_t Size;
time_t ModTime;
llvm::sys::fs::UniqueID UniqueID;
+ const bool HasData;
bool IsDirectory;
PTHStatData(uint64_t Size, time_t ModTime, llvm::sys::fs::UniqueID UniqueID,
bool IsDirectory)
- : HasData(true), Size(Size), ModTime(ModTime), UniqueID(UniqueID),
+ : Size(Size), ModTime(ModTime), UniqueID(UniqueID), HasData(true),
IsDirectory(IsDirectory) {}
PTHStatData() : HasData(false) {}
@@ -645,10 +644,10 @@ public:
class PTHStatLookupTrait : public PTHFileLookupCommonTrait {
public:
- typedef const char* external_key_type; // const char*
+ typedef StringRef external_key_type; // const char*
typedef PTHStatData data_type;
- static internal_key_type GetInternalKey(const char *path) {
+ static internal_key_type GetInternalKey(StringRef path) {
// The key 'kind' doesn't matter here because it is ignored in EqualKey.
return std::make_pair((unsigned char) 0x0, path);
}
@@ -656,7 +655,7 @@ public:
static bool EqualKey(internal_key_type a, internal_key_type b) {
// When doing 'stat' lookups we don't care about the kind of 'a' and 'b',
// just the paths.
- return strcmp(a.second, b.second) == 0;
+ return a.second == b.second;
}
static data_type ReadData(const internal_key_type& k, const unsigned char* d,
@@ -695,7 +694,7 @@ public:
: Cache(FL.getNumBuckets(), FL.getNumEntries(), FL.getBuckets(),
FL.getBase()) {}
- LookupResult getStat(const char *Path, FileData &Data, bool isFile,
+ LookupResult getStat(StringRef Path, FileData &Data, bool isFile,
std::unique_ptr<vfs::File> *F,
vfs::FileSystem &FS) override {
// Do the lookup for the file's data in the PTH file.
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 3bdd31b26ff8b..100da514144a6 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -14,21 +14,36 @@
#include "clang/Lex/Pragma.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LexDiagnostic.h"
-#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Token.h"
+#include "clang/Lex/TokenLexer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CrashRecoveryContext.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
-using namespace clang;
+#include <cassert>
+#include <cstdint>
+#include <limits>
+#include <string>
+#include <vector>
-#include "llvm/Support/raw_ostream.h"
+using namespace clang;
// Out-of-line destructor to provide a home for the class.
PragmaHandler::~PragmaHandler() {
@@ -123,6 +138,7 @@ void Preprocessor::HandlePragmaDirective(SourceLocation IntroducerLoc,
}
namespace {
+
/// \brief Helper class for \see Preprocessor::Handle_Pragma.
class LexingFor_PragmaRAII {
Preprocessor &PP;
@@ -157,7 +173,8 @@ public:
Failed = true;
}
};
-}
+
+} // end anonymous namespace
/// Handle_Pragma - Read a _Pragma directive, slice it up, process it, then
/// return the first token after the directive. The _Pragma token has just
@@ -264,7 +281,7 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
// Remove escaped quotes and escapes.
unsigned ResultPos = 1;
- for (unsigned i = 1, e = StrVal.size() - 1; i != e; ++i) {
+ for (size_t i = 1, e = StrVal.size() - 1; i != e; ++i) {
// Skip escapes. \\ -> '\' and \" -> '"'.
if (StrVal[i] == '\\' && i + 1 < e &&
(StrVal[i + 1] == '\\' || StrVal[i + 1] == '"'))
@@ -355,8 +372,10 @@ void Preprocessor::HandleMicrosoft__pragma(Token &Tok) {
///
void Preprocessor::HandlePragmaOnce(Token &OnceTok) {
// Don't honor the 'once' when handling the primary source file, unless
- // this is a prefix to a TU, which indicates we're generating a PCH file.
- if (isInPrimaryFile() && TUKind != TU_Prefix) {
+ // this is a prefix to a TU, which indicates we're generating a PCH file, or
+ // when the main file is a header (e.g. when -xc-header is provided on the
+ // commandline).
+ if (isInPrimaryFile() && TUKind != TU_Prefix && !getLangOpts().IsHeaderFile) {
Diag(OnceTok, diag::pp_pragma_once_in_main_file);
return;
}
@@ -374,13 +393,12 @@ void Preprocessor::HandlePragmaMark() {
CurPTHLexer->DiscardToEndOfLine();
}
-
/// HandlePragmaPoison - Handle \#pragma GCC poison. PoisonTok is the 'poison'.
///
-void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
+void Preprocessor::HandlePragmaPoison() {
Token Tok;
- while (1) {
+ while (true) {
// Read the next token to poison. While doing this, pretend that we are
// skipping while reading the identifier to poison.
// This avoids errors on code like:
@@ -612,7 +630,7 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
// Pop PragmaPushMacroInfo stack.
iter->second.pop_back();
- if (iter->second.size() == 0)
+ if (iter->second.empty())
PragmaPushMacroInfo.erase(iter);
} else {
Diag(MessageLoc, diag::warn_pragma_pop_macro_no_push)
@@ -809,6 +827,7 @@ bool Preprocessor::LexOnOffSwitch(tok::OnOffSwitch &Result) {
}
namespace {
+
/// PragmaOnceHandler - "\#pragma once" marks the file as atomically included.
struct PragmaOnceHandler : public PragmaHandler {
PragmaOnceHandler() : PragmaHandler("once") {}
@@ -823,6 +842,7 @@ struct PragmaOnceHandler : public PragmaHandler {
/// rest of the line is not lexed.
struct PragmaMarkHandler : public PragmaHandler {
PragmaMarkHandler() : PragmaHandler("mark") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &MarkTok) override {
PP.HandlePragmaMark();
@@ -832,9 +852,10 @@ struct PragmaMarkHandler : public PragmaHandler {
/// PragmaPoisonHandler - "\#pragma poison x" marks x as not usable.
struct PragmaPoisonHandler : public PragmaHandler {
PragmaPoisonHandler() : PragmaHandler("poison") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &PoisonTok) override {
- PP.HandlePragmaPoison(PoisonTok);
+ PP.HandlePragmaPoison();
}
};
@@ -842,14 +863,17 @@ struct PragmaPoisonHandler : public PragmaHandler {
/// as a system header, which silences warnings in it.
struct PragmaSystemHeaderHandler : public PragmaHandler {
PragmaSystemHeaderHandler() : PragmaHandler("system_header") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &SHToken) override {
PP.HandlePragmaSystemHeader(SHToken);
PP.CheckEndOfDirective("pragma");
}
};
+
struct PragmaDependencyHandler : public PragmaHandler {
PragmaDependencyHandler() : PragmaHandler("dependency") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &DepToken) override {
PP.HandlePragmaDependency(DepToken);
@@ -858,6 +882,7 @@ struct PragmaDependencyHandler : public PragmaHandler {
struct PragmaDebugHandler : public PragmaHandler {
PragmaDebugHandler() : PragmaHandler("__debug") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &DepToken) override {
Token Tok;
@@ -967,9 +992,11 @@ struct PragmaDebugHandler : public PragmaHandler {
struct PragmaDiagnosticHandler : public PragmaHandler {
private:
const char *Namespace;
+
public:
explicit PragmaDiagnosticHandler(const char *NS) :
PragmaHandler("diagnostic"), Namespace(NS) {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &DiagToken) override {
SourceLocation DiagLoc = DiagToken.getLocation();
@@ -1142,7 +1169,7 @@ struct PragmaWarningHandler : public PragmaHandler {
while (Tok.is(tok::numeric_constant)) {
uint64_t Value;
if (!PP.parseSimpleIntegerLiteral(Tok, Value) || Value == 0 ||
- Value > INT_MAX) {
+ Value > std::numeric_limits<int>::max()) {
PP.Diag(Tok, diag::warn_pragma_warning_expected_number);
return;
}
@@ -1267,17 +1294,18 @@ public:
/// macro on the top of the stack.
struct PragmaPushMacroHandler : public PragmaHandler {
PragmaPushMacroHandler() : PragmaHandler("push_macro") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &PushMacroTok) override {
PP.HandlePragmaPushMacro(PushMacroTok);
}
};
-
/// PragmaPopMacroHandler - "\#pragma pop_macro" sets the value of the
/// macro to the value on the top of the stack.
struct PragmaPopMacroHandler : public PragmaHandler {
PragmaPopMacroHandler() : PragmaHandler("pop_macro") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &PopMacroTok) override {
PP.HandlePragmaPopMacro(PopMacroTok);
@@ -1289,6 +1317,7 @@ struct PragmaPopMacroHandler : public PragmaHandler {
/// PragmaSTDC_FENV_ACCESSHandler - "\#pragma STDC FENV_ACCESS ...".
struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
PragmaSTDC_FENV_ACCESSHandler() : PragmaHandler("FENV_ACCESS") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &Tok) override {
tok::OnOffSwitch OOS;
@@ -1303,6 +1332,7 @@ struct PragmaSTDC_FENV_ACCESSHandler : public PragmaHandler {
struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
PragmaSTDC_CX_LIMITED_RANGEHandler()
: PragmaHandler("CX_LIMITED_RANGE") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &Tok) override {
tok::OnOffSwitch OOS;
@@ -1313,6 +1343,7 @@ struct PragmaSTDC_CX_LIMITED_RANGEHandler : public PragmaHandler {
/// PragmaSTDC_UnknownHandler - "\#pragma STDC ...".
struct PragmaSTDC_UnknownHandler : public PragmaHandler {
PragmaSTDC_UnknownHandler() {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &UnknownTok) override {
// C99 6.10.6p2, unknown forms are not allowed.
@@ -1324,6 +1355,7 @@ struct PragmaSTDC_UnknownHandler : public PragmaHandler {
/// \#pragma clang arc_cf_code_audited begin/end
struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
PragmaARCCFCodeAuditedHandler() : PragmaHandler("arc_cf_code_audited") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &NameTok) override {
SourceLocation Loc = NameTok.getLocation();
@@ -1378,6 +1410,7 @@ struct PragmaARCCFCodeAuditedHandler : public PragmaHandler {
/// \#pragma clang assume_nonnull begin/end
struct PragmaAssumeNonNullHandler : public PragmaHandler {
PragmaAssumeNonNullHandler() : PragmaHandler("assume_nonnull") {}
+
void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
Token &NameTok) override {
SourceLocation Loc = NameTok.getLocation();
@@ -1451,8 +1484,7 @@ struct PragmaRegionHandler : public PragmaHandler {
}
};
-} // end anonymous namespace
-
+} // end anonymous namespace
/// RegisterBuiltinPragmas - Install the standard preprocessor pragmas:
/// \#pragma GCC poison/system_header/dependency and \#pragma once.
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index 32e6de69f0dbf..13e15f3c943be 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -21,18 +21,13 @@ using namespace clang;
ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { }
-
InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
- InclusionKind Kind,
- StringRef FileName,
+ InclusionKind Kind, StringRef FileName,
bool InQuotes, bool ImportedModule,
- const FileEntry *File,
- SourceRange Range)
- : PreprocessingDirective(InclusionDirectiveKind, Range),
- InQuotes(InQuotes), Kind(Kind), ImportedModule(ImportedModule), File(File)
-{
- char *Memory
- = (char*)PPRec.Allocate(FileName.size() + 1, llvm::alignOf<char>());
+ const FileEntry *File, SourceRange Range)
+ : PreprocessingDirective(InclusionDirectiveKind, Range), InQuotes(InQuotes),
+ Kind(Kind), ImportedModule(ImportedModule), File(File) {
+ char *Memory = (char *)PPRec.Allocate(FileName.size() + 1, alignof(char));
memcpy(Memory, FileName.data(), FileName.size());
Memory[FileName.size()] = 0;
this->FileName = StringRef(Memory, FileName.size());
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 78179dd7988df..0f7473b8c1ffc 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -43,18 +43,27 @@
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/ScratchBuffer.h"
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Capacity.h"
-#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <memory>
+#include <string>
#include <utility>
+#include <vector>
+
using namespace clang;
-template class llvm::Registry<clang::PragmaHandler>;
+LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry)
//===----------------------------------------------------------------------===//
ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
@@ -74,11 +83,12 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr),
CodeCompletionFile(nullptr), CodeCompletionOffset(0),
LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),
- CodeCompletionReached(0), MainFileDir(nullptr),
- SkipMainFilePreamble(0, true), CurPPLexer(nullptr), CurDirLookup(nullptr),
- CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), Callbacks(nullptr),
- CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr),
- Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
+ CodeCompletionReached(false), CodeCompletionII(nullptr),
+ MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
+ CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
+ Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState),
+ MacroArgCache(nullptr), Record(nullptr), MIChainHead(nullptr),
+ DeserialMIChainHead(nullptr) {
OwnsHeaderSearch = OwnsHeaders;
CounterValue = 0; // __COUNTER__ starts at 0.
@@ -480,7 +490,7 @@ void Preprocessor::CreateString(StringRef Str, Token &Tok,
}
Module *Preprocessor::getCurrentModule() {
- if (!getLangOpts().CompilingModule)
+ if (!getLangOpts().isCompilingModule())
return nullptr;
return getHeaderSearchInfo().lookupModule(getLangOpts().CurrentModule);
@@ -490,7 +500,6 @@ Module *Preprocessor::getCurrentModule() {
// Preprocessor Initialization Methods
//===----------------------------------------------------------------------===//
-
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
void Preprocessor::EnterMainSourceFile() {
@@ -618,6 +627,11 @@ static diag::kind getFutureCompatDiagKind(const IdentifierInfo &II,
"Keyword not known to come from a newer Standard or proposed Standard");
}
+void Preprocessor::updateOutOfDateIdentifier(IdentifierInfo &II) const {
+ assert(II.isOutOfDate() && "not out of date");
+ getExternalSource()->updateOutOfDateIdentifier(II);
+}
+
/// HandleIdentifier - This callback is invoked when the lexer reads an
/// identifier. This callback looks up the identifier in the map and/or
/// potentially macro expands it or turns it into a named token (like 'for').
@@ -642,7 +656,7 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
if (&II == Ident__VA_ARGS__)
CurrentIsPoisoned = Ident__VA_ARGS__->isPoisoned();
- ExternalSource->updateOutOfDateIdentifier(II);
+ updateOutOfDateIdentifier(II);
Identifier.setKind(II.getTokenID());
if (&II == Ident__VA_ARGS__)
@@ -707,9 +721,12 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
// Note that we do not treat 'import' as a contextual
// keyword when we're in a caching lexer, because caching lexers only get
// used in contexts where import declarations are disallowed.
- if (LastTokenWasAt && II.isModulesImport() && !InMacroArgs &&
- !DisableMacroExpansion &&
- (getLangOpts().Modules || getLangOpts().DebuggerSupport) &&
+ //
+ // Likewise if this is the C++ Modules TS import keyword.
+ if (((LastTokenWasAt && II.isModulesImport()) ||
+ Identifier.is(tok::kw_import)) &&
+ !InMacroArgs && !DisableMacroExpansion &&
+ (getLangOpts().Modules || getLangOpts().DebuggerSupport) &&
CurLexerKind != CLK_CachingLexer) {
ModuleImportLoc = Identifier.getLocation();
ModuleImportPath.clear();
@@ -744,10 +761,12 @@ void Preprocessor::Lex(Token &Result) {
}
} while (!ReturnedToken);
+ if (Result.is(tok::code_completion))
+ setCodeCompletionIdentifierInfo(Result.getIdentifierInfo());
+
LastTokenWasAt = Result.is(tok::at);
}
-
/// \brief Lex a token following the 'import' contextual keyword.
///
void Preprocessor::LexAfterModuleImport(Token &Result) {
@@ -774,7 +793,8 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
}
// If we're expecting a '.' or a ';', and we got a '.', then wait until we
- // see the next identifier.
+ // see the next identifier. (We can also see a '[[' that begins an
+ // attribute-specifier-seq here under the C++ Modules TS.)
if (!ModuleImportExpectsIdentifier && Result.getKind() == tok::period) {
ModuleImportExpectsIdentifier = true;
CurLexerKind = CLK_LexAfterModuleImport;
@@ -783,6 +803,23 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
// If we have a non-empty module path, load the named module.
if (!ModuleImportPath.empty()) {
+ // Under the Modules TS, the dot is just part of the module name, and not
+ // a real hierarachy separator. Flatten such module names now.
+ //
+ // FIXME: Is this the right level to be performing this transformation?
+ std::string FlatModuleName;
+ if (getLangOpts().ModulesTS) {
+ for (auto &Piece : ModuleImportPath) {
+ if (!FlatModuleName.empty())
+ FlatModuleName += ".";
+ FlatModuleName += Piece.first->getName();
+ }
+ SourceLocation FirstPathLoc = ModuleImportPath[0].second;
+ ModuleImportPath.clear();
+ ModuleImportPath.push_back(
+ std::make_pair(getIdentifierInfo(FlatModuleName), FirstPathLoc));
+ }
+
Module *Imported = nullptr;
if (getLangOpts().Modules) {
Imported = TheModuleLoader.loadModule(ModuleImportLoc,
diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp
index 27b4eab1a28db..d1facd9c68796 100644
--- a/lib/Lex/TokenConcatenation.cpp
+++ b/lib/Lex/TokenConcatenation.cpp
@@ -232,7 +232,7 @@ bool TokenConcatenation::AvoidConcat(const Token &PrevPrevTok,
// it as an identifier.
if (!PrevTok.hasUDSuffix())
return false;
- // FALL THROUGH.
+ LLVM_FALLTHROUGH;
case tok::identifier: // id+id or id+number or id+L"foo".
// id+'.'... will not append.
if (Tok.is(tok::numeric_constant))
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 994bae632aec7..a53c8014ebaf0 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -275,7 +275,7 @@ void TokenLexer::ExpandFunctionArguments() {
// If the arg token expanded into anything, append it.
if (ResultArgToks->isNot(tok::eof)) {
- unsigned FirstResult = ResultToks.size();
+ size_t FirstResult = ResultToks.size();
unsigned NumToks = MacroArgs::getArgLength(ResultArgToks);
ResultToks.append(ResultArgToks, ResultArgToks+NumToks);
@@ -289,8 +289,8 @@ void TokenLexer::ExpandFunctionArguments() {
// If the '##' came from expanding an argument, turn it into 'unknown'
// to avoid pasting.
- for (unsigned i = FirstResult, e = ResultToks.size(); i != e; ++i) {
- Token &Tok = ResultToks[i];
+ for (Token &Tok : llvm::make_range(ResultToks.begin() + FirstResult,
+ ResultToks.end())) {
if (Tok.is(tok::hashhash))
Tok.setKind(tok::unknown);
}
@@ -333,9 +333,8 @@ void TokenLexer::ExpandFunctionArguments() {
// If the '##' came from expanding an argument, turn it into 'unknown'
// to avoid pasting.
- for (unsigned i = ResultToks.size() - NumToks, e = ResultToks.size();
- i != e; ++i) {
- Token &Tok = ResultToks[i];
+ for (Token &Tok : llvm::make_range(ResultToks.end() - NumToks,
+ ResultToks.end())) {
if (Tok.is(tok::hashhash))
Tok.setKind(tok::unknown);
}