aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-29 16:25:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-29 16:25:46 +0000
commitb5aee35cc5d62f11d98539f62e4fe63f0ac9edc6 (patch)
tree3e6ab962dbc73cfe1445a60d2eb4dfba7c939a22 /lib/Lex
parentaa803409c3bd3930126db630c29f63d42f255153 (diff)
downloadsrc-b5aee35cc5d62f11d98539f62e4fe63f0ac9edc6.tar.gz
src-b5aee35cc5d62f11d98539f62e4fe63f0ac9edc6.zip
Vendor import of clang trunk r304149:vendor/clang/clang-trunk-r304149
Notes
Notes: svn path=/vendor/clang/dist/; revision=319142 svn path=/vendor/clang/clang-trunk-r304149/; revision=319143; tag=vendor/clang/clang-trunk-r304149
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/LiteralSupport.cpp5
-rw-r--r--lib/Lex/ModuleMap.cpp201
-rw-r--r--lib/Lex/PPDirectives.cpp42
-rw-r--r--lib/Lex/PPMacroExpansion.cpp1
-rw-r--r--lib/Lex/Pragma.cpp4
5 files changed, 130 insertions, 123 deletions
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index fbfd3fe5cce0..1e2cbde825f5 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -563,7 +563,6 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
// Parse the suffix. At this point we can classify whether we have an FP or
// integer constant.
bool isFPConstant = isFloatingLiteral();
- const char *ImaginarySuffixLoc = nullptr;
// Loop over all of the characters of the suffix. If we see something bad,
// we break out of the loop.
@@ -660,7 +659,6 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
case 'J':
if (isImaginary) break; // Cannot be repeated.
isImaginary = true;
- ImaginarySuffixLoc = s;
continue; // Success.
}
// If we reached here, there was an error or a ud-suffix.
@@ -694,8 +692,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
}
if (isImaginary) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc,
- ImaginarySuffixLoc - ThisTokBegin),
+ PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, SuffixBegin - ThisTokBegin),
diag::ext_imaginary_constant);
}
}
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 1f7003a2a4a7..8c57931e47b7 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -84,6 +84,90 @@ Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
return Context;
}
+/// \brief Append to \p Paths the set of paths needed to get to the
+/// subframework in which the given module lives.
+static void appendSubframeworkPaths(Module *Mod,
+ SmallVectorImpl<char> &Path) {
+ // Collect the framework names from the given module to the top-level module.
+ SmallVector<StringRef, 2> Paths;
+ for (; Mod; Mod = Mod->Parent) {
+ if (Mod->IsFramework)
+ Paths.push_back(Mod->Name);
+ }
+
+ if (Paths.empty())
+ return;
+
+ // Add Frameworks/Name.framework for each subframework.
+ for (unsigned I = Paths.size() - 1; I != 0; --I)
+ llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
+}
+
+const FileEntry *
+ModuleMap::resolveHeader(Module *M, Module::UnresolvedHeaderDirective Header,
+ SmallVectorImpl<char> &RelativePathName) {
+ if (llvm::sys::path::is_absolute(Header.FileName)) {
+ RelativePathName.clear();
+ RelativePathName.append(Header.FileName.begin(), Header.FileName.end());
+ return SourceMgr.getFileManager().getFile(Header.FileName);
+ }
+
+ // Search for the header file within the module's home directory.
+ auto *Directory = M->Directory;
+ SmallString<128> FullPathName(Directory->getName());
+ unsigned FullPathLength = FullPathName.size();
+
+ if (M->isPartOfFramework()) {
+ appendSubframeworkPaths(M, RelativePathName);
+ unsigned RelativePathLength = RelativePathName.size();
+
+ // Check whether this file is in the public headers.
+ llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
+ llvm::sys::path::append(FullPathName, RelativePathName);
+ if (auto *File = SourceMgr.getFileManager().getFile(FullPathName))
+ return File;
+
+ // Check whether this file is in the private headers.
+ // Ideally, private modules in the form 'FrameworkName.Private' should
+ // be defined as 'module FrameworkName.Private', and not as
+ // 'framework module FrameworkName.Private', since a 'Private.Framework'
+ // does not usually exist. However, since both are currently widely used
+ // for private modules, make sure we find the right path in both cases.
+ if (M->IsFramework && M->Name == "Private")
+ RelativePathName.clear();
+ else
+ RelativePathName.resize(RelativePathLength);
+ FullPathName.resize(FullPathLength);
+ llvm::sys::path::append(RelativePathName, "PrivateHeaders",
+ Header.FileName);
+ llvm::sys::path::append(FullPathName, RelativePathName);
+ return SourceMgr.getFileManager().getFile(FullPathName);
+ }
+
+ // Lookup for normal headers.
+ llvm::sys::path::append(RelativePathName, Header.FileName);
+ llvm::sys::path::append(FullPathName, RelativePathName);
+ return SourceMgr.getFileManager().getFile(FullPathName);
+}
+
+const FileEntry *
+ModuleMap::resolveAsBuiltinHeader(Module *M,
+ Module::UnresolvedHeaderDirective Header,
+ SmallVectorImpl<char> &BuiltinPathName) {
+ if (llvm::sys::path::is_absolute(Header.FileName) || M->isPartOfFramework() ||
+ !M->IsSystem || Header.IsUmbrella || !BuiltinIncludeDir ||
+ BuiltinIncludeDir == M->Directory || !isBuiltinHeader(Header.FileName))
+ return nullptr;
+
+ // This is a system module with a top-level header. This header
+ // may have a counterpart (or replacement) in the set of headers
+ // supplied by Clang. Find that builtin header.
+ llvm::sys::path::append(BuiltinPathName, BuiltinIncludeDir->getName(),
+ Header.FileName);
+ return SourceMgr.getFileManager().getFile(
+ StringRef(BuiltinPathName.data(), BuiltinPathName.size()));
+}
+
ModuleMap::ModuleMap(SourceManager &SourceMgr, DiagnosticsEngine &Diags,
const LangOptions &LangOpts, const TargetInfo *Target,
HeaderSearch &HeaderInfo)
@@ -1026,9 +1110,6 @@ namespace clang {
/// be resolved relative to.
const DirectoryEntry *Directory;
- /// \brief The directory containing Clang-supplied headers.
- const DirectoryEntry *BuiltinIncludeDir;
-
/// \brief Whether this module map is in a system header directory.
bool IsSystem;
@@ -1087,12 +1168,10 @@ namespace clang {
ModuleMap &Map,
const FileEntry *ModuleMapFile,
const DirectoryEntry *Directory,
- const DirectoryEntry *BuiltinIncludeDir,
bool IsSystem)
: L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
ModuleMapFile(ModuleMapFile), Directory(Directory),
- BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
- HadError(false), ActiveModule(nullptr)
+ IsSystem(IsSystem), HadError(false), ActiveModule(nullptr)
{
Tok.clear();
consumeToken();
@@ -1772,25 +1851,6 @@ void ModuleMapParser::parseRequiresDecl() {
} while (true);
}
-/// \brief Append to \p Paths the set of paths needed to get to the
-/// subframework in which the given module lives.
-static void appendSubframeworkPaths(Module *Mod,
- SmallVectorImpl<char> &Path) {
- // Collect the framework names from the given module to the top-level module.
- SmallVector<StringRef, 2> Paths;
- for (; Mod; Mod = Mod->Parent) {
- if (Mod->IsFramework)
- Paths.push_back(Mod->Name);
- }
-
- if (Paths.empty())
- return;
-
- // Add Frameworks/Name.framework for each subframework.
- for (unsigned I = Paths.size() - 1; I != 0; --I)
- llvm::sys::path::append(Path, "Frameworks", Paths[I-1] + ".framework");
-}
-
/// \brief Parse a header declaration.
///
/// header-declaration:
@@ -1843,85 +1903,36 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
Module::UnresolvedHeaderDirective Header;
Header.FileName = Tok.getString();
Header.FileNameLoc = consumeToken();
+ Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
// Check whether we already have an umbrella.
- if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
+ if (Header.IsUmbrella && ActiveModule->Umbrella) {
Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
<< ActiveModule->getFullModuleName();
HadError = true;
return;
}
- // Look for this file.
- const FileEntry *File = nullptr;
- const FileEntry *BuiltinFile = nullptr;
- SmallString<128> RelativePathName;
- if (llvm::sys::path::is_absolute(Header.FileName)) {
- RelativePathName = Header.FileName;
- File = SourceMgr.getFileManager().getFile(RelativePathName);
- } else {
- // Search for the header file within the search directory.
- SmallString<128> FullPathName(Directory->getName());
- unsigned FullPathLength = FullPathName.size();
-
- if (ActiveModule->isPartOfFramework()) {
- appendSubframeworkPaths(ActiveModule, RelativePathName);
- unsigned RelativePathLength = RelativePathName.size();
-
- // Check whether this file is in the public headers.
- llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
- llvm::sys::path::append(FullPathName, RelativePathName);
- File = SourceMgr.getFileManager().getFile(FullPathName);
-
- // Check whether this file is in the private headers.
- if (!File) {
- // Ideally, private modules in the form 'FrameworkName.Private' should
- // be defined as 'module FrameworkName.Private', and not as
- // 'framework module FrameworkName.Private', since a 'Private.Framework'
- // does not usually exist. However, since both are currently widely used
- // for private modules, make sure we find the right path in both cases.
- if (ActiveModule->IsFramework && ActiveModule->Name == "Private")
- RelativePathName.clear();
- else
- RelativePathName.resize(RelativePathLength);
- FullPathName.resize(FullPathLength);
- llvm::sys::path::append(RelativePathName, "PrivateHeaders",
- Header.FileName);
- 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);
- File = SourceMgr.getFileManager().getFile(FullPathName);
-
- // If this is a system module with a top-level header, this header
- // may have a counterpart (or replacement) in the set of headers
- // supplied by Clang. Find that builtin header.
- if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
- BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
- ModuleMap::isBuiltinHeader(Header.FileName)) {
- SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
- llvm::sys::path::append(BuiltinPathName, Header.FileName);
- BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
-
- // 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 (BuiltinFile && !File) {
- File = BuiltinFile;
- RelativePathName = BuiltinPathName;
- BuiltinFile = nullptr;
- }
- }
- }
+ // Look for this file by name if we don't have any stat information.
+ SmallString<128> RelativePathName, BuiltinPathName;
+ const FileEntry *File =
+ Map.resolveHeader(ActiveModule, Header, RelativePathName);
+ const FileEntry *BuiltinFile =
+ Map.resolveAsBuiltinHeader(ActiveModule, Header, BuiltinPathName);
+
+ // 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 (BuiltinFile && !File) {
+ RelativePathName = BuiltinPathName;
+ File = BuiltinFile;
+ BuiltinFile = nullptr;
}
// FIXME: We shouldn't be eagerly stat'ing every file named in a module map.
// Come up with a lazy way to do this.
if (File) {
- if (LeadingToken == MMToken::UmbrellaKeyword) {
+ if (Header.IsUmbrella) {
const DirectoryEntry *UmbrellaDir = File->getDir();
if (Module *UmbrellaModule = Map.UmbrellaDirs[UmbrellaDir]) {
Diags.Report(LeadingLoc, diag::err_mmap_umbrella_clash)
@@ -1938,10 +1949,7 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// If there is a builtin counterpart to this file, add it now so it can
// wrap the system header.
if (BuiltinFile) {
- // FIXME: Taking the name from the FileEntry is unstable and can give
- // different results depending on how we've previously named that file
- // in this build.
- Module::Header H = { BuiltinFile->getName(), BuiltinFile };
+ Module::Header H = { BuiltinPathName.str(), BuiltinFile };
Map.addHeader(ActiveModule, H, Role);
// If we have both a builtin and system version of the file, the
@@ -1960,7 +1968,6 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// If we find a module that has a missing header, we mark this module as
// unavailable and store the header directive for displaying diagnostics.
- Header.IsUmbrella = LeadingToken == MMToken::UmbrellaKeyword;
ActiveModule->markUnavailable();
ActiveModule->MissingHeaders.push_back(Header);
}
@@ -2555,7 +2562,7 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem,
Buffer->getBufferEnd());
SourceLocation Start = L.getSourceLocation();
ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
- BuiltinIncludeDir, IsSystem);
+ IsSystem);
bool Result = Parser.parseModuleMapFile();
ParsedModuleMap[File] = Result;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 0534aeb10ccb..030717b8bd5c 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -1171,18 +1171,26 @@ void Preprocessor::HandleLineDirective() {
CheckEndOfDirective("line", true);
}
- SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID);
+ // Take the file kind of the file containing the #line directive. #line
+ // directives are often used for generated sources from the same codebase, so
+ // the new file should generally be classified the same way as the current
+ // file. This is visible in GCC's pre-processed output, which rewrites #line
+ // to GNU line markers.
+ SrcMgr::CharacteristicKind FileKind =
+ SourceMgr.getFileCharacteristic(DigitTok.getLocation());
+
+ SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, false,
+ false, FileKind);
if (Callbacks)
Callbacks->FileChanged(CurPPLexer->getSourceLocation(),
- PPCallbacks::RenameFile,
- SrcMgr::C_User);
+ PPCallbacks::RenameFile, FileKind);
}
/// ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line
/// marker directive.
static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit,
- bool &IsSystemHeader, bool &IsExternCHeader,
+ SrcMgr::CharacteristicKind &FileKind,
Preprocessor &PP) {
unsigned FlagVal;
Token FlagTok;
@@ -1233,7 +1241,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit,
return true;
}
- IsSystemHeader = true;
+ FileKind = SrcMgr::C_System;
PP.Lex(FlagTok);
if (FlagTok.is(tok::eod)) return false;
@@ -1247,7 +1255,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit,
return true;
}
- IsExternCHeader = true;
+ FileKind = SrcMgr::C_ExternCSystem;
PP.Lex(FlagTok);
if (FlagTok.is(tok::eod)) return false;
@@ -1277,14 +1285,15 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
Lex(StrTok);
bool IsFileEntry = false, IsFileExit = false;
- bool IsSystemHeader = false, IsExternCHeader = false;
int FilenameID = -1;
+ SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User;
// If the StrTok is "eod", then it wasn't present. Otherwise, it must be a
// string followed by eod.
- if (StrTok.is(tok::eod))
- ; // ok
- else if (StrTok.isNot(tok::string_literal)) {
+ if (StrTok.is(tok::eod)) {
+ // Treat this like "#line NN", which doesn't change file characteristics.
+ FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
+ } else if (StrTok.isNot(tok::string_literal)) {
Diag(StrTok, diag::err_pp_linemarker_invalid_filename);
return DiscardUntilEndOfDirective();
} else if (StrTok.hasUDSuffix()) {
@@ -1303,15 +1312,13 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString());
// If a filename was present, read any flags that are present.
- if (ReadLineMarkerFlags(IsFileEntry, IsFileExit,
- IsSystemHeader, IsExternCHeader, *this))
+ if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, FileKind, *this))
return;
}
// Create a line note with this information.
- SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID,
- IsFileEntry, IsFileExit,
- IsSystemHeader, IsExternCHeader);
+ SourceMgr.AddLineNote(DigitTok.getLocation(), LineNo, FilenameID, IsFileEntry,
+ IsFileExit, FileKind);
// If the preprocessor has callbacks installed, notify them of the #line
// change. This is used so that the line marker comes out in -E mode for
@@ -1322,11 +1329,6 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
Reason = PPCallbacks::EnterFile;
else if (IsFileExit)
Reason = PPCallbacks::ExitFile;
- SrcMgr::CharacteristicKind FileKind = SrcMgr::C_User;
- if (IsExternCHeader)
- FileKind = SrcMgr::C_ExternCSystem;
- else if (IsSystemHeader)
- FileKind = SrcMgr::C_System;
Callbacks->FileChanged(CurPPLexer->getSourceLocation(), Reason, FileKind);
}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 6c7663994a49..a6bfc32e2213 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1125,6 +1125,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("attribute_overloadable", true)
.Case("attribute_unavailable_with_message", true)
.Case("attribute_unused_on_fields", true)
+ .Case("attribute_diagnose_if_objc", true)
.Case("blocks", LangOpts.Blocks)
.Case("c_thread_safety_attributes", true)
.Case("cxx_exceptions", LangOpts.CXXExceptions)
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 99d56182c1bb..2d078a4e7603 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -475,9 +475,9 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
// Emit a line marker. This will change any source locations from this point
// forward to realize they are in a system header.
// Create a line note with this information.
- SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
+ SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine() + 1,
FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
- /*IsSystem=*/true, /*IsExternC=*/false);
+ SrcMgr::C_System);
}
/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.