aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-05-27 18:47:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-05-27 18:47:56 +0000
commit5e20cdd81c44a443562a09007668ffdf76c455af (patch)
treedbbd4047878da71c1a706e26ce05b4e7791b14cc /lib/Lex
parentd5f23b0b7528b5c3caed1ba14f897cc4aaa9e3c3 (diff)
downloadsrc-5e20cdd81c44a443562a09007668ffdf76c455af.tar.gz
src-5e20cdd81c44a443562a09007668ffdf76c455af.zip
Vendor import of clang trunk r238337:vendor/clang/clang-trunk-r238337
Notes
Notes: svn path=/vendor/clang/dist/; revision=283627 svn path=/vendor/clang/clang-trunk-r238337/; revision=283628; tag=vendor/clang/clang-trunk-r238337
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/HeaderSearch.cpp47
-rw-r--r--lib/Lex/Lexer.cpp12
-rw-r--r--lib/Lex/LiteralSupport.cpp90
-rw-r--r--lib/Lex/MacroArgs.cpp7
-rw-r--r--lib/Lex/MacroInfo.cpp17
-rw-r--r--lib/Lex/ModuleMap.cpp184
-rw-r--r--lib/Lex/PPConditionalDirectiveRecord.cpp4
-rw-r--r--lib/Lex/PPDirectives.cpp325
-rw-r--r--lib/Lex/PPExpressions.cpp25
-rw-r--r--lib/Lex/PPLexerChange.cpp130
-rw-r--r--lib/Lex/PPMacroExpansion.cpp293
-rw-r--r--lib/Lex/Pragma.cpp67
-rw-r--r--lib/Lex/PreprocessingRecord.cpp74
-rw-r--r--lib/Lex/Preprocessor.cpp82
-rw-r--r--lib/Lex/ScratchBuffer.cpp5
-rw-r--r--lib/Lex/TokenLexer.cpp9
16 files changed, 894 insertions, 477 deletions
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index d6b255fb014e..ad7d3449ac4a 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -18,6 +18,7 @@
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallString.h"
@@ -149,7 +150,7 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
SmallString<128> HashStr;
llvm::APInt(64, size_t(Hash)).toStringUnsigned(HashStr, /*Radix*/36);
- llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm");
+ llvm::sys::path::append(Result, ModuleName + "-" + HashStr + ".pcm");
}
return Result.str().str();
}
@@ -297,7 +298,7 @@ const FileEntry *DirectoryLookup::LookupFile(
RelativePath->append(Filename.begin(), Filename.end());
}
- return getFileAndSuggestModule(HS, TmpDir.str(), getDir(),
+ return getFileAndSuggestModule(HS, TmpDir, getDir(),
isSystemHeaderDirectory(),
SuggestedModule);
}
@@ -438,7 +439,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
HS.IncrementFrameworkLookupCount();
// If the framework dir doesn't exist, we fail.
- const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
+ const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName);
if (!Dir) return nullptr;
// Otherwise, if it does, remember that this is the right direntry for this
@@ -450,7 +451,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
if (getDirCharacteristic() == SrcMgr::C_User) {
SmallString<1024> SystemFrameworkMarker(FrameworkName);
SystemFrameworkMarker += ".system_framework";
- if (llvm::sys::fs::exists(SystemFrameworkMarker.str())) {
+ if (llvm::sys::fs::exists(SystemFrameworkMarker)) {
CacheEntry.IsUserSpecifiedSystemFramework = true;
}
}
@@ -476,7 +477,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
}
FrameworkName.append(Filename.begin()+SlashPos+1, Filename.end());
- const FileEntry *FE = FileMgr.getFile(FrameworkName.str(),
+ const FileEntry *FE = FileMgr.getFile(FrameworkName,
/*openFile=*/!SuggestedModule);
if (!FE) {
// Check "/System/Library/Frameworks/Cocoa.framework/PrivateHeaders/file.h"
@@ -487,7 +488,7 @@ const FileEntry *DirectoryLookup::DoFrameworkLookup(
SearchPath->insert(SearchPath->begin()+OrigSize, Private,
Private+strlen(Private));
- FE = FileMgr.getFile(FrameworkName.str(), /*openFile=*/!SuggestedModule);
+ FE = FileMgr.getFile(FrameworkName, /*openFile=*/!SuggestedModule);
}
// If we found the header and are allowed to suggest a module, do so now.
@@ -594,7 +595,13 @@ const FileEntry *HeaderSearch::LookupFile(
RelativePath->append(Filename.begin(), Filename.end());
}
// Otherwise, just return the file.
- return FileMgr.getFile(Filename, /*openFile=*/true);
+ const FileEntry *File = FileMgr.getFile(Filename, /*openFile=*/true);
+ if (File && SuggestedModule) {
+ // If there is a module that corresponds to this header, suggest it.
+ hasModuleMap(Filename, File->getDir(), /*SystemHeaderDir*/false);
+ *SuggestedModule = findModuleForHeader(File);
+ }
+ return File;
}
// This is the header that MSVC's header search would have found.
@@ -628,7 +635,7 @@ const FileEntry *HeaderSearch::LookupFile(
bool IncluderIsSystemHeader =
Includer && getFileInfo(Includer).DirInfo != SrcMgr::C_User;
if (const FileEntry *FE = getFileAndSuggestModule(
- *this, TmpDir.str(), IncluderAndDir.second,
+ *this, TmpDir, IncluderAndDir.second,
IncluderIsSystemHeader, SuggestedModule)) {
if (!Includer) {
assert(First && "only first includer can have no file");
@@ -865,7 +872,7 @@ LookupSubframeworkHeader(StringRef Filename,
++NumSubFrameworkLookups;
// If the framework dir doesn't exist, we fail.
- const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName.str());
+ const DirectoryEntry *Dir = FileMgr.getDirectory(FrameworkName);
if (!Dir) return nullptr;
// Otherwise, if it does, remember that this is the right direntry for this
@@ -890,7 +897,7 @@ LookupSubframeworkHeader(StringRef Filename,
}
HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
- if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true))) {
+ if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true))) {
// Check ".../Frameworks/HIToolbox.framework/PrivateHeaders/HIToolbox.h"
HeadersFilename = FrameworkName;
@@ -902,7 +909,7 @@ LookupSubframeworkHeader(StringRef Filename,
}
HeadersFilename.append(Filename.begin()+SlashPos+1, Filename.end());
- if (!(FE = FileMgr.getFile(HeadersFilename.str(), /*openFile=*/true)))
+ if (!(FE = FileMgr.getFile(HeadersFilename, /*openFile=*/true)))
return nullptr;
}
@@ -1016,7 +1023,9 @@ void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
HFI.setHeaderRole(Role);
}
-bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
+bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
+ const FileEntry *File,
+ bool isImport) {
++NumIncluded; // Count # of attempted #includes.
// Get information about this file.
@@ -1041,7 +1050,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
// if the macro that guards it is defined, we know the #include has no effect.
if (const IdentifierInfo *ControllingMacro
= FileInfo.getControllingMacro(ExternalLookup))
- if (ControllingMacro->hasMacroDefinition()) {
+ if (PP.isMacroDefined(ControllingMacro)) {
++NumMultiIncludeFileOptzn;
return false;
}
@@ -1067,7 +1076,7 @@ StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
bool HeaderSearch::hasModuleMap(StringRef FileName,
const DirectoryEntry *Root,
bool IsSystem) {
- if (!enabledModules() || !LangOpts.ModulesImplicitMaps)
+ if (!HSOpts->ModuleMaps || !LangOpts.ModulesImplicitMaps)
return false;
SmallVector<const DirectoryEntry *, 2> FixUpDirectories;
@@ -1284,7 +1293,7 @@ void HeaderSearch::collectAllModules(SmallVectorImpl<Module *> &Modules) {
DirNative);
// Search each of the ".framework" directories to load them as modules.
- for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
+ for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
if (llvm::sys::path::extension(Dir->path()) != ".framework")
continue;
@@ -1351,10 +1360,12 @@ void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) {
std::error_code EC;
SmallString<128> DirNative;
llvm::sys::path::native(SearchDir.getDir()->getName(), DirNative);
- for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd;
+ for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
- loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
- SearchDir.isFramework());
+ bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
+ if (IsFramework == SearchDir.isFramework())
+ loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
+ SearchDir.isFramework());
}
SearchDir.setSearchedAllModuleMaps(true);
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index ca5252e1c9ce..3f89ea649cbb 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -143,14 +143,8 @@ Lexer::Lexer(SourceLocation fileloc, const LangOptions &langOpts,
/// range will outlive it, so it doesn't take ownership of it.
Lexer::Lexer(FileID FID, const llvm::MemoryBuffer *FromFile,
const SourceManager &SM, const LangOptions &langOpts)
- : FileLoc(SM.getLocForStartOfFile(FID)), LangOpts(langOpts) {
-
- InitLexer(FromFile->getBufferStart(), FromFile->getBufferStart(),
- FromFile->getBufferEnd());
-
- // We *are* in raw mode.
- LexingRawMode = true;
-}
+ : Lexer(SM.getLocForStartOfFile(FID), langOpts, FromFile->getBufferStart(),
+ FromFile->getBufferStart(), FromFile->getBufferEnd()) {}
/// Create_PragmaLexer: Lexer constructor - Create a new lexer object for
/// _Pragma expansion. This has a variety of magic semantics that this method
@@ -1860,7 +1854,7 @@ bool Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) {
char C = getAndAdvanceChar(CurPtr, Result);
while (C != '>') {
// Skip escaped characters.
- if (C == '\\') {
+ if (C == '\\' && CurPtr < BufferEnd) {
// Skip the escaped character.
getAndAdvanceChar(CurPtr, Result);
} else if (C == '\n' || C == '\r' || // Newline.
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 03331fb33eb2..aed91648799b 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -144,7 +144,8 @@ static unsigned ProcessCharEscape(const char *ThisTokBegin,
int CharVal = llvm::hexDigitValue(ThisTokBuf[0]);
if (CharVal == -1) break;
// About to shift out a digit?
- Overflow |= (ResultChar & 0xF0000000) ? true : false;
+ if (ResultChar & 0xF0000000)
+ Overflow = true;
ResultChar <<= 4;
ResultChar |= CharVal;
}
@@ -596,7 +597,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (isFloat) break; // LF invalid.
// Check for long long. The L's need to be adjacent and the same case.
- if (s+1 != ThisTokEnd && s[1] == s[0]) {
+ if (s[1] == s[0]) {
+ assert(s + 1 < ThisTokEnd && "didn't maximally munch?");
if (isFPConstant) break; // long long invalid for floats.
isLongLong = true;
++s; // Eat both of them.
@@ -610,54 +612,45 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (isLong || isLongLong || MicrosoftInteger)
break;
- // Allow i8, i16, i32, i64, and i128.
- if (s + 1 != ThisTokEnd) {
+ if (!isFPConstant) {
+ // Allow i8, i16, i32, i64, and i128.
switch (s[1]) {
- case '8':
- if (isFPConstant) break;
- s += 2; // i8 suffix
- MicrosoftInteger = 8;
- break;
- case '1':
- if (isFPConstant) break;
- if (s + 2 == ThisTokEnd) break;
- if (s[2] == '6') {
- s += 3; // i16 suffix
- MicrosoftInteger = 16;
- }
- else if (s[2] == '2') {
- if (s + 3 == ThisTokEnd) break;
- if (s[3] == '8') {
- s += 4; // i128 suffix
- MicrosoftInteger = 128;
- }
- }
- break;
- case '3':
- if (isFPConstant) break;
- if (s + 2 == ThisTokEnd) break;
- if (s[2] == '2') {
- s += 3; // i32 suffix
- MicrosoftInteger = 32;
- }
- break;
- case '6':
- if (isFPConstant) break;
- if (s + 2 == ThisTokEnd) break;
- if (s[2] == '4') {
- s += 3; // i64 suffix
- MicrosoftInteger = 64;
- }
- break;
- default:
- break;
- }
- if (MicrosoftInteger)
+ case '8':
+ s += 2; // i8 suffix
+ MicrosoftInteger = 8;
+ break;
+ case '1':
+ if (s[2] == '6') {
+ s += 3; // i16 suffix
+ MicrosoftInteger = 16;
+ } else if (s[2] == '2' && s[3] == '8') {
+ s += 4; // i128 suffix
+ MicrosoftInteger = 128;
+ }
+ break;
+ case '3':
+ if (s[2] == '2') {
+ s += 3; // i32 suffix
+ MicrosoftInteger = 32;
+ }
+ break;
+ case '6':
+ if (s[2] == '4') {
+ s += 3; // i64 suffix
+ MicrosoftInteger = 64;
+ }
break;
+ default:
+ break;
+ }
+ }
+ if (MicrosoftInteger) {
+ assert(s <= ThisTokEnd && "didn't maximally munch?");
+ break;
}
}
// "i", "if", and "il" are user-defined suffixes in C++1y.
- if (PP.getLangOpts().CPlusPlus14 && *s == 'i')
+ if (*s == 'i' && PP.getLangOpts().CPlusPlus14)
break;
// fall through.
case 'j':
@@ -755,11 +748,11 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
s++;
int c1 = s[0];
- int c2 = s[1];
// Handle a hex number like 0x1234.
- if ((c1 == 'x' || c1 == 'X') && (isHexDigit(c2) || c2 == '.')) {
+ if ((c1 == 'x' || c1 == 'X') && (isHexDigit(s[1]) || s[1] == '.')) {
s++;
+ assert(s < ThisTokEnd && "didn't maximally munch?");
radix = 16;
DigitsBegin = s;
s = SkipHexDigits(s);
@@ -811,7 +804,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
}
// Handle simple binary numbers 0b01010
- if ((c1 == 'b' || c1 == 'B') && (c2 == '0' || c2 == '1')) {
+ if ((c1 == 'b' || c1 == 'B') && (s[1] == '0' || s[1] == '1')) {
// 0b101010 is a C++1y / GCC extension.
PP.Diag(TokLoc,
PP.getLangOpts().CPlusPlus14
@@ -820,6 +813,7 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
? diag::ext_binary_literal_cxx14
: diag::ext_binary_literal);
++s;
+ assert(s < ThisTokEnd && "didn't maximally munch?");
radix = 2;
DigitsBegin = s;
s = SkipBinaryDigits(s);
diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp
index 9967f3f0e493..1c1979d8e83d 100644
--- a/lib/Lex/MacroArgs.cpp
+++ b/lib/Lex/MacroArgs.cpp
@@ -133,12 +133,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok,
// If there are no identifiers in the argument list, or if the identifiers are
// known to not be macros, pre-expansion won't modify it.
for (; ArgTok->isNot(tok::eof); ++ArgTok)
- if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) {
- if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled())
+ if (IdentifierInfo *II = ArgTok->getIdentifierInfo())
+ if (II->hasMacroDefinition())
// Return true even though the macro could be a function-like macro
- // without a following '(' token.
+ // without a following '(' token, or could be disabled, or not visible.
return true;
- }
return false;
}
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 5416886cc9f7..109b6c12b89b 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -218,13 +218,9 @@ void MacroDirective::dump() const {
if (auto *Prev = getPrevious())
Out << " prev " << Prev;
if (IsFromPCH) Out << " from_pch";
- if (IsImported) Out << " imported";
- if (IsAmbiguous) Out << " ambiguous";
- if (IsPublic)
- Out << " public";
- else if (isa<VisibilityMacroDirective>(this))
- Out << " private";
+ if (isa<VisibilityMacroDirective>(this))
+ Out << (IsPublic ? " public" : " private");
if (auto *DMD = dyn_cast<DefMacroDirective>(this)) {
if (auto *Info = DMD->getInfo()) {
@@ -234,3 +230,12 @@ void MacroDirective::dump() const {
}
Out << "\n";
}
+
+ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule,
+ IdentifierInfo *II, MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides) {
+ void *Mem = PP.getPreprocessorAllocator().Allocate(
+ sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
+ llvm::alignOf<ModuleMacro>());
+ return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
+}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index ef322d8cdc4c..412918362d32 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -89,7 +89,9 @@ ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
HeaderSearch &HeaderInfo)
: SourceMgr(SourceMgr), Diags(Diags), LangOpts(LangOpts), Target(Target),
HeaderInfo(HeaderInfo), BuiltinIncludeDir(nullptr),
- CompilingModule(nullptr), SourceModule(nullptr) {}
+ CompilingModule(nullptr), SourceModule(nullptr), NumCreatedModules(0) {
+ MMapLangOpts.LineComment = true;
+}
ModuleMap::~ModuleMap() {
for (llvm::StringMap<Module *>::iterator I = Modules.begin(),
@@ -203,35 +205,32 @@ ModuleMap::findHeaderInUmbrellaDirs(const FileEntry *File,
return KnownHeader();
}
-// Returns true if RequestingModule directly uses RequestedModule.
-static bool directlyUses(const Module *RequestingModule,
- const Module *RequestedModule) {
- return std::find(RequestingModule->DirectUses.begin(),
- RequestingModule->DirectUses.end(),
- RequestedModule) != RequestingModule->DirectUses.end();
-}
-
static bool violatesPrivateInclude(Module *RequestingModule,
const FileEntry *IncFileEnt,
ModuleMap::ModuleHeaderRole Role,
Module *RequestedModule) {
bool IsPrivateRole = Role & ModuleMap::PrivateHeader;
#ifndef NDEBUG
- // Check for consistency between the module header role
- // as obtained from the lookup and as obtained from the module.
- // This check is not cheap, so enable it only for debugging.
- bool IsPrivate = false;
- SmallVectorImpl<Module::Header> *HeaderList[] =
- {&RequestedModule->Headers[Module::HK_Private],
- &RequestedModule->Headers[Module::HK_PrivateTextual]};
- for (auto *Hdrs : HeaderList)
- IsPrivate |=
- std::find_if(Hdrs->begin(), Hdrs->end(), [&](const Module::Header &H) {
- return H.Entry == IncFileEnt;
- }) != Hdrs->end();
- assert(IsPrivate == IsPrivateRole && "inconsistent headers and roles");
+ if (IsPrivateRole) {
+ // Check for consistency between the module header role
+ // as obtained from the lookup and as obtained from the module.
+ // This check is not cheap, so enable it only for debugging.
+ bool IsPrivate = false;
+ SmallVectorImpl<Module::Header> *HeaderList[] = {
+ &RequestedModule->Headers[Module::HK_Private],
+ &RequestedModule->Headers[Module::HK_PrivateTextual]};
+ for (auto *Hs : HeaderList)
+ IsPrivate |=
+ std::find_if(Hs->begin(), Hs->end(), [&](const Module::Header &H) {
+ return H.Entry == IncFileEnt;
+ }) != Hs->end();
+ assert((!IsPrivateRole || IsPrivate) && "inconsistent headers and roles");
+ }
#endif
return IsPrivateRole &&
+ // FIXME: Should we map RequestingModule to its top-level module here
+ // too? This check is redundant with the isSubModuleOf check in
+ // diagnoseHeaderInclusion.
RequestedModule->getTopLevelModule() != RequestingModule;
}
@@ -259,7 +258,8 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
if (Known != Headers.end()) {
for (const KnownHeader &Header : Known->second) {
// If 'File' is part of 'RequestingModule' we can definitely include it.
- if (Header.getModule() == RequestingModule)
+ if (Header.getModule() &&
+ Header.getModule()->isSubModuleOf(RequestingModule))
return;
// Remember private headers for later printing of a diagnostic.
@@ -272,7 +272,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// If uses need to be specified explicitly, we are only allowed to return
// modules that are explicitly used by the requesting module.
if (RequestingModule && LangOpts.ModulesDeclUse &&
- !directlyUses(RequestingModule, Header.getModule())) {
+ !RequestingModule->directlyUses(Header.getModule())) {
NotUsed = Header.getModule();
continue;
}
@@ -286,14 +286,14 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// We have found a header, but it is private.
if (Private) {
- Diags.Report(FilenameLoc, diag::error_use_of_private_header_outside_module)
+ Diags.Report(FilenameLoc, diag::warn_use_of_private_header_outside_module)
<< Filename;
return;
}
// We have found a module, but we don't use it.
if (NotUsed) {
- Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+ Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
<< RequestingModule->getFullModuleName() << Filename;
return;
}
@@ -304,7 +304,7 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
// At this point, only non-modular includes remain.
if (LangOpts.ModulesStrictDeclUse) {
- Diags.Report(FilenameLoc, diag::error_undeclared_use_of_module)
+ Diags.Report(FilenameLoc, diag::err_undeclared_use_of_module)
<< RequestingModule->getFullModuleName() << Filename;
} else if (RequestingModule) {
diag::kind DiagID = RequestingModule->getTopLevelModule()->IsFramework ?
@@ -314,6 +314,22 @@ void ModuleMap::diagnoseHeaderInclusion(Module *RequestingModule,
}
}
+static bool isBetterKnownHeader(const ModuleMap::KnownHeader &New,
+ const ModuleMap::KnownHeader &Old) {
+ // Prefer a public header over a private header.
+ if ((New.getRole() & ModuleMap::PrivateHeader) !=
+ (Old.getRole() & ModuleMap::PrivateHeader))
+ return !(New.getRole() & ModuleMap::PrivateHeader);
+
+ // Prefer a non-textual header over a textual header.
+ if ((New.getRole() & ModuleMap::TextualHeader) !=
+ (Old.getRole() & ModuleMap::TextualHeader))
+ return !(New.getRole() & ModuleMap::TextualHeader);
+
+ // Don't have a reason to choose between these. Just keep the first one.
+ return false;
+}
+
ModuleMap::KnownHeader
ModuleMap::findModuleForHeader(const FileEntry *File,
Module *RequestingModule,
@@ -345,11 +361,10 @@ ModuleMap::findModuleForHeader(const FileEntry *File,
// If uses need to be specified explicitly, we are only allowed to return
// modules that are explicitly used by the requesting module.
if (RequestingModule && LangOpts.ModulesDeclUse &&
- !directlyUses(RequestingModule, I->getModule()))
+ !RequestingModule->directlyUses(I->getModule()))
continue;
- // Prefer a public header over a private header.
- if (!Result || (Result.getRole() & ModuleMap::PrivateHeader))
+ if (!Result || isBetterKnownHeader(*I, Result))
Result = *I;
}
return MakeResult(Result);
@@ -548,7 +563,7 @@ ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,
// Create a new module with this name.
Module *Result = new Module(Name, SourceLocation(), Parent,
- IsFramework, IsExplicit);
+ IsFramework, IsExplicit, NumCreatedModules++);
if (LangOpts.CurrentModule == Name) {
SourceModule = Result;
SourceModuleName = Name;
@@ -678,7 +693,8 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
return nullptr;
Module *Result = new Module(ModuleName, SourceLocation(), Parent,
- /*IsFramework=*/true, /*IsExplicit=*/false);
+ /*IsFramework=*/true, /*IsExplicit=*/false,
+ NumCreatedModules++);
InferredModuleAllowedBy[Result] = ModuleMapFile;
Result->IsInferred = true;
if (LangOpts.CurrentModule == ModuleName) {
@@ -689,14 +705,16 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
Result->IsSystem |= Attrs.IsSystem;
Result->IsExternC |= Attrs.IsExternC;
Result->ConfigMacrosExhaustive |= Attrs.IsExhaustive;
+ Result->Directory = FrameworkDir;
if (!Parent)
Modules[ModuleName] = Result;
// umbrella header "umbrella-header-name"
- Result->Umbrella = UmbrellaHeader;
- Headers[UmbrellaHeader].push_back(KnownHeader(Result, NormalHeader));
- UmbrellaDirs[UmbrellaHeader->getDir()] = Result;
+ //
+ // The "Headers/" component of the name is implied because this is
+ // a framework module.
+ setUmbrellaHeader(Result, UmbrellaHeader, ModuleName + ".h");
// export *
Result->Exports.push_back(Module::ExportDecl(nullptr, true));
@@ -711,8 +729,7 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
= StringRef(FrameworkDir->getName());
llvm::sys::path::append(SubframeworksDirName, "Frameworks");
llvm::sys::path::native(SubframeworksDirName);
- for (llvm::sys::fs::directory_iterator
- Dir(SubframeworksDirName.str(), EC), DirEnd;
+ for (llvm::sys::fs::directory_iterator Dir(SubframeworksDirName, EC), DirEnd;
Dir != DirEnd && !EC; Dir.increment(EC)) {
if (!StringRef(Dir->path()).endswith(".framework"))
continue;
@@ -758,14 +775,18 @@ Module *ModuleMap::inferFrameworkModule(StringRef ModuleName,
return Result;
}
-void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
+void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader,
+ Twine NameAsWritten) {
Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader));
Mod->Umbrella = UmbrellaHeader;
+ Mod->UmbrellaAsWritten = NameAsWritten.str();
UmbrellaDirs[UmbrellaHeader->getDir()] = Mod;
}
-void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir) {
+void ModuleMap::setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir,
+ Twine NameAsWritten) {
Mod->Umbrella = UmbrellaDir;
+ Mod->UmbrellaAsWritten = NameAsWritten.str();
UmbrellaDirs[UmbrellaDir] = Mod;
}
@@ -850,50 +871,44 @@ void ModuleMap::dump() {
}
bool ModuleMap::resolveExports(Module *Mod, bool Complain) {
- bool HadError = false;
- for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
- Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I],
- Complain);
+ auto Unresolved = std::move(Mod->UnresolvedExports);
+ Mod->UnresolvedExports.clear();
+ for (auto &UE : Unresolved) {
+ Module::ExportDecl Export = resolveExport(Mod, UE, Complain);
if (Export.getPointer() || Export.getInt())
Mod->Exports.push_back(Export);
else
- HadError = true;
+ Mod->UnresolvedExports.push_back(UE);
}
- Mod->UnresolvedExports.clear();
- return HadError;
+ return !Mod->UnresolvedExports.empty();
}
bool ModuleMap::resolveUses(Module *Mod, bool Complain) {
- bool HadError = false;
- for (unsigned I = 0, N = Mod->UnresolvedDirectUses.size(); I != N; ++I) {
- Module *DirectUse =
- resolveModuleId(Mod->UnresolvedDirectUses[I], Mod, Complain);
+ auto Unresolved = std::move(Mod->UnresolvedDirectUses);
+ Mod->UnresolvedDirectUses.clear();
+ for (auto &UDU : Unresolved) {
+ Module *DirectUse = resolveModuleId(UDU, Mod, Complain);
if (DirectUse)
Mod->DirectUses.push_back(DirectUse);
else
- HadError = true;
+ Mod->UnresolvedDirectUses.push_back(UDU);
}
- Mod->UnresolvedDirectUses.clear();
- return HadError;
+ return !Mod->UnresolvedDirectUses.empty();
}
bool ModuleMap::resolveConflicts(Module *Mod, bool Complain) {
- bool HadError = false;
- for (unsigned I = 0, N = Mod->UnresolvedConflicts.size(); I != N; ++I) {
- Module *OtherMod = resolveModuleId(Mod->UnresolvedConflicts[I].Id,
- Mod, Complain);
- if (!OtherMod) {
- HadError = true;
- continue;
- }
-
- Module::Conflict Conflict;
- Conflict.Other = OtherMod;
- Conflict.Message = Mod->UnresolvedConflicts[I].Message;
- Mod->Conflicts.push_back(Conflict);
- }
+ auto Unresolved = std::move(Mod->UnresolvedConflicts);
Mod->UnresolvedConflicts.clear();
- return HadError;
+ for (auto &UC : Unresolved) {
+ if (Module *OtherMod = resolveModuleId(UC.Id, Mod, Complain)) {
+ Module::Conflict Conflict;
+ Conflict.Other = OtherMod;
+ Conflict.Message = UC.Message;
+ Mod->Conflicts.push_back(Conflict);
+ } else
+ Mod->UnresolvedConflicts.push_back(UC);
+ }
+ return !Mod->UnresolvedConflicts.empty();
}
Module *ModuleMap::inferModuleFromLocation(FullSourceLoc Loc) {
@@ -1565,7 +1580,7 @@ void ModuleMapParser::parseExternModuleDecl() {
if (llvm::sys::path::is_relative(FileNameRef)) {
ModuleMapFileName += Directory->getName();
llvm::sys::path::append(ModuleMapFileName, FileName);
- FileNameRef = ModuleMapFileName.str();
+ FileNameRef = ModuleMapFileName;
}
if (const FileEntry *File = SourceMgr.getFileManager().getFile(FileNameRef))
Map.parseModuleMapFile(
@@ -1712,7 +1727,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// Check whether this file is in the public headers.
llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName.str());
+ llvm::sys::path::append(FullPathName, RelativePathName);
File = SourceMgr.getFileManager().getFile(FullPathName);
if (!File) {
@@ -1722,13 +1737,13 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
FullPathName.resize(FullPathLength);
llvm::sys::path::append(RelativePathName, "PrivateHeaders",
Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName.str());
+ llvm::sys::path::append(FullPathName, RelativePathName);
File = SourceMgr.getFileManager().getFile(FullPathName);
}
} else {
// Lookup for normal headers.
llvm::sys::path::append(RelativePathName, Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName.str());
+ llvm::sys::path::append(FullPathName, RelativePathName);
File = SourceMgr.getFileManager().getFile(FullPathName);
// If this is a system module with a top-level header, this header
@@ -1744,7 +1759,13 @@ 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).
- if (!File && BuiltinFile) {
+ //
+ // 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)) {
File = BuiltinFile;
RelativePathName = BuiltinPathName;
BuiltinFile = nullptr;
@@ -1764,7 +1785,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
HadError = true;
} else {
// Record this umbrella header.
- Map.setUmbrellaHeader(ActiveModule, File);
+ Map.setUmbrellaHeader(ActiveModule, File, RelativePathName.str());
}
} else if (LeadingToken == MMToken::ExcludeKeyword) {
Module::Header H = {RelativePathName.str(), File};
@@ -1846,7 +1867,7 @@ void ModuleMapParser::parseUmbrellaDirDecl(SourceLocation UmbrellaLoc) {
}
// Record this umbrella directory.
- Map.setUmbrellaDir(ActiveModule, Dir);
+ Map.setUmbrellaDir(ActiveModule, Dir, DirName);
}
/// \brief Parse a module export declaration.
@@ -1897,18 +1918,21 @@ void ModuleMapParser::parseExportDecl() {
ActiveModule->UnresolvedExports.push_back(Unresolved);
}
-/// \brief Parse a module uses declaration.
+/// \brief Parse a module use declaration.
///
-/// uses-declaration:
-/// 'uses' wildcard-module-id
+/// use-declaration:
+/// 'use' wildcard-module-id
void ModuleMapParser::parseUseDecl() {
assert(Tok.is(MMToken::UseKeyword));
- consumeToken();
+ auto KWLoc = consumeToken();
// Parse the module-id.
ModuleId ParsedModuleId;
parseModuleId(ParsedModuleId);
- ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
+ if (ActiveModule->Parent)
+ Diags.Report(KWLoc, diag::err_mmap_use_decl_submodule);
+ else
+ ActiveModule->UnresolvedDirectUses.push_back(ParsedModuleId);
}
/// \brief Parse a link declaration.
diff --git a/lib/Lex/PPConditionalDirectiveRecord.cpp b/lib/Lex/PPConditionalDirectiveRecord.cpp
index 99b87a0a1525..12a77849b8b3 100644
--- a/lib/Lex/PPConditionalDirectiveRecord.cpp
+++ b/lib/Lex/PPConditionalDirectiveRecord.cpp
@@ -84,14 +84,14 @@ void PPConditionalDirectiveRecord::If(SourceLocation Loc,
void PPConditionalDirectiveRecord::Ifdef(SourceLocation Loc,
const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.push_back(Loc);
}
void PPConditionalDirectiveRecord::Ifndef(SourceLocation Loc,
const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
addCondDirectiveLoc(CondDirectiveLoc(Loc, CondDirectiveStack.back()));
CondDirectiveStack.push_back(Loc);
}
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index bf0ce72f6668..ec06e790f018 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -62,26 +62,14 @@ MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L,
return MI;
}
-DefMacroDirective *
-Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc,
- unsigned ImportedFromModuleID,
- ArrayRef<unsigned> Overrides) {
- unsigned NumExtra = (ImportedFromModuleID ? 1 : 0) + Overrides.size();
- return new (BP.Allocate(sizeof(DefMacroDirective) +
- sizeof(unsigned) * NumExtra,
- llvm::alignOf<DefMacroDirective>()))
- DefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides);
+DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI,
+ SourceLocation Loc) {
+ return new (BP) DefMacroDirective(MI, Loc);
}
UndefMacroDirective *
-Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc,
- unsigned ImportedFromModuleID,
- ArrayRef<unsigned> Overrides) {
- unsigned NumExtra = (ImportedFromModuleID ? 1 : 0) + Overrides.size();
- return new (BP.Allocate(sizeof(UndefMacroDirective) +
- sizeof(unsigned) * NumExtra,
- llvm::alignOf<UndefMacroDirective>()))
- UndefMacroDirective(UndefLoc, ImportedFromModuleID, Overrides);
+Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) {
+ return new (BP) UndefMacroDirective(UndefLoc);
}
VisibilityMacroDirective *
@@ -182,11 +170,13 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
return Diag(MacroNameTok, diag::err_defined_macro_name);
}
- if (isDefineUndef == MU_Undef && II->hasMacroDefinition() &&
- getMacroInfo(II)->isBuiltinMacro()) {
- // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
- // and C++ [cpp.predefined]p4], but allow it as an extension.
- Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
+ if (isDefineUndef == MU_Undef) {
+ auto *MI = getMacroInfo(II);
+ if (MI && MI->isBuiltinMacro()) {
+ // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
+ // and C++ [cpp.predefined]p4], but allow it as an extension.
+ Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
+ }
}
// If defining/undefining reserved identifier or a keyword, we need to issue
@@ -585,16 +575,16 @@ void Preprocessor::PTHSkipExcludedConditionalBlock() {
}
}
-Module *Preprocessor::getModuleForLocation(SourceLocation FilenameLoc) {
+Module *Preprocessor::getModuleForLocation(SourceLocation Loc) {
ModuleMap &ModMap = HeaderInfo.getModuleMap();
- if (SourceMgr.isInMainFile(FilenameLoc)) {
+ if (SourceMgr.isInMainFile(Loc)) {
if (Module *CurMod = getCurrentModule())
return CurMod; // Compiling a module.
return HeaderInfo.getModuleMap().SourceModule; // Compiling a source.
}
// Try to determine the module of the include directive.
// FIXME: Look into directly passing the FileEntry from LookupFile instead.
- FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(FilenameLoc));
+ FileID IDOfIncl = SourceMgr.getFileID(SourceMgr.getExpansionLoc(Loc));
if (const FileEntry *EntryOfIncl = SourceMgr.getFileEntryForID(IDOfIncl)) {
// The include comes from a file.
return ModMap.findModuleForHeader(EntryOfIncl).getModule();
@@ -605,6 +595,11 @@ Module *Preprocessor::getModuleForLocation(SourceLocation FilenameLoc) {
}
}
+Module *Preprocessor::getModuleContainingLocation(SourceLocation Loc) {
+ return HeaderInfo.getModuleMap().inferModuleFromLocation(
+ FullSourceLoc(Loc, SourceMgr));
+}
+
const FileEntry *Preprocessor::LookupFile(
SourceLocation FilenameLoc,
StringRef Filename,
@@ -1233,7 +1228,7 @@ void Preprocessor::HandleUserDiagnosticDirective(Token &Tok,
// Find the first non-whitespace character, so that we can make the
// diagnostic more succinct.
- StringRef Msg = Message.str().ltrim(" ");
+ StringRef Msg = StringRef(Message).ltrim(" ");
if (isWarning)
Diag(Tok, diag::pp_hash_warning) << Msg;
@@ -1290,7 +1285,7 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) {
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
// Okay, we finally have a valid identifier to undef.
- MacroDirective *MD = getMacroDirective(II);
+ MacroDirective *MD = getLocalMacroDirective(II);
// If the macro is not defined, this is an error.
if (!MD) {
@@ -1317,7 +1312,7 @@ void Preprocessor::HandleMacroPrivateDirective(Token &Tok) {
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
// Okay, we finally have a valid identifier to undef.
- MacroDirective *MD = getMacroDirective(II);
+ MacroDirective *MD = getLocalMacroDirective(II);
// If the macro is not defined, this is an error.
if (!MD) {
@@ -1444,6 +1439,8 @@ bool Preprocessor::ConcatenateIncludeName(SmallString<128> &FilenameBuffer,
static void EnterAnnotationToken(Preprocessor &PP,
SourceLocation Begin, SourceLocation End,
tok::TokenKind Kind, void *AnnotationVal) {
+ // FIXME: Produce this as the current token directly, rather than
+ // allocating a new token for it.
Token *Tok = new Token[1];
Tok[0].startToken();
Tok[0].setKind(Kind);
@@ -1453,6 +1450,51 @@ static void EnterAnnotationToken(Preprocessor &PP,
PP.EnterTokenStream(Tok, 1, true, true);
}
+/// \brief Produce a diagnostic informing the user that a #include or similar
+/// was implicitly treated as a module import.
+static void diagnoseAutoModuleImport(
+ Preprocessor &PP, SourceLocation HashLoc, Token &IncludeTok,
+ ArrayRef<std::pair<IdentifierInfo *, SourceLocation>> Path,
+ SourceLocation PathEnd) {
+ assert(PP.getLangOpts().ObjC2 && "no import syntax available");
+
+ SmallString<128> PathString;
+ for (unsigned I = 0, N = Path.size(); I != N; ++I) {
+ if (I)
+ PathString += '.';
+ PathString += Path[I].first->getName();
+ }
+ int IncludeKind = 0;
+
+ switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
+ case tok::pp_include:
+ IncludeKind = 0;
+ break;
+
+ case tok::pp_import:
+ IncludeKind = 1;
+ break;
+
+ case tok::pp_include_next:
+ IncludeKind = 2;
+ break;
+
+ case tok::pp___include_macros:
+ IncludeKind = 3;
+ break;
+
+ default:
+ llvm_unreachable("unknown include directive kind");
+ }
+
+ CharSourceRange ReplaceRange(SourceRange(HashLoc, PathEnd),
+ /*IsTokenRange=*/false);
+ PP.Diag(HashLoc, diag::warn_auto_module_import)
+ << IncludeKind << PathString
+ << FixItHint::CreateReplacement(ReplaceRange,
+ ("@import " + PathString + ";").str());
+}
+
/// HandleIncludeDirective - The "\#include" tokens have just been read, read
/// the file to be included from the lexer, then include it! This is a common
/// routine with functionality shared between \#include, \#include_next and
@@ -1491,7 +1533,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FilenameBuffer.push_back('<');
if (ConcatenateIncludeName(FilenameBuffer, End))
return; // Found <eod> but no ">"? Diagnostic already emitted.
- Filename = FilenameBuffer.str();
+ Filename = FilenameBuffer;
CharEnd = End.getLocWithOffset(1);
break;
default:
@@ -1563,8 +1605,8 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,
HeaderInfo.getHeaderSearchOpts().ModuleMaps ? &SuggestedModule : nullptr);
- if (Callbacks) {
- if (!File) {
+ if (!File) {
+ if (Callbacks) {
// Give the clients a chance to recover.
SmallString<128> RecoveryPath;
if (Callbacks->FileNotFound(Filename, RecoveryPath)) {
@@ -1584,18 +1626,7 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
}
}
}
-
- if (!SuggestedModule || !getLangOpts().Modules) {
- // Notify the callback object that we've seen an inclusion directive.
- Callbacks->InclusionDirective(HashLoc, IncludeTok,
- LangOpts.MSVCCompat ? NormalizedPath.c_str()
- : Filename,
- isAngled, FilenameRange, File, SearchPath,
- RelativePath, /*ImportedModule=*/nullptr);
- }
- }
- if (!File) {
if (!SuppressIncludeNotFoundError) {
// If the file could not be located and it was included via angle
// brackets, we can attempt a lookup as though it were a quoted path to
@@ -1616,19 +1647,27 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FixItHint::CreateReplacement(Range, "\"" + Filename.str() + "\"");
}
}
+
// If the file is still not found, just go with the vanilla diagnostic
if (!File)
Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
}
- if (!File)
- return;
}
- // If we are supposed to import a module rather than including the header,
- // do so now.
- if (SuggestedModule && getLangOpts().Modules &&
+ // Should we enter the source file? Set to false if either the source file is
+ // known to have no effect beyond its effect on module visibility -- that is,
+ // if it's got an include guard that is already defined or is a modular header
+ // we've imported or already built.
+ bool ShouldEnter = true;
+
+ // Determine whether we should try to import the module for this #include, if
+ // there is one. Don't do so if precompiled module support is disabled or we
+ // are processing this module textually (because we're building the module).
+ if (File && SuggestedModule && getLangOpts().Modules &&
SuggestedModule.getModule()->getTopLevelModuleName() !=
- getLangOpts().ImplementationOfModule) {
+ getLangOpts().CurrentModule &&
+ SuggestedModule.getModule()->getTopLevelModuleName() !=
+ getLangOpts().ImplementationOfModule) {
// Compute the module access path corresponding to this module.
// FIXME: Should we have a second loadModule() overload to avoid this
// extra lookup step?
@@ -1639,111 +1678,57 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
std::reverse(Path.begin(), Path.end());
// Warn that we're replacing the include/import with a module import.
- SmallString<128> PathString;
- for (unsigned I = 0, N = Path.size(); I != N; ++I) {
- if (I)
- PathString += '.';
- PathString += Path[I].first->getName();
- }
- int IncludeKind = 0;
-
- switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
- case tok::pp_include:
- IncludeKind = 0;
- break;
-
- case tok::pp_import:
- IncludeKind = 1;
- break;
-
- case tok::pp_include_next:
- IncludeKind = 2;
- break;
-
- case tok::pp___include_macros:
- IncludeKind = 3;
- break;
-
- default:
- llvm_unreachable("unknown include directive kind");
- }
-
- // Determine whether we are actually building the module that this
- // include directive maps to.
- bool BuildingImportedModule
- = Path[0].first->getName() == getLangOpts().CurrentModule;
-
- if (!BuildingImportedModule && getLangOpts().ObjC2) {
- // If we're not building the imported module, warn that we're going
- // to automatically turn this inclusion directive into a module import.
- // We only do this in Objective-C, where we have a module-import syntax.
- CharSourceRange ReplaceRange(SourceRange(HashLoc, CharEnd),
- /*IsTokenRange=*/false);
- Diag(HashLoc, diag::warn_auto_module_import)
- << IncludeKind << PathString
- << FixItHint::CreateReplacement(ReplaceRange,
- "@import " + PathString.str().str() + ";");
- }
+ // We only do this in Objective-C, where we have a module-import syntax.
+ if (getLangOpts().ObjC2)
+ diagnoseAutoModuleImport(*this, HashLoc, IncludeTok, Path, CharEnd);
- // Load the module. Only make macros visible. We'll make the declarations
+ // Load the module to import its macros. We'll make the declarations
// visible when the parser gets here.
- Module::NameVisibilityKind Visibility = Module::MacrosVisible;
- ModuleLoadResult Imported
- = TheModuleLoader.loadModule(IncludeTok.getLocation(), Path, Visibility,
- /*IsIncludeDirective=*/true);
+ // FIXME: Pass SuggestedModule in here rather than converting it to a path
+ // and making the module loader convert it back again.
+ ModuleLoadResult Imported = TheModuleLoader.loadModule(
+ IncludeTok.getLocation(), Path, Module::Hidden,
+ /*IsIncludeDirective=*/true);
assert((Imported == nullptr || Imported == SuggestedModule.getModule()) &&
"the imported module is different than the suggested one");
- if (!Imported && hadModuleLoaderFatalFailure()) {
- // With a fatal failure in the module loader, we abort parsing.
- Token &Result = IncludeTok;
- if (CurLexer) {
- Result.startToken();
- CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
- CurLexer->cutOffLexing();
- } else {
- assert(CurPTHLexer && "#include but no current lexer set!");
- CurPTHLexer->getEOF(Result);
- }
- return;
- }
-
- // If this header isn't part of the module we're building, we're done.
- if (!BuildingImportedModule && Imported) {
- if (Callbacks) {
- Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
- FilenameRange, File,
- SearchPath, RelativePath, Imported);
- }
-
- if (IncludeKind != 3) {
- // Let the parser know that we hit a module import, and it should
- // make the module visible.
- // FIXME: Produce this as the current token directly, rather than
- // allocating a new token for it.
- EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include,
- Imported);
+ if (Imported)
+ ShouldEnter = false;
+ 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
+ // incomplete). Treat this as a textual inclusion.
+ SuggestedModule = ModuleMap::KnownHeader();
+ } else {
+ // We hit an error processing the import. Bail out.
+ if (hadModuleLoaderFatalFailure()) {
+ // With a fatal failure in the module loader, we abort parsing.
+ Token &Result = IncludeTok;
+ if (CurLexer) {
+ Result.startToken();
+ CurLexer->FormTokenWithChars(Result, CurLexer->BufferEnd, tok::eof);
+ CurLexer->cutOffLexing();
+ } else {
+ assert(CurPTHLexer && "#include but no current lexer set!");
+ CurPTHLexer->getEOF(Result);
+ }
}
return;
}
-
- // If we failed to find a submodule that we expected to find, we can
- // continue. Otherwise, there's an error in the included file, so we
- // don't want to include it.
- if (!BuildingImportedModule && !Imported.isMissingExpected()) {
- return;
- }
}
- if (Callbacks && SuggestedModule) {
- // We didn't notify the callback object that we've seen an inclusion
- // directive before. Now that we are parsing the include normally and not
- // turning it to a module import, notify the callback object.
- Callbacks->InclusionDirective(HashLoc, IncludeTok, Filename, isAngled,
- FilenameRange, File,
- SearchPath, RelativePath,
- /*ImportedModule=*/nullptr);
+ if (Callbacks) {
+ // Notify the callback object that we've seen an inclusion directive.
+ Callbacks->InclusionDirective(
+ HashLoc, IncludeTok,
+ LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
+ FilenameRange, File, SearchPath, RelativePath,
+ ShouldEnter ? nullptr : SuggestedModule.getModule());
}
+
+ if (!File)
+ return;
// The #included file will be considered to be a system header if either it is
// in a system include directory, or if the #includer is a system include
@@ -1752,11 +1737,28 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
std::max(HeaderInfo.getFileDirFlavor(File),
SourceMgr.getFileCharacteristic(FilenameTok.getLocation()));
+ // FIXME: If we have a suggested module, and we've already visited this file,
+ // don't bother entering it again. We know it has no further effect.
+
// Ask HeaderInfo if we should enter this #include file. If not, #including
// this file will have no effect.
- if (!HeaderInfo.ShouldEnterIncludeFile(File, isImport)) {
+ if (ShouldEnter &&
+ !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport)) {
+ ShouldEnter = false;
if (Callbacks)
Callbacks->FileSkipped(*File, FilenameTok, FileCharacter);
+ }
+
+ // If we don't need to enter the file, stop now.
+ if (!ShouldEnter) {
+ // If this is a module import, make it visible if needed.
+ if (auto *M = SuggestedModule.getModule()) {
+ makeModuleVisible(M, HashLoc);
+
+ if (IncludeTok.getIdentifierInfo()->getPPKeywordID() !=
+ tok::pp___include_macros)
+ EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_include, M);
+ }
return;
}
@@ -1769,26 +1771,24 @@ void Preprocessor::HandleIncludeDirective(SourceLocation HashLoc,
FileID FID = SourceMgr.createFileID(File, IncludePos, FileCharacter);
assert(!FID.isInvalid() && "Expected valid file ID");
- // Determine if we're switching to building a new submodule, and which one.
- ModuleMap::KnownHeader BuildingModule;
- if (getLangOpts().Modules && !getLangOpts().CurrentModule.empty()) {
- Module *RequestingModule = getModuleForLocation(FilenameLoc);
- BuildingModule =
- HeaderInfo.getModuleMap().findModuleForHeader(File, RequestingModule);
- }
-
// If all is good, enter the new file!
if (EnterSourceFile(FID, CurDir, FilenameTok.getLocation()))
return;
- // If we're walking into another part of the same module, let the parser
- // know that any future declarations are within that other submodule.
- if (BuildingModule) {
+ // Determine if we're switching to building a new submodule, and which one.
+ if (auto *M = SuggestedModule.getModule()) {
assert(!CurSubmodule && "should not have marked this as a module yet");
- CurSubmodule = BuildingModule.getModule();
+ CurSubmodule = M;
- EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin,
- CurSubmodule);
+ // Let the macro handling code know that any future macros are within
+ // the new submodule.
+ EnterSubmodule(M, HashLoc);
+
+ // Let the parser know that any future declarations are within the new
+ // submodule.
+ // FIXME: There's no point doing this if we're handling a #__include_macros
+ // directive.
+ EnterAnnotationToken(*this, HashLoc, End, tok::annot_module_begin, M);
}
}
@@ -2290,9 +2290,9 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) {
// Check to see if this is the last token on the #undef line.
CheckEndOfDirective("undef");
- // Okay, we finally have a valid identifier to undef.
- MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo());
- const MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr;
+ // Okay, we have a valid identifier to undef.
+ auto *II = MacroNameTok.getIdentifierInfo();
+ auto MD = getMacroDefinition(II);
// If the callbacks want to know, tell them about the macro #undef.
// Note: no matter if the macro was defined or not.
@@ -2300,6 +2300,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) {
Callbacks->MacroUndefined(MacroNameTok, MD);
// If the macro is not defined, this is a noop undef, just return.
+ const MacroInfo *MI = MD.getMacroInfo();
if (!MI)
return;
@@ -2344,8 +2345,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
CheckEndOfDirective(isIfndef ? "ifndef" : "ifdef");
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
- MacroDirective *MD = getMacroDirective(MII);
- MacroInfo *MI = MD ? MD->getMacroInfo() : nullptr;
+ auto MD = getMacroDefinition(MII);
+ MacroInfo *MI = MD.getMacroInfo();
if (CurPPLexer->getConditionalStackDepth() == 0) {
// If the start of a top-level #ifdef and if the macro is not defined,
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 9cf72cf8f8fb..44513023395d 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -108,15 +108,13 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
// Otherwise, we got an identifier, is it defined to something?
IdentifierInfo *II = PeekTok.getIdentifierInfo();
- Result.Val = II->hasMacroDefinition();
- Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
+ MacroDefinition Macro = PP.getMacroDefinition(II);
+ Result.Val = !!Macro;
+ Result.Val.setIsUnsigned(false); // Result is signed intmax_t.
- MacroDirective *Macro = nullptr;
// If there is a macro, mark it used.
- if (Result.Val != 0 && ValueLive) {
- Macro = PP.getMacroDirective(II);
- PP.markMacroAsUsed(Macro->getMacroInfo());
- }
+ if (Result.Val != 0 && ValueLive)
+ PP.markMacroAsUsed(Macro.getMacroInfo());
// Save macro token for callback.
Token macroToken(PeekTok);
@@ -144,11 +142,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
// Invoke the 'defined' callback.
if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
- MacroDirective *MD = Macro;
- // Pass the MacroInfo for the macro name even if the value is dead.
- if (!MD && Result.Val != 0)
- MD = PP.getMacroDirective(II);
- Callbacks->Defined(macroToken, MD,
+ Callbacks->Defined(macroToken, Macro,
SourceRange(beginLoc, PeekTok.getLocation()));
}
@@ -310,7 +304,9 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
// Set the value.
Val = Literal.getValue();
// Set the signedness. UTF-16 and UTF-32 are always unsigned
- if (!Literal.isUTF16() && !Literal.isUTF32())
+ if (Literal.isWide())
+ Val.setIsUnsigned(!TargetInfo::isTypeSigned(TI.getWCharType()));
+ else if (!Literal.isUTF16() && !Literal.isUTF32())
Val.setIsUnsigned(!PP.getLangOpts().CharIsSigned);
if (Result.Val.getBitWidth() > Val.getBitWidth()) {
@@ -732,8 +728,7 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
/// EvaluateDirectiveExpression - Evaluate an integer constant expression that
/// may occur after a #if or #elif directive. If the expression is equivalent
/// to "!defined(X)" return X in IfNDefMacro.
-bool Preprocessor::
-EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
+bool Preprocessor::EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
SaveAndRestore<bool> PPDir(ParsingIfOrElifDirective, true);
// Save the current state of 'DisableMacroExpansion' and reset it to false. If
// 'DisableMacroExpansion' is true, then we must be in a macro argument list
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index fb5e2b05808c..e68fb7df8e88 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -309,7 +309,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
}
if (const IdentifierInfo *DefinedMacro =
CurPPLexer->MIOpt.GetDefinedMacro()) {
- if (!ControllingMacro->hasMacroDefinition() &&
+ if (!isMacroDefined(ControllingMacro) &&
DefinedMacro != ControllingMacro &&
HeaderInfo.FirstTimeLexingFile(FE)) {
@@ -400,6 +400,9 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
CurLexer->FormTokenWithChars(Result, EndPos, tok::annot_module_end);
Result.setAnnotationEndLoc(Result.getLocation());
Result.setAnnotationValue(CurSubmodule);
+
+ // We're done with this submodule.
+ LeaveSubmodule();
}
// We're done with the #included file.
@@ -471,7 +474,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header,
StartLoc)) {
ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
- const DirectoryEntry *Dir = Mod->getUmbrellaDir();
+ const DirectoryEntry *Dir = Mod->getUmbrellaDir().Entry;
vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
std::error_code EC;
for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End;
@@ -605,3 +608,126 @@ void Preprocessor::HandleMicrosoftCommentPaste(Token &Tok) {
// preprocessor directive mode), so just return EOF as our token.
assert(!FoundLexer && "Lexer should return EOD before EOF in PP mode");
}
+
+void Preprocessor::EnterSubmodule(Module *M, SourceLocation ImportLoc) {
+ if (!getLangOpts().ModulesLocalVisibility) {
+ // Just track that we entered this submodule.
+ BuildingSubmoduleStack.push_back(
+ BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState));
+ return;
+ }
+
+ // Resolve as much of the module definition as we can now, before we enter
+ // one of its headers.
+ // FIXME: Can we enable Complain here?
+ // FIXME: Can we do this when local visibility is disabled?
+ ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
+ ModMap.resolveExports(M, /*Complain=*/false);
+ ModMap.resolveUses(M, /*Complain=*/false);
+ ModMap.resolveConflicts(M, /*Complain=*/false);
+
+ // If this is the first time we've entered this module, set up its state.
+ auto R = Submodules.insert(std::make_pair(M, SubmoduleState()));
+ auto &State = R.first->second;
+ bool FirstTime = R.second;
+ if (FirstTime) {
+ // Determine the set of starting macros for this submodule; take these
+ // from the "null" module (the predefines buffer).
+ auto &StartingMacros = NullSubmoduleState.Macros;
+
+ // Restore to the starting state.
+ // FIXME: Do this lazily, when each macro name is first referenced.
+ for (auto &Macro : StartingMacros) {
+ MacroState MS(Macro.second.getLatest());
+ MS.setOverriddenMacros(*this, Macro.second.getOverriddenMacros());
+ State.Macros.insert(std::make_pair(Macro.first, std::move(MS)));
+ }
+ }
+
+ // Track that we entered this module.
+ BuildingSubmoduleStack.push_back(
+ BuildingSubmoduleInfo(M, ImportLoc, CurSubmoduleState));
+
+ // Switch to this submodule as the current submodule.
+ CurSubmoduleState = &State;
+
+ // This module is visible to itself.
+ if (FirstTime)
+ makeModuleVisible(M, ImportLoc);
+}
+
+void Preprocessor::LeaveSubmodule() {
+ auto &Info = BuildingSubmoduleStack.back();
+
+ Module *LeavingMod = Info.M;
+ SourceLocation ImportLoc = Info.ImportLoc;
+
+ // Create ModuleMacros for any macros defined in this submodule.
+ for (auto &Macro : CurSubmoduleState->Macros) {
+ auto *II = const_cast<IdentifierInfo*>(Macro.first);
+
+ // Find the starting point for the MacroDirective chain in this submodule.
+ MacroDirective *OldMD = nullptr;
+ if (getLangOpts().ModulesLocalVisibility) {
+ // FIXME: It'd be better to start at the state from when we most recently
+ // entered this submodule, but it doesn't really matter.
+ auto &PredefMacros = NullSubmoduleState.Macros;
+ auto PredefMacroIt = PredefMacros.find(Macro.first);
+ if (PredefMacroIt == PredefMacros.end())
+ OldMD = nullptr;
+ else
+ OldMD = PredefMacroIt->second.getLatest();
+ }
+
+ // This module may have exported a new macro. If so, create a ModuleMacro
+ // representing that fact.
+ bool ExplicitlyPublic = false;
+ for (auto *MD = Macro.second.getLatest(); MD != OldMD;
+ MD = MD->getPrevious()) {
+ assert(MD && "broken macro directive chain");
+
+ // Stop on macros defined in other submodules we #included along the way.
+ // There's no point doing this if we're tracking local submodule
+ // visibility, since there can be no such directives in our list.
+ if (!getLangOpts().ModulesLocalVisibility) {
+ Module *Mod = getModuleContainingLocation(MD->getLocation());
+ if (Mod != LeavingMod)
+ break;
+ }
+
+ if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
+ // The latest visibility directive for a name in a submodule affects
+ // all the directives that come before it.
+ if (VisMD->isPublic())
+ ExplicitlyPublic = true;
+ else if (!ExplicitlyPublic)
+ // Private with no following public directive: not exported.
+ break;
+ } else {
+ MacroInfo *Def = nullptr;
+ if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
+ Def = DefMD->getInfo();
+
+ // FIXME: Issue a warning if multiple headers for the same submodule
+ // define a macro, rather than silently ignoring all but the first.
+ bool IsNew;
+ // Don't bother creating a module macro if it would represent a #undef
+ // that doesn't override anything.
+ if (Def || !Macro.second.getOverriddenMacros().empty())
+ addModuleMacro(LeavingMod, II, Def,
+ Macro.second.getOverriddenMacros(), IsNew);
+ break;
+ }
+ }
+ }
+
+ // Put back the outer module's state, if we're tracking it.
+ if (getLangOpts().ModulesLocalVisibility)
+ CurSubmoduleState = Info.OuterSubmoduleState;
+
+ BuildingSubmoduleStack.pop_back();
+
+ // A nested #include makes the included submodule visible.
+ if (!BuildingSubmoduleStack.empty() || !getLangOpts().ModulesLocalVisibility)
+ makeModuleVisible(LeavingMod, ImportLoc);
+}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index cd05d06633f2..9046ad51c14a 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -34,44 +34,234 @@
using namespace clang;
MacroDirective *
-Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const {
- assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
-
- macro_iterator Pos = Macros.find(II);
- assert(Pos != Macros.end() && "Identifier macro info is missing!");
- return Pos->second;
+Preprocessor::getLocalMacroDirectiveHistory(const IdentifierInfo *II) const {
+ if (!II->hadMacroDefinition())
+ return nullptr;
+ auto Pos = CurSubmoduleState->Macros.find(II);
+ return Pos == CurSubmoduleState->Macros.end() ? nullptr
+ : Pos->second.getLatest();
}
void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
assert(MD && "MacroDirective should be non-zero!");
assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
- MacroDirective *&StoredMD = Macros[II];
- MD->setPrevious(StoredMD);
- StoredMD = MD;
- // Setup the identifier as having associated macro history.
+ MacroState &StoredMD = CurSubmoduleState->Macros[II];
+ auto *OldMD = StoredMD.getLatest();
+ MD->setPrevious(OldMD);
+ StoredMD.setLatest(MD);
+ StoredMD.overrideActiveModuleMacros(*this, II);
+
+ // Set up the identifier as having associated macro history.
II->setHasMacroDefinition(true);
- if (!MD->isDefined())
+ if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
II->setHasMacroDefinition(false);
- bool isImportedMacro = isa<DefMacroDirective>(MD) &&
- cast<DefMacroDirective>(MD)->isImported();
- if (II->isFromAST() && !isImportedMacro)
+ if (II->isFromAST())
II->setChangedSinceDeserialization();
}
void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
MacroDirective *MD) {
assert(II && MD);
- MacroDirective *&StoredMD = Macros[II];
- assert(!StoredMD &&
+ MacroState &StoredMD = CurSubmoduleState->Macros[II];
+ assert(!StoredMD.getLatest() &&
"the macro history was modified before initializing it from a pch");
StoredMD = MD;
// Setup the identifier as having associated macro history.
II->setHasMacroDefinition(true);
- if (!MD->isDefined())
+ if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
II->setHasMacroDefinition(false);
}
+ModuleMacro *Preprocessor::addModuleMacro(Module *Mod, IdentifierInfo *II,
+ MacroInfo *Macro,
+ ArrayRef<ModuleMacro *> Overrides,
+ bool &New) {
+ llvm::FoldingSetNodeID ID;
+ ModuleMacro::Profile(ID, Mod, II);
+
+ void *InsertPos;
+ if (auto *MM = ModuleMacros.FindNodeOrInsertPos(ID, InsertPos)) {
+ New = false;
+ return MM;
+ }
+
+ auto *MM = ModuleMacro::create(*this, Mod, II, Macro, Overrides);
+ ModuleMacros.InsertNode(MM, InsertPos);
+
+ // Each overridden macro is now overridden by one more macro.
+ bool HidAny = false;
+ for (auto *O : Overrides) {
+ HidAny |= (O->NumOverriddenBy == 0);
+ ++O->NumOverriddenBy;
+ }
+
+ // If we were the first overrider for any macro, it's no longer a leaf.
+ auto &LeafMacros = LeafModuleMacros[II];
+ if (HidAny) {
+ LeafMacros.erase(std::remove_if(LeafMacros.begin(), LeafMacros.end(),
+ [](ModuleMacro *MM) {
+ return MM->NumOverriddenBy != 0;
+ }),
+ LeafMacros.end());
+ }
+
+ // The new macro is always a leaf macro.
+ LeafMacros.push_back(MM);
+ // The identifier now has defined macros (that may or may not be visible).
+ II->setHasMacroDefinition(true);
+
+ New = true;
+ return MM;
+}
+
+ModuleMacro *Preprocessor::getModuleMacro(Module *Mod, IdentifierInfo *II) {
+ llvm::FoldingSetNodeID ID;
+ ModuleMacro::Profile(ID, Mod, II);
+
+ void *InsertPos;
+ return ModuleMacros.FindNodeOrInsertPos(ID, InsertPos);
+}
+
+void Preprocessor::updateModuleMacroInfo(const IdentifierInfo *II,
+ ModuleMacroInfo &Info) {
+ assert(Info.ActiveModuleMacrosGeneration !=
+ CurSubmoduleState->VisibleModules.getGeneration() &&
+ "don't need to update this macro name info");
+ Info.ActiveModuleMacrosGeneration =
+ CurSubmoduleState->VisibleModules.getGeneration();
+
+ auto Leaf = LeafModuleMacros.find(II);
+ if (Leaf == LeafModuleMacros.end()) {
+ // No imported macros at all: nothing to do.
+ return;
+ }
+
+ Info.ActiveModuleMacros.clear();
+
+ // Every macro that's locally overridden is overridden by a visible macro.
+ llvm::DenseMap<ModuleMacro *, int> NumHiddenOverrides;
+ for (auto *O : Info.OverriddenMacros)
+ NumHiddenOverrides[O] = -1;
+
+ // Collect all macros that are not overridden by a visible macro.
+ llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf->second.begin(),
+ Leaf->second.end());
+ while (!Worklist.empty()) {
+ auto *MM = Worklist.pop_back_val();
+ if (CurSubmoduleState->VisibleModules.isVisible(MM->getOwningModule())) {
+ // We only care about collecting definitions; undefinitions only act
+ // to override other definitions.
+ if (MM->getMacroInfo())
+ Info.ActiveModuleMacros.push_back(MM);
+ } else {
+ for (auto *O : MM->overrides())
+ if ((unsigned)++NumHiddenOverrides[O] == O->getNumOverridingMacros())
+ Worklist.push_back(O);
+ }
+ }
+ // Our reverse postorder walk found the macros in reverse order.
+ std::reverse(Info.ActiveModuleMacros.begin(), Info.ActiveModuleMacros.end());
+
+ // Determine whether the macro name is ambiguous.
+ MacroInfo *MI = nullptr;
+ bool IsSystemMacro = true;
+ bool IsAmbiguous = false;
+ if (auto *MD = Info.MD) {
+ while (MD && isa<VisibilityMacroDirective>(MD))
+ MD = MD->getPrevious();
+ if (auto *DMD = dyn_cast_or_null<DefMacroDirective>(MD)) {
+ MI = DMD->getInfo();
+ IsSystemMacro &= SourceMgr.isInSystemHeader(DMD->getLocation());
+ }
+ }
+ for (auto *Active : Info.ActiveModuleMacros) {
+ auto *NewMI = Active->getMacroInfo();
+
+ // Before marking the macro as ambiguous, check if this is a case where
+ // both macros are in system headers. If so, we trust that the system
+ // did not get it wrong. This also handles cases where Clang's own
+ // headers have a different spelling of certain system macros:
+ // #define LONG_MAX __LONG_MAX__ (clang's limits.h)
+ // #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
+ //
+ // FIXME: Remove the defined-in-system-headers check. clang's limits.h
+ // overrides the system limits.h's macros, so there's no conflict here.
+ if (MI && NewMI != MI &&
+ !MI->isIdenticalTo(*NewMI, *this, /*Syntactically=*/true))
+ IsAmbiguous = true;
+ IsSystemMacro &= Active->getOwningModule()->IsSystem ||
+ SourceMgr.isInSystemHeader(NewMI->getDefinitionLoc());
+ MI = NewMI;
+ }
+ Info.IsAmbiguous = IsAmbiguous && !IsSystemMacro;
+}
+
+void Preprocessor::dumpMacroInfo(const IdentifierInfo *II) {
+ ArrayRef<ModuleMacro*> Leaf;
+ auto LeafIt = LeafModuleMacros.find(II);
+ if (LeafIt != LeafModuleMacros.end())
+ Leaf = LeafIt->second;
+ const MacroState *State = nullptr;
+ auto Pos = CurSubmoduleState->Macros.find(II);
+ if (Pos != CurSubmoduleState->Macros.end())
+ State = &Pos->second;
+
+ llvm::errs() << "MacroState " << State << " " << II->getNameStart();
+ if (State && State->isAmbiguous(*this, II))
+ llvm::errs() << " ambiguous";
+ if (State && !State->getOverriddenMacros().empty()) {
+ llvm::errs() << " overrides";
+ for (auto *O : State->getOverriddenMacros())
+ llvm::errs() << " " << O->getOwningModule()->getFullModuleName();
+ }
+ llvm::errs() << "\n";
+
+ // Dump local macro directives.
+ for (auto *MD = State ? State->getLatest() : nullptr; MD;
+ MD = MD->getPrevious()) {
+ llvm::errs() << " ";
+ MD->dump();
+ }
+
+ // Dump module macros.
+ llvm::DenseSet<ModuleMacro*> Active;
+ for (auto *MM : State ? State->getActiveModuleMacros(*this, II) : None)
+ Active.insert(MM);
+ llvm::DenseSet<ModuleMacro*> Visited;
+ llvm::SmallVector<ModuleMacro *, 16> Worklist(Leaf.begin(), Leaf.end());
+ while (!Worklist.empty()) {
+ auto *MM = Worklist.pop_back_val();
+ llvm::errs() << " ModuleMacro " << MM << " "
+ << MM->getOwningModule()->getFullModuleName();
+ if (!MM->getMacroInfo())
+ llvm::errs() << " undef";
+
+ if (Active.count(MM))
+ llvm::errs() << " active";
+ else if (!CurSubmoduleState->VisibleModules.isVisible(
+ MM->getOwningModule()))
+ llvm::errs() << " hidden";
+ else if (MM->getMacroInfo())
+ llvm::errs() << " overridden";
+
+ if (!MM->overrides().empty()) {
+ llvm::errs() << " overrides";
+ for (auto *O : MM->overrides()) {
+ llvm::errs() << " " << O->getOwningModule()->getFullModuleName();
+ if (Visited.insert(O).second)
+ Worklist.push_back(O);
+ }
+ }
+ llvm::errs() << "\n";
+ if (auto *MI = MM->getMacroInfo()) {
+ llvm::errs() << " ";
+ MI->dump();
+ llvm::errs() << "\n";
+ }
+ }
+}
+
/// RegisterBuiltinMacro - Register the specified identifier in the identifier
/// table and mark it as a builtin macro to be expanded.
static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
@@ -97,7 +287,11 @@ void Preprocessor::RegisterBuiltinMacros() {
Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma");
// C++ Standing Document Extensions.
- Ident__has_cpp_attribute = RegisterBuiltinMacro(*this, "__has_cpp_attribute");
+ if (LangOpts.CPlusPlus)
+ Ident__has_cpp_attribute =
+ RegisterBuiltinMacro(*this, "__has_cpp_attribute");
+ else
+ Ident__has_cpp_attribute = nullptr;
// GCC Extensions.
Ident__BASE_FILE__ = RegisterBuiltinMacro(*this, "__BASE_FILE__");
@@ -156,10 +350,11 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
// If the identifier is a macro, and if that macro is enabled, it may be
// expanded so it's not a trivial expansion.
- if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&
- // Fast expanding "#define X X" is ok, because X would be disabled.
- II != MacroIdent)
- return false;
+ if (auto *ExpansionMI = PP.getMacroInfo(II))
+ if (ExpansionMI->isEnabled() &&
+ // Fast expanding "#define X X" is ok, because X would be disabled.
+ II != MacroIdent)
+ return false;
// If this is an object-like macro invocation, it is safe to trivially expand
// it.
@@ -222,10 +417,8 @@ bool Preprocessor::isNextPPTokenLParen() {
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
/// expanded as a macro, handle it and return the next token as 'Identifier'.
bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
- MacroDirective *MD) {
- MacroDirective::DefInfo Def = MD->getDefinition();
- assert(Def.isValid());
- MacroInfo *MI = Def.getMacroInfo();
+ const MacroDefinition &M) {
+ MacroInfo *MI = M.getMacroInfo();
// If this is a macro expansion in the "#if !defined(x)" line for the file,
// then the macro could expand to different things in other contexts, we need
@@ -234,9 +427,9 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
if (MI->isBuiltinMacro()) {
- if (Callbacks) Callbacks->MacroExpands(Identifier, MD,
- Identifier.getLocation(),
- /*Args=*/nullptr);
+ if (Callbacks)
+ Callbacks->MacroExpands(Identifier, M, Identifier.getLocation(),
+ /*Args=*/nullptr);
ExpandBuiltinMacro(Identifier);
return true;
}
@@ -283,9 +476,9 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// MacroExpands callbacks still happen in source order, queue this
// callback to have it happen after the function macro callback.
DelayedMacroExpandsCallbacks.push_back(
- MacroExpandsInfo(Identifier, MD, ExpansionRange));
+ MacroExpandsInfo(Identifier, M, ExpansionRange));
} else {
- Callbacks->MacroExpands(Identifier, MD, ExpansionRange, Args);
+ Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
if (!DelayedMacroExpandsCallbacks.empty()) {
for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
@@ -299,20 +492,16 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
}
// If the macro definition is ambiguous, complain.
- if (Def.getDirective()->isAmbiguous()) {
+ if (M.isAmbiguous()) {
Diag(Identifier, diag::warn_pp_ambiguous_macro)
<< Identifier.getIdentifierInfo();
Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen)
<< Identifier.getIdentifierInfo();
- for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition();
- PrevDef && !PrevDef.isUndefined();
- PrevDef = PrevDef.getPreviousDefinition()) {
- Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
- diag::note_pp_ambiguous_macro_other)
- << Identifier.getIdentifierInfo();
- if (!PrevDef.getDirective()->isAmbiguous())
- break;
- }
+ M.forAllDefinitions([&](const MacroInfo *OtherMI) {
+ if (OtherMI != MI)
+ Diag(OtherMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other)
+ << Identifier.getIdentifierInfo();
+ });
}
// If we started lexing a macro, enter the macro expansion body.
@@ -598,7 +787,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// If this is a comment token in the argument list and we're just in
// -C mode (not -CC mode), discard the comment.
continue;
- } else if (Tok.getIdentifierInfo() != nullptr) {
+ } else if (!Tok.isAnnotation() && Tok.getIdentifierInfo() != nullptr) {
// Reading macro arguments can cause macros that we are currently
// expanding from to be popped off the expansion stack. Doing so causes
// them to be reenabled for expansion. Here we record whether any
@@ -868,6 +1057,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_availability", true)
.Case("attribute_availability_with_message", true)
+ .Case("attribute_availability_app_extension", true)
.Case("attribute_cf_returns_not_retained", true)
.Case("attribute_cf_returns_retained", true)
.Case("attribute_deprecated_with_message", true)
@@ -912,7 +1102,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("objc_dictionary_literals", LangOpts.ObjC2)
.Case("objc_boxed_expressions", LangOpts.ObjC2)
.Case("arc_cf_code_audited", true)
- .Case("objc_bridge_id", LangOpts.ObjC2)
+ .Case("objc_bridge_id", true)
+ .Case("objc_bridge_id_on_typedefs", true)
// C11 features
.Case("c_alignas", LangOpts.C11)
.Case("c_alignof", LangOpts.C11)
@@ -1050,6 +1241,7 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("cxx_range_for", LangOpts.CPlusPlus)
.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.
.Case("cxx_binary_literals", true)
.Case("cxx_init_captures", LangOpts.CPlusPlus11)
@@ -1071,6 +1263,9 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
// These expressions are only allowed within a preprocessor directive.
if (!PP.isParsingIfOrElifDirective()) {
PP.Diag(LParenLoc, diag::err_pp_directive_required) << II->getName();
+ // Return a valid identifier token.
+ assert(Tok.is(tok::identifier));
+ Tok.setIdentifierInfo(II);
return false;
}
@@ -1129,7 +1324,7 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
Tok.setKind(tok::eod);
return false; // Found <eod> but no ">"? Diagnostic already emitted.
}
- Filename = FilenameBuffer.str();
+ Filename = FilenameBuffer;
break;
default:
PP.Diag(Tok.getLocation(), diag::err_pp_expects_filename);
@@ -1179,7 +1374,7 @@ static bool EvaluateHasIncludeNext(Token &Tok,
// __has_include_next is like __has_include, except that we start
// searching after the current found directory. If we can't do this,
// issue a diagnostic.
- // FIXME: Factor out duplication wiht
+ // FIXME: Factor out duplication with
// Preprocessor::HandleIncludeNextDirective.
const DirectoryLookup *Lookup = PP.GetCurDirLookup();
const FileEntry *LookupFromFile = nullptr;
@@ -1312,7 +1507,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
if (PLoc.isValid()) {
FN += PLoc.getFilename();
Lexer::Stringify(FN);
- OS << '"' << FN.str() << '"';
+ OS << '"' << FN << '"';
}
Tok.setKind(tok::string_literal);
} else if (II == Ident__DATE__) {
@@ -1459,9 +1654,11 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Value = EvaluateHasInclude(Tok, II, *this);
else
Value = EvaluateHasIncludeNext(Tok, II, *this);
+
+ if (Tok.isNot(tok::r_paren))
+ return;
OS << (int)Value;
- if (Tok.is(tok::r_paren))
- Tok.setKind(tok::numeric_constant);
+ Tok.setKind(tok::numeric_constant);
} else if (II == Ident__has_warning) {
// The argument should be a parenthesized string literal.
// The argument to these builtins should be a parenthesized identifier.
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 8ed832893771..26ed674f65aa 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -22,6 +22,7 @@
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@@ -400,7 +401,7 @@ void Preprocessor::HandlePragmaPoison(Token &PoisonTok) {
if (II->isPoisoned()) continue;
// If this is a macro identifier, emit a warning.
- if (II->hasMacroDefinition())
+ if (isMacroDefined(II))
Diag(Tok, diag::pp_poisoning_existing_macro);
// Finally, poison it!
@@ -590,8 +591,7 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
PragmaPushMacroInfo.find(IdentInfo);
if (iter != PragmaPushMacroInfo.end()) {
// Forget the MacroInfo currently associated with IdentInfo.
- if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) {
- MacroInfo *MI = CurrentMD->getMacroInfo();
+ if (MacroInfo *MI = getMacroInfo(IdentInfo)) {
if (MI->isWarnIfUnused())
WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc));
@@ -600,11 +600,9 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
// Get the MacroInfo we want to reinstall.
MacroInfo *MacroToReInstall = iter->second.back();
- if (MacroToReInstall) {
+ if (MacroToReInstall)
// Reinstall the previously pushed macro.
- appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc,
- /*isImported=*/false, /*Overrides*/None);
- }
+ appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc);
// Pop PragmaPushMacroInfo stack.
iter->second.pop_back();
@@ -648,7 +646,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
SourceLocation End;
if (ConcatenateIncludeName(FileNameBuffer, End))
return; // Diagnostic already emitted
- SourceFileName = FileNameBuffer.str();
+ SourceFileName = FileNameBuffer;
} else {
Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
return;
@@ -679,7 +677,7 @@ void Preprocessor::HandlePragmaIncludeAlias(Token &Tok) {
SourceLocation End;
if (ConcatenateIncludeName(FileNameBuffer, End))
return; // Diagnostic already emitted
- ReplaceFileName = FileNameBuffer.str();
+ ReplaceFileName = FileNameBuffer;
} else {
Diag(Tok, diag::warn_pragma_include_alias_expected_filename);
return;
@@ -870,12 +868,22 @@ struct PragmaDebugHandler : public PragmaHandler {
LLVM_BUILTIN_TRAP;
} else if (II->isStr("parser_crash")) {
Token Crasher;
+ Crasher.startToken();
Crasher.setKind(tok::annot_pragma_parser_crash);
+ Crasher.setAnnotationRange(SourceRange(Tok.getLocation()));
PP.EnterToken(Crasher);
} else if (II->isStr("llvm_fatal_error")) {
llvm::report_fatal_error("#pragma clang __debug llvm_fatal_error");
} else if (II->isStr("llvm_unreachable")) {
llvm_unreachable("#pragma clang __debug llvm_unreachable");
+ } else if (II->isStr("macro")) {
+ Token MacroName;
+ PP.LexUnexpandedToken(MacroName);
+ auto *MacroII = MacroName.getIdentifierInfo();
+ if (MacroII)
+ PP.dumpMacroInfo(MacroII);
+ else
+ PP.Diag(MacroName, diag::warn_pragma_diagnostic_invalid);
} else if (II->isStr("overflow_stack")) {
DebugOverflowStack();
} else if (II->isStr("handle_crash")) {
@@ -1029,12 +1037,8 @@ struct PragmaWarningHandler : public PragmaHandler {
PP.Lex(Tok);
IdentifierInfo *II = Tok.getIdentifierInfo();
- if (!II) {
- PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
- return;
- }
- if (II->isStr("push")) {
+ if (II && II->isStr("push")) {
// #pragma warning( push[ ,n ] )
int Level = -1;
PP.Lex(Tok);
@@ -1051,7 +1055,7 @@ struct PragmaWarningHandler : public PragmaHandler {
}
if (Callbacks)
Callbacks->PragmaWarningPush(DiagLoc, Level);
- } else if (II->isStr("pop")) {
+ } else if (II && II->isStr("pop")) {
// #pragma warning( pop )
PP.Lex(Tok);
if (Callbacks)
@@ -1061,23 +1065,40 @@ struct PragmaWarningHandler : public PragmaHandler {
// [; warning-specifier : warning-number-list...] )
while (true) {
II = Tok.getIdentifierInfo();
- if (!II) {
+ if (!II && !Tok.is(tok::numeric_constant)) {
PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
return;
}
// Figure out which warning specifier this is.
- StringRef Specifier = II->getName();
- bool SpecifierValid =
- llvm::StringSwitch<bool>(Specifier)
- .Cases("1", "2", "3", "4", true)
- .Cases("default", "disable", "error", "once", "suppress", true)
- .Default(false);
+ bool SpecifierValid;
+ StringRef Specifier;
+ llvm::SmallString<1> SpecifierBuf;
+ if (II) {
+ Specifier = II->getName();
+ SpecifierValid = llvm::StringSwitch<bool>(Specifier)
+ .Cases("default", "disable", "error", "once",
+ "suppress", true)
+ .Default(false);
+ // If we read a correct specifier, snatch next token (that should be
+ // ":", checked later).
+ if (SpecifierValid)
+ PP.Lex(Tok);
+ } else {
+ // Token is a numeric constant. It should be either 1, 2, 3 or 4.
+ uint64_t Value;
+ Specifier = PP.getSpelling(Tok, SpecifierBuf);
+ if (PP.parseSimpleIntegerLiteral(Tok, Value)) {
+ SpecifierValid = (Value >= 1) && (Value <= 4);
+ } else
+ SpecifierValid = false;
+ // Next token already snatched by parseSimpleIntegerLiteral.
+ }
+
if (!SpecifierValid) {
PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid);
return;
}
- PP.Lex(Tok);
if (Tok.isNot(tok::colon)) {
PP.Diag(Tok, diag::warn_pragma_warning_expected) << ":";
return;
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index 41bb581bb0aa..a423041a2d95 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -45,22 +45,23 @@ PreprocessingRecord::PreprocessingRecord(SourceManager &SM)
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
/// that source range \p Range encompasses.
-std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
+llvm::iterator_range<PreprocessingRecord::iterator>
PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
if (Range.isInvalid())
- return std::make_pair(iterator(), iterator());
+ return llvm::make_range(iterator(), iterator());
if (CachedRangeQuery.Range == Range) {
- return std::make_pair(iterator(this, CachedRangeQuery.Result.first),
- iterator(this, CachedRangeQuery.Result.second));
+ return llvm::make_range(iterator(this, CachedRangeQuery.Result.first),
+ iterator(this, CachedRangeQuery.Result.second));
}
std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
CachedRangeQuery.Range = Range;
CachedRangeQuery.Result = Res;
-
- return std::make_pair(iterator(this, Res.first), iterator(this, Res.second));
+
+ return llvm::make_range(iterator(this, Res.first),
+ iterator(this, Res.second));
}
static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
@@ -72,11 +73,8 @@ static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
SourceLocation Loc = PPE->getSourceRange().getBegin();
if (Loc.isInvalid())
return false;
-
- if (SM.isInFileID(SM.getFileLoc(Loc), FID))
- return true;
- else
- return false;
+
+ return SM.isInFileID(SM.getFileLoc(Loc), FID);
}
/// \brief Returns true if the preprocessed entity that \arg PPEI iterator
@@ -90,7 +88,7 @@ bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
if (FID.isInvalid())
return false;
- int Pos = PPEI.Position;
+ int Pos = std::distance(iterator(this, 0), PPEI);
if (Pos < 0) {
if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
assert(0 && "Out-of bounds loaded preprocessed entity");
@@ -248,10 +246,11 @@ PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
assert(Entity);
SourceLocation BeginLoc = Entity->getSourceRange().getBegin();
- if (isa<MacroDefinition>(Entity)) {
+ if (isa<MacroDefinitionRecord>(Entity)) {
assert((PreprocessedEntities.empty() ||
- !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
- PreprocessedEntities.back()->getSourceRange().getBegin())) &&
+ !SourceMgr.isBeforeInTranslationUnit(
+ BeginLoc,
+ PreprocessedEntities.back()->getSourceRange().getBegin())) &&
"a macro definition was encountered out-of-order");
PreprocessedEntities.push_back(Entity);
return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
@@ -320,7 +319,7 @@ unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) {
}
void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
- MacroDefinition *Def) {
+ MacroDefinitionRecord *Def) {
MacroDefinitions[Macro] = Def;
}
@@ -357,9 +356,10 @@ PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
return Entity;
}
-MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
- llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
- = MacroDefinitions.find(MI);
+MacroDefinitionRecord *
+PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
+ llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos =
+ MacroDefinitions.find(MI);
if (Pos == MacroDefinitions.end())
return nullptr;
@@ -374,35 +374,34 @@ void PreprocessingRecord::addMacroExpansion(const Token &Id,
return;
if (MI->isBuiltinMacro())
- addPreprocessedEntity(
- new (*this) MacroExpansion(Id.getIdentifierInfo(),Range));
- else if (MacroDefinition *Def = findMacroDefinition(MI))
- addPreprocessedEntity(
- new (*this) MacroExpansion(Def, Range));
+ addPreprocessedEntity(new (*this)
+ MacroExpansion(Id.getIdentifierInfo(), Range));
+ else if (MacroDefinitionRecord *Def = findMacroDefinition(MI))
+ addPreprocessedEntity(new (*this) MacroExpansion(Def, Range));
}
void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
// This is not actually a macro expansion but record it as a macro reference.
if (MD)
- addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+ addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
MacroNameTok.getLocation());
}
void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
- const MacroDirective *MD) {
+ const MacroDefinition &MD) {
// This is not actually a macro expansion but record it as a macro reference.
if (MD)
- addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+ addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
MacroNameTok.getLocation());
}
void PreprocessingRecord::Defined(const Token &MacroNameTok,
- const MacroDirective *MD,
+ const MacroDefinition &MD,
SourceRange Range) {
// This is not actually a macro expansion but record it as a macro reference.
if (MD)
- addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
+ addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
MacroNameTok.getLocation());
}
@@ -410,27 +409,26 @@ void PreprocessingRecord::SourceRangeSkipped(SourceRange Range) {
SkippedRanges.push_back(Range);
}
-void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD,
+void PreprocessingRecord::MacroExpands(const Token &Id,
+ const MacroDefinition &MD,
SourceRange Range,
const MacroArgs *Args) {
- addMacroExpansion(Id, MD->getMacroInfo(), Range);
+ addMacroExpansion(Id, MD.getMacroInfo(), Range);
}
void PreprocessingRecord::MacroDefined(const Token &Id,
const MacroDirective *MD) {
const MacroInfo *MI = MD->getMacroInfo();
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
- MacroDefinition *Def
- = new (*this) MacroDefinition(Id.getIdentifierInfo(), R);
+ MacroDefinitionRecord *Def =
+ new (*this) MacroDefinitionRecord(Id.getIdentifierInfo(), R);
addPreprocessedEntity(Def);
MacroDefinitions[MI] = Def;
}
void PreprocessingRecord::MacroUndefined(const Token &Id,
- const MacroDirective *MD) {
- // Note: MI may be null (when #undef'ining an undefined macro).
- if (MD)
- MacroDefinitions.erase(MD->getMacroInfo());
+ const MacroDefinition &MD) {
+ MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); });
}
void PreprocessingRecord::InclusionDirective(
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index b2a6d933a0f2..7e33f1ccb487 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -73,7 +73,8 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
ModuleImportExpectsIdentifier(false), CodeCompletionReached(0),
MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr),
- Callbacks(nullptr), MacroArgCache(nullptr), Record(nullptr),
+ Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState),
+ MacroArgCache(nullptr), Record(nullptr),
MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
OwnsHeaderSearch = OwnsHeaders;
@@ -266,7 +267,9 @@ void Preprocessor::PrintStats() {
llvm::errs() << "\n Macro Expanded Tokens: "
<< llvm::capacity_in_bytes(MacroExpandedTokens);
llvm::errs() << "\n Predefines Buffer: " << Predefines.capacity();
- llvm::errs() << "\n Macros: " << llvm::capacity_in_bytes(Macros);
+ // FIXME: List information for all submodules.
+ llvm::errs() << "\n Macros: "
+ << llvm::capacity_in_bytes(CurSubmoduleState->Macros);
llvm::errs() << "\n #pragma push_macro Info: "
<< llvm::capacity_in_bytes(PragmaPushMacroInfo);
llvm::errs() << "\n Poison Reasons: "
@@ -283,14 +286,16 @@ Preprocessor::macro_begin(bool IncludeExternalMacros) const {
ExternalSource->ReadDefinedMacros();
}
- return Macros.begin();
+ return CurSubmoduleState->Macros.begin();
}
size_t Preprocessor::getTotalMemory() const {
return BP.getTotalMemory()
+ llvm::capacity_in_bytes(MacroExpandedTokens)
+ Predefines.capacity() /* Predefines buffer. */
- + llvm::capacity_in_bytes(Macros)
+ // FIXME: Include sizes from all submodules, and include MacroInfo sizes,
+ // and ModuleMacros.
+ + llvm::capacity_in_bytes(CurSubmoduleState->Macros)
+ llvm::capacity_in_bytes(PragmaPushMacroInfo)
+ llvm::capacity_in_bytes(PoisonReasons)
+ llvm::capacity_in_bytes(CommentHandlers);
@@ -304,7 +309,7 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const {
ExternalSource->ReadDefinedMacros();
}
- return Macros.end();
+ return CurSubmoduleState->Macros.end();
}
/// \brief Compares macro tokens with a specified token value sequence.
@@ -321,11 +326,11 @@ StringRef Preprocessor::getLastMacroWithSpelling(
StringRef BestSpelling;
for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
I != E; ++I) {
- if (!I->second->getMacroInfo()->isObjectLike())
- continue;
const MacroDirective::DefInfo
- Def = I->second->findDirectiveAtLoc(Loc, SourceMgr);
- if (!Def)
+ Def = I->second.findDirectiveAtLoc(Loc, SourceMgr);
+ if (!Def || !Def.getMacroInfo())
+ continue;
+ if (!Def.getMacroInfo()->isObjectLike())
continue;
if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens))
continue;
@@ -584,6 +589,23 @@ void Preprocessor::HandlePoisonedIdentifier(Token & Identifier) {
Diag(Identifier,it->second) << Identifier.getIdentifierInfo();
}
+/// \brief Returns a diagnostic message kind for reporting a future keyword as
+/// appropriate for the identifier and specified language.
+static diag::kind getFutureCompatDiagKind(const IdentifierInfo &II,
+ const LangOptions &LangOpts) {
+ assert(II.isFutureCompatKeyword() && "diagnostic should not be needed");
+
+ if (LangOpts.CPlusPlus)
+ return llvm::StringSwitch<diag::kind>(II.getName())
+#define CXX11_KEYWORD(NAME, FLAGS) \
+ .Case(#NAME, diag::warn_cxx11_keyword)
+#include "clang/Basic/TokenKinds.def"
+ ;
+
+ llvm_unreachable(
+ "Keyword not known to come from a newer Standard or proposed Standard");
+}
+
/// 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').
@@ -622,8 +644,9 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
}
// If this is a macro to be expanded, do it.
- if (MacroDirective *MD = getMacroDirective(&II)) {
- MacroInfo *MI = MD->getMacroInfo();
+ if (MacroDefinition MD = getMacroDefinition(&II)) {
+ auto *MI = MD.getMacroInfo();
+ assert(MI && "macro definition with no macro info?");
if (!DisableMacroExpansion) {
if (!Identifier.isExpandDisabled() && MI->isEnabled()) {
// C99 6.10.3p10: If the preprocessing token immediately after the
@@ -641,15 +664,16 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
}
}
- // If this identifier is a keyword in C++11, produce a warning. Don't warn if
- // we're not considering macro expansion, since this identifier might be the
- // name of a macro.
+ // If this identifier is a keyword in a newer Standard or proposed Standard,
+ // produce a warning. Don't warn if we're not considering macro expansion,
+ // since this identifier might be the name of a macro.
// FIXME: This warning is disabled in cases where it shouldn't be, like
// "#define constexpr constexpr", "int constexpr;"
- if (II.isCXX11CompatKeyword() && !DisableMacroExpansion) {
- Diag(Identifier, diag::warn_cxx11_keyword) << II.getName();
+ if (II.isFutureCompatKeyword() && !DisableMacroExpansion) {
+ Diag(Identifier, getFutureCompatDiagKind(II, getLangOpts()))
+ << II.getName();
// Don't diagnose this keyword again in this translation unit.
- II.setIsCXX11CompatKeyword(false);
+ II.setIsFutureCompatKeyword(false);
}
// C++ 2.11p2: If this is an alternative representation of a C++ operator,
@@ -748,16 +772,36 @@ void Preprocessor::LexAfterModuleImport(Token &Result) {
// If we have a non-empty module path, load the named module.
if (!ModuleImportPath.empty()) {
Module *Imported = nullptr;
- if (getLangOpts().Modules)
+ if (getLangOpts().Modules) {
Imported = TheModuleLoader.loadModule(ModuleImportLoc,
ModuleImportPath,
- Module::MacrosVisible,
+ Module::Hidden,
/*IsIncludeDirective=*/false);
+ if (Imported)
+ makeModuleVisible(Imported, ModuleImportLoc);
+ }
if (Callbacks && (getLangOpts().Modules || getLangOpts().DebuggerSupport))
Callbacks->moduleImport(ModuleImportLoc, ModuleImportPath, Imported);
}
}
+void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) {
+ CurSubmoduleState->VisibleModules.setVisible(
+ M, Loc, [](Module *) {},
+ [&](ArrayRef<Module *> Path, Module *Conflict, StringRef Message) {
+ // FIXME: Include the path in the diagnostic.
+ // FIXME: Include the import location for the conflicting module.
+ Diag(ModuleImportLoc, diag::warn_module_conflict)
+ << Path[0]->getFullModuleName()
+ << Conflict->getFullModuleName()
+ << Message;
+ });
+
+ // Add this module to the imports list of the currently-built submodule.
+ if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M)
+ BuildingSubmoduleStack.back().M->Imports.insert(M);
+}
+
bool Preprocessor::FinishLexStringLiteral(Token &Result, std::string &String,
const char *DiagnosticTag,
bool AllowMacroExpansion) {
diff --git a/lib/Lex/ScratchBuffer.cpp b/lib/Lex/ScratchBuffer.cpp
index 3bac8891c646..cd8a27e76c28 100644
--- a/lib/Lex/ScratchBuffer.cpp
+++ b/lib/Lex/ScratchBuffer.cpp
@@ -64,12 +64,13 @@ void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) {
if (RequestLen < ScratchBufSize)
RequestLen = ScratchBufSize;
+ // Get scratch buffer. Zero-initialize it so it can be dumped into a PCH file
+ // deterministically.
std::unique_ptr<llvm::MemoryBuffer> OwnBuf =
llvm::MemoryBuffer::getNewMemBuffer(RequestLen, "<scratch space>");
llvm::MemoryBuffer &Buf = *OwnBuf;
FileID FID = SourceMgr.createFileID(std::move(OwnBuf));
BufferStartLoc = SourceMgr.getLocForStartOfFile(FID);
CurBuffer = const_cast<char*>(Buf.getBufferStart());
- BytesUsed = 1;
- CurBuffer[0] = '0'; // Start out with a \0 for cleanliness.
+ BytesUsed = 0;
}
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 5f4705eff697..83efbab76139 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -521,6 +521,13 @@ bool TokenLexer::Lex(Token &Tok) {
/// are more ## after it, chomp them iteratively. Return the result as Tok.
/// If this returns true, the caller should immediately return the token.
bool TokenLexer::PasteTokens(Token &Tok) {
+ // MSVC: If previous token was pasted, this must be a recovery from an invalid
+ // paste operation. Ignore spaces before this token to mimic MSVC output.
+ // Required for generating valid UUID strings in some MS headers.
+ if (PP.getLangOpts().MicrosoftExt && (CurToken >= 2) &&
+ Tokens[CurToken - 2].is(tok::hashhash))
+ Tok.clearFlag(Token::LeadingSpace);
+
SmallString<128> Buffer;
const char *ResultTokStrPtr = nullptr;
SourceLocation StartLoc = Tok.getLocation();
@@ -637,7 +644,7 @@ bool TokenLexer::PasteTokens(Token &Tok) {
// disabling it.
PP.Diag(Loc, PP.getLangOpts().MicrosoftExt ? diag::ext_pp_bad_paste_ms
: diag::err_pp_bad_paste)
- << Buffer.str();
+ << Buffer;
}
// An error has occurred so exit loop.