aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Frontend
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:49:41 +0000
commit45b533945f0851ec234ca846e1af5ee1e4df0b6e (patch)
tree0a5b74c0b9ca73aded34df95c91fcaf3815230d8 /lib/Frontend
parent7e86edd64bfae4e324224452e4ea879b3371a4bd (diff)
downloadsrc-45b533945f0851ec234ca846e1af5ee1e4df0b6e.tar.gz
src-45b533945f0851ec234ca846e1af5ee1e4df0b6e.zip
Vendor import of clang trunk r256633:vendor/clang/clang-trunk-r256633
Notes
Notes: svn path=/vendor/clang/dist/; revision=292920 svn path=/vendor/clang/clang-trunk-r256633/; revision=292923; tag=vendor/clang/clang-trunk-r256633
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTMerge.cpp1
-rw-r--r--lib/Frontend/ASTUnit.cpp134
-rw-r--r--lib/Frontend/CMakeLists.txt2
-rw-r--r--lib/Frontend/CacheTokens.cpp3
-rw-r--r--lib/Frontend/ChainedIncludesSource.cpp20
-rw-r--r--lib/Frontend/CompilerInstance.cpp254
-rw-r--r--lib/Frontend/CompilerInvocation.cpp267
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp6
-rw-r--r--lib/Frontend/DependencyFile.cpp77
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp317
-rw-r--r--lib/Frontend/FrontendAction.cpp18
-rw-r--r--lib/Frontend/FrontendActions.cpp58
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp64
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp90
-rw-r--r--lib/Frontend/InitPreprocessor.cpp59
-rw-r--r--lib/Frontend/LogDiagnosticPrinter.cpp4
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp9
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp10
-rw-r--r--lib/Frontend/PCHContainerOperations.cpp21
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp2
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp5
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp69
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp47
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp74
-rw-r--r--lib/Frontend/TestModuleFileExtension.cpp123
-rw-r--r--lib/Frontend/TestModuleFileExtension.h72
-rw-r--r--lib/Frontend/TextDiagnostic.cpp10
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp4
28 files changed, 1159 insertions, 661 deletions
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index 762c7a5da5e6..b499fa2b0e68 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -59,7 +59,6 @@ void ASTMergeAction::ExecuteAction() {
/*MinimalImport=*/false);
TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
- CI.getASTConsumer().Initialize(CI.getASTContext());
for (auto *D : TU->decls()) {
// Don't re-import __va_list_tag, __builtin_va_list.
if (const auto *ND = dyn_cast<NamedDecl>(D))
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 1bb5c3ff279d..e6ba29201f85 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1,4 +1,4 @@
-//===--- ASTUnit.cpp - ASTUnit utility ------------------------------------===//
+//===--- ASTUnit.cpp - ASTUnit utility --------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -47,6 +47,7 @@
#include <atomic>
#include <cstdio>
#include <cstdlib>
+
using namespace clang;
using llvm::TimeRecord;
@@ -185,7 +186,7 @@ struct ASTUnit::ASTWriterData {
llvm::BitstreamWriter Stream;
ASTWriter Writer;
- ASTWriterData() : Stream(Buffer), Writer(Stream) { }
+ ASTWriterData() : Stream(Buffer), Writer(Stream, { }) { }
};
void ASTUnit::clearFileLevelDecls() {
@@ -649,12 +650,12 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
}
std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
- const std::string &Filename,
- const PCHContainerReader &PCHContainerRdr,
+ const std::string &Filename, const PCHContainerReader &PCHContainerRdr,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
- const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls,
- ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics,
- bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) {
+ const FileSystemOptions &FileSystemOpts, bool UseDebugInfo,
+ bool OnlyLocalDecls, ArrayRef<RemappedFile> RemappedFiles,
+ bool CaptureDiagnostics, bool AllowPCHWithCompilerErrors,
+ bool UserFilesAreVolatile) {
std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
// Recover resources if we crash before exiting this method.
@@ -708,7 +709,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
bool disableValid = false;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
disableValid = true;
- AST->Reader = new ASTReader(PP, Context, PCHContainerRdr,
+ AST->Reader = new ASTReader(PP, Context, PCHContainerRdr, { },
/*isysroot=*/"",
/*DisableValidation=*/disableValid,
AllowPCHWithCompilerErrors);
@@ -926,6 +927,7 @@ public:
const Preprocessor &PP, StringRef isysroot,
raw_ostream *Out)
: PCHGenerator(PP, "", nullptr, isysroot, std::make_shared<PCHBuffer>(),
+ ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>>(),
/*AllowASTWithErrors=*/true),
Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action),
Out(Out) {
@@ -973,7 +975,7 @@ public:
}
};
-}
+} // anonymous namespace
std::unique_ptr<ASTConsumer>
PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
@@ -1076,11 +1078,10 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
// Configure the various subsystems.
LangOpts = Clang->getInvocation().LangOpts;
FileSystemOpts = Clang->getFileSystemOpts();
- IntrusiveRefCntPtr<vfs::FileSystem> VFS =
- createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics());
- if (!VFS)
- return true;
- FileMgr = new FileManager(FileSystemOpts, VFS);
+ if (!FileMgr) {
+ Clang->createFileManager();
+ FileMgr = &Clang->getFileManager();
+ }
SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
UserFilesAreVolatile);
TheSema.reset();
@@ -1724,9 +1725,10 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, ASTFrontendAction *Action,
ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
- bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble,
- bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
- bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
+ bool OnlyLocalDecls, bool CaptureDiagnostics,
+ unsigned PrecompilePreambleAfterNParses, bool CacheCodeCompletionResults,
+ bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile,
+ std::unique_ptr<ASTUnit> *ErrAST) {
assert(CI && "A CompilerInvocation is required");
std::unique_ptr<ASTUnit> OwnAST;
@@ -1745,8 +1747,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
}
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->CaptureDiagnostics = CaptureDiagnostics;
- if (PrecompilePreamble)
- AST->PreambleRebuildCounter = 2;
+ if (PrecompilePreambleAfterNParses > 0)
+ AST->PreambleRebuildCounter = PrecompilePreambleAfterNParses;
AST->TUKind = Action ? Action->getTranslationUnitKind() : TU_Complete;
AST->ShouldCacheCodeCompletionResults = CacheCodeCompletionResults;
AST->IncludeBriefCommentsInCodeCompletion
@@ -1863,7 +1865,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
bool ASTUnit::LoadFromCompilerInvocation(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- bool PrecompilePreamble) {
+ unsigned PrecompilePreambleAfterNParses) {
if (!Invocation)
return true;
@@ -1873,8 +1875,8 @@ bool ASTUnit::LoadFromCompilerInvocation(
ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
- if (PrecompilePreamble) {
- PreambleRebuildCounter = 2;
+ if (PrecompilePreambleAfterNParses > 0) {
+ PreambleRebuildCounter = PrecompilePreambleAfterNParses;
OverrideMainBuffer =
getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
}
@@ -1892,10 +1894,11 @@ bool ASTUnit::LoadFromCompilerInvocation(
std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
CompilerInvocation *CI,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls,
- bool CaptureDiagnostics, bool PrecompilePreamble,
- TranslationUnitKind TUKind, bool CacheCodeCompletionResults,
- bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) {
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr,
+ bool OnlyLocalDecls, bool CaptureDiagnostics,
+ unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
+ bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
+ bool UserFilesAreVolatile) {
// Create the AST unit.
std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
@@ -1907,12 +1910,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
AST->IncludeBriefCommentsInCodeCompletion
= IncludeBriefCommentsInCodeCompletion;
AST->Invocation = CI;
- AST->FileSystemOpts = CI->getFileSystemOpts();
- IntrusiveRefCntPtr<vfs::FileSystem> VFS =
- createVFSFromCompilerInvocation(*CI, *Diags);
- if (!VFS)
- return nullptr;
- AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
+ AST->FileSystemOpts = FileMgr->getFileSystemOpts();
+ AST->FileMgr = FileMgr;
AST->UserFilesAreVolatile = UserFilesAreVolatile;
// Recover resources if we crash before exiting this method.
@@ -1922,7 +1921,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
DiagCleanup(Diags.get());
- if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble))
+ if (AST->LoadFromCompilerInvocation(PCHContainerOps,
+ PrecompilePreambleAfterNParses))
return nullptr;
return AST;
}
@@ -1933,11 +1933,11 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
bool OnlyLocalDecls, bool CaptureDiagnostics,
ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
- bool PrecompilePreamble, TranslationUnitKind TUKind,
+ unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,
bool UserFilesAreVolatile, bool ForSerialization,
- std::unique_ptr<ASTUnit> *ErrAST) {
+ llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST) {
assert(Diags.get() && "no DiagnosticsEngine was provided");
SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
@@ -1970,6 +1970,9 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies;
+ if (ModuleFormat)
+ CI->getHeaderSearchOpts().ModuleFormat = ModuleFormat.getValue();
+
// Create the AST unit.
std::unique_ptr<ASTUnit> AST;
AST.reset(new ASTUnit(false));
@@ -2001,7 +2004,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
ASTUnitCleanup(AST.get());
- if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble)) {
+ if (AST->LoadFromCompilerInvocation(PCHContainerOps,
+ PrecompilePreambleAfterNParses)) {
// Some error occurred, if caller wants to examine diagnostics, pass it the
// ASTUnit.
if (ErrAST) {
@@ -2043,6 +2047,7 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
// Clear out the diagnostics state.
+ FileMgr.reset();
getDiagnostics().Reset();
ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
if (OverrideMainBuffer)
@@ -2124,7 +2129,7 @@ namespace {
return Next.getCodeCompletionTUInfo();
}
};
-}
+} // anonymous namespace
/// \brief Helper function that computes which global names are hidden by the
/// local code-completion results.
@@ -2210,7 +2215,6 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
}
}
-
void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
CodeCompletionContext Context,
CodeCompletionResult *Results,
@@ -2504,7 +2508,7 @@ bool ASTUnit::serialize(raw_ostream &OS) {
SmallString<128> Buffer;
llvm::BitstreamWriter Stream(Buffer);
- ASTWriter Writer(Stream);
+ ASTWriter Writer(Stream, { });
return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
}
@@ -2782,39 +2786,29 @@ bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {
return true;
}
-namespace {
-struct PCHLocatorInfo {
- serialization::ModuleFile *Mod;
- PCHLocatorInfo() : Mod(nullptr) {}
-};
-}
-
-static bool PCHLocator(serialization::ModuleFile &M, void *UserData) {
- PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData);
- switch (M.Kind) {
- case serialization::MK_ImplicitModule:
- case serialization::MK_ExplicitModule:
- return true; // skip dependencies.
- case serialization::MK_PCH:
- Info.Mod = &M;
- return true; // found it.
- case serialization::MK_Preamble:
- return false; // look in dependencies.
- case serialization::MK_MainFile:
- return false; // look in dependencies.
- }
-
- return true;
-}
-
const FileEntry *ASTUnit::getPCHFile() {
if (!Reader)
return nullptr;
- PCHLocatorInfo Info;
- Reader->getModuleManager().visit(PCHLocator, &Info);
- if (Info.Mod)
- return Info.Mod->File;
+ serialization::ModuleFile *Mod = nullptr;
+ Reader->getModuleManager().visit([&Mod](serialization::ModuleFile &M) {
+ switch (M.Kind) {
+ case serialization::MK_ImplicitModule:
+ case serialization::MK_ExplicitModule:
+ return true; // skip dependencies.
+ case serialization::MK_PCH:
+ Mod = &M;
+ return true; // found it.
+ case serialization::MK_Preamble:
+ return false; // look in dependencies.
+ case serialization::MK_MainFile:
+ return false; // look in dependencies.
+ }
+
+ return true;
+ });
+ if (Mod)
+ return Mod->File;
return nullptr;
}
@@ -2854,9 +2848,9 @@ void ASTUnit::ConcurrencyState::finish() {
#else // NDEBUG
-ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = 0; }
+ASTUnit::ConcurrencyState::ConcurrencyState() { Mutex = nullptr; }
ASTUnit::ConcurrencyState::~ConcurrencyState() {}
void ASTUnit::ConcurrencyState::start() {}
void ASTUnit::ConcurrencyState::finish() {}
-#endif
+#endif // NDEBUG
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 9a3e459640a5..476812046241 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -35,6 +35,7 @@ add_clang_library(clangFrontend
PrintPreprocessedOutput.cpp
SerializedDiagnosticPrinter.cpp
SerializedDiagnosticReader.cpp
+ TestModuleFileExtension.cpp
TextDiagnostic.cpp
TextDiagnosticBuffer.cpp
TextDiagnosticPrinter.cpp
@@ -42,6 +43,7 @@ add_clang_library(clangFrontend
DEPENDS
ClangDriverOptions
+ intrinsics_gen
LINK_LIBS
clangAST
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 7d2a09cd7ca0..87f3d1725814 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -19,6 +19,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PTHManager.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
@@ -105,7 +106,7 @@ public:
}
unsigned getRepresentationLength() const {
- return Kind == IsNoExist ? 0 : 4 + 4 + 2 + 8 + 8;
+ return Kind == IsNoExist ? 0 : 4 * 8;
}
};
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index cc0504ba8b29..1c1081fbe08e 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -47,9 +47,9 @@ protected:
CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override;
bool FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) override;
- ExternalLoadResult
+ void
FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
+ llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) override;
void CompleteType(TagDecl *Tag) override;
void CompleteType(ObjCInterfaceDecl *Class) override;
@@ -82,6 +82,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
std::unique_ptr<ASTReader> Reader;
Reader.reset(new ASTReader(PP, CI.getASTContext(),
CI.getPCHContainerReader(),
+ /*Extensions=*/{ },
/*isysroot=*/"", /*DisableValidation=*/true));
for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
StringRef sr(bufNames[ti]);
@@ -160,8 +161,10 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
Clang->createASTContext();
auto Buffer = std::make_shared<PCHBuffer>();
+ ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions;
auto consumer = llvm::make_unique<PCHGenerator>(
- Clang->getPreprocessor(), "-", nullptr, /*isysroot=*/"", Buffer);
+ Clang->getPreprocessor(), "-", nullptr, /*isysroot=*/"", Buffer,
+ Extensions);
Clang->getASTContext().setASTMutationListener(
consumer->GetASTMutationListener());
Clang->setASTConsumer(std::move(consumer));
@@ -169,7 +172,7 @@ IntrusiveRefCntPtr<ExternalSemaSource> clang::createChainedIncludesSource(
if (firstInclude) {
Preprocessor &PP = Clang->getPreprocessor();
- PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
+ PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
PP.getLangOpts());
} else {
assert(!SerialBufs.empty());
@@ -246,11 +249,10 @@ ChainedIncludesSource::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
return getFinalReader().FindExternalVisibleDeclsByName(DC, Name);
}
-ExternalLoadResult
-ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
- bool (*isKindWeWant)(Decl::Kind),
- SmallVectorImpl<Decl*> &Result) {
- return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
+void ChainedIncludesSource::FindExternalLexicalDecls(
+ const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
+ SmallVectorImpl<Decl *> &Result) {
+ return getFinalReader().FindExternalLexicalDecls(DC, IsKindWeWant, Result);
}
void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
return getFinalReader().CompleteType(Tag);
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index c33b150e3047..3edcf5d654b9 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -78,9 +78,8 @@ void CompilerInstance::setDiagnostics(DiagnosticsEngine *Value) {
Diagnostics = Value;
}
-void CompilerInstance::setTarget(TargetInfo *Value) {
- Target = Value;
-}
+void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
+void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
void CompilerInstance::setFileManager(FileManager *Value) {
FileMgr = Value;
@@ -96,7 +95,12 @@ void CompilerInstance::setSourceManager(SourceManager *Value) {
void CompilerInstance::setPreprocessor(Preprocessor *Value) { PP = Value; }
-void CompilerInstance::setASTContext(ASTContext *Value) { Context = Value; }
+void CompilerInstance::setASTContext(ASTContext *Value) {
+ Context = Value;
+
+ if (Context && Consumer)
+ getASTConsumer().Initialize(getASTContext());
+}
void CompilerInstance::setSema(Sema *S) {
TheSema.reset(S);
@@ -104,6 +108,9 @@ void CompilerInstance::setSema(Sema *S) {
void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {
Consumer = std::move(Value);
+
+ if (Context && Consumer)
+ getASTConsumer().Initialize(getASTContext());
}
void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
@@ -148,7 +155,6 @@ static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
<< DiagOpts->DiagnosticLogFile << EC.message();
} else {
FileOS->SetUnbuffered();
- FileOS->SetUseAtomicWrites(true);
OS = FileOS.get();
StreamOwner = std::move(FileOS);
}
@@ -304,7 +310,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
PP = new Preprocessor(&getPreprocessorOpts(), getDiagnostics(), getLangOpts(),
getSourceManager(), *HeaderInfo, *this, PTHMgr,
/*OwnsHeaderSearch=*/true, TUKind);
- PP->Initialize(getTarget());
+ PP->Initialize(getTarget(), getAuxTarget());
// Note that this is different then passing PTHMgr to Preprocessor's ctor.
// That argument is used as the IdentifierInfoLookup argument to
@@ -331,7 +337,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
PP->setPreprocessedOutput(getPreprocessorOutputOpts().ShowCPP);
- if (PP->getLangOpts().Modules)
+ if (PP->getLangOpts().Modules && PP->getLangOpts().ImplicitModules)
PP->getHeaderSearchInfo().setModuleCachePath(getSpecificModuleCachePath());
// Handle generating dependencies, if requested.
@@ -354,17 +360,19 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
// Handle generating header include information, if requested.
if (DepOpts.ShowHeaderIncludes)
- AttachHeaderIncludeGen(*PP);
+ AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps);
if (!DepOpts.HeaderIncludeOutputFile.empty()) {
StringRef OutputPath = DepOpts.HeaderIncludeOutputFile;
if (OutputPath == "-")
OutputPath = "";
- AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/true, OutputPath,
+ AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps,
+ /*ShowAllHeaders=*/true, OutputPath,
/*ShowDepth=*/false);
}
if (DepOpts.PrintShowIncludes) {
- AttachHeaderIncludeGen(*PP, /*ShowAllHeaders=*/false, /*OutputPath=*/"",
+ AttachHeaderIncludeGen(*PP, DepOpts.ExtraDeps,
+ /*ShowAllHeaders=*/false, /*OutputPath=*/"",
/*ShowDepth=*/true, /*MSStyle=*/true);
}
}
@@ -372,9 +380,8 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
std::string CompilerInstance::getSpecificModuleCachePath() {
// Set up the module path, including the hash for the
// module-creation options.
- SmallString<256> SpecificModuleCache(
- getHeaderSearchOpts().ModuleCachePath);
- if (!getHeaderSearchOpts().DisableModuleHash)
+ SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath);
+ if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
llvm::sys::path::append(SpecificModuleCache,
getInvocation().getModuleHash());
return SpecificModuleCache.str();
@@ -384,10 +391,11 @@ std::string CompilerInstance::getSpecificModuleCachePath() {
void CompilerInstance::createASTContext() {
Preprocessor &PP = getPreprocessor();
- Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
- PP.getIdentifierTable(), PP.getSelectorTable(),
- PP.getBuiltinInfo());
- Context->InitBuiltinTypes(getTarget());
+ auto *Context = new ASTContext(getLangOpts(), PP.getSourceManager(),
+ PP.getIdentifierTable(), PP.getSelectorTable(),
+ PP.getBuiltinInfo());
+ Context->InitBuiltinTypes(getTarget(), getAuxTarget());
+ setASTContext(Context);
}
// ExternalASTSource
@@ -399,7 +407,9 @@ void CompilerInstance::createPCHExternalASTSource(
ModuleManager = createPCHExternalASTSource(
Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
- getPCHContainerReader(), DeserializationListener,
+ getPCHContainerReader(),
+ getFrontendOpts().ModuleFileExtensions,
+ DeserializationListener,
OwnDeserializationListener, Preamble,
getFrontendOpts().UseGlobalModuleIndex);
}
@@ -408,15 +418,16 @@ IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
const PCHContainerReader &PCHContainerRdr,
+ ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions,
void *DeserializationListener, bool OwnDeserializationListener,
bool Preamble, bool UseGlobalModuleIndex) {
HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
- PP, Context, PCHContainerRdr, Sysroot.empty() ? "" : Sysroot.data(),
- DisablePCHValidation, AllowPCHWithCompilerErrors,
- /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders,
- UseGlobalModuleIndex));
+ PP, Context, PCHContainerRdr, Extensions,
+ Sysroot.empty() ? "" : Sysroot.data(), DisablePCHValidation,
+ AllowPCHWithCompilerErrors, /*AllowConfigurationMismatch*/ false,
+ HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
// We need the external source to be set up before we read the AST, because
// eagerly-deserialized declarations may use it.
@@ -631,8 +642,10 @@ std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile(
llvm::sys::fs::status(OutputPath, Status);
if (llvm::sys::fs::exists(Status)) {
// Fail early if we can't write to the final destination.
- if (!llvm::sys::fs::can_write(OutputPath))
+ if (!llvm::sys::fs::can_write(OutputPath)) {
+ Error = make_error_code(llvm::errc::operation_not_permitted);
return nullptr;
+ }
// Don't use a temporary if the output is a special file. This handles
// things like '-o /dev/null'
@@ -715,7 +728,7 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
if (Input.isBuffer()) {
SourceMgr.setMainFileID(SourceMgr.createFileID(
std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind));
- assert(!SourceMgr.getMainFileID().isInvalid() &&
+ assert(SourceMgr.getMainFileID().isValid() &&
"Couldn't establish MainFileID!");
return true;
}
@@ -766,7 +779,7 @@ bool CompilerInstance::InitializeSourceManager(const FrontendInputFile &Input,
SourceMgr.overrideFileContents(File, std::move(SB));
}
- assert(!SourceMgr.getMainFileID().isInvalid() &&
+ assert(SourceMgr.getMainFileID().isValid() &&
"Couldn't establish MainFileID!");
return true;
}
@@ -788,6 +801,13 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
if (!hasTarget())
return false;
+ // Create TargetInfo for the other side of CUDA compilation.
+ if (getLangOpts().CUDA && !getFrontendOpts().AuxTriple.empty()) {
+ std::shared_ptr<TargetOptions> TO(new TargetOptions);
+ TO->Triple = getFrontendOpts().AuxTriple;
+ setAuxTarget(TargetInfo::CreateTargetInfo(getDiagnostics(), TO));
+ }
+
// Inform the target of the language options.
//
// FIXME: We shouldn't need to do this, the target should be immutable once
@@ -810,13 +830,13 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
if (getFrontendOpts().ShowStats)
llvm::EnableStatistics();
- for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
+ for (const FrontendInputFile &FIF : getFrontendOpts().Inputs) {
// Reset the ID tables if we are reusing the SourceManager and parsing
// regular files.
if (hasSourceManager() && !Act.isModelParsingAction())
getSourceManager().clearIDTables();
- if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
+ if (Act.BeginSourceFile(*this, FIF)) {
Act.Execute();
Act.EndSourceFile();
}
@@ -912,6 +932,7 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance,
FrontendOpts.OutputFile = ModuleFileName.str();
FrontendOpts.DisableFree = false;
FrontendOpts.GenerateGlobalModuleIndex = false;
+ FrontendOpts.BuildingImplicitModule = true;
FrontendOpts.Inputs.clear();
InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
@@ -945,8 +966,10 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance,
FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
// If we're collecting module dependencies, we need to share a collector
- // between all of the module CompilerInstances.
+ // between all of the module CompilerInstances. Other than that, we don't
+ // want to produce any dependency output from the module build.
Instance.setModuleDepCollector(ImportingInstance.getModuleDepCollector());
+ Invocation->getDependencyOutputOpts() = DependencyOutputOptions();
// Get or create the module map that we'll use to build this module.
std::string InferredModuleMapContent;
@@ -1151,6 +1174,7 @@ static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {
struct stat StatBuf;
llvm::SmallString<128> TimestampFile;
TimestampFile = HSOpts.ModuleCachePath;
+ assert(!TimestampFile.empty());
llvm::sys::path::append(TimestampFile, "modules.timestamp");
// Try to stat() the timestamp file.
@@ -1229,8 +1253,8 @@ void CompilerInstance::createModuleManager() {
// If we're implicitly building modules but not currently recursively
// building a module, check whether we need to prune the module cache.
- if (getLangOpts().ImplicitModules &&
- getSourceManager().getModuleBuildStack().empty() &&
+ if (getSourceManager().getModuleBuildStack().empty() &&
+ !getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty() &&
getHeaderSearchOpts().ModuleCachePruneInterval > 0 &&
getHeaderSearchOpts().ModuleCachePruneAfter > 0) {
pruneModuleCache(getHeaderSearchOpts());
@@ -1244,7 +1268,8 @@ void CompilerInstance::createModuleManager() {
ReadTimer = llvm::make_unique<llvm::Timer>("Reading modules",
*FrontendTimerGroup);
ModuleManager = new ASTReader(
- getPreprocessor(), *Context, getPCHContainerReader(),
+ getPreprocessor(), getASTContext(), getPCHContainerReader(),
+ getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
/*AllowASTWithCompilerErrors=*/false,
/*AllowConfigurationMismatch=*/false,
@@ -1262,6 +1287,13 @@ void CompilerInstance::createModuleManager() {
ModuleManager->InitializeSema(getSema());
if (hasASTConsumer())
ModuleManager->StartTranslationUnit(&getASTConsumer());
+
+ if (TheDependencyFileGenerator)
+ TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
+ if (ModuleDepCollector)
+ ModuleDepCollector->attachToASTReader(*ModuleManager);
+ for (auto &Listener : DependencyCollectors)
+ Listener->attachToASTReader(*ModuleManager);
}
}
@@ -1276,87 +1308,68 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
// the files we were handed.
struct ReadModuleNames : ASTReaderListener {
CompilerInstance &CI;
- std::vector<StringRef> ModuleFileStack;
- std::vector<StringRef> ModuleNameStack;
- bool Failed;
- bool TopFileIsModule;
-
- ReadModuleNames(CompilerInstance &CI)
- : CI(CI), Failed(false), TopFileIsModule(false) {}
+ llvm::SmallVector<IdentifierInfo*, 8> LoadedModules;
- bool needsImportVisitation() const override { return true; }
+ ReadModuleNames(CompilerInstance &CI) : CI(CI) {}
- void visitImport(StringRef FileName) override {
- if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second) {
- if (ModuleFileStack.size() == 0)
- TopFileIsModule = true;
- return;
- }
+ void ReadModuleName(StringRef ModuleName) override {
+ LoadedModules.push_back(
+ CI.getPreprocessor().getIdentifierInfo(ModuleName));
+ }
- ModuleFileStack.push_back(FileName);
- ModuleNameStack.push_back(StringRef());
- if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
- CI.getPCHContainerReader(),
- *this)) {
- CI.getDiagnostics().Report(
- SourceLocation(), CI.getFileManager().getBufferForFile(FileName)
- ? diag::err_module_file_invalid
- : diag::err_module_file_not_found)
- << FileName;
- for (int I = ModuleFileStack.size() - 2; I >= 0; --I)
- CI.getDiagnostics().Report(SourceLocation(),
- diag::note_module_file_imported_by)
- << ModuleFileStack[I]
- << !ModuleNameStack[I].empty() << ModuleNameStack[I];
- Failed = true;
+ void registerAll() {
+ for (auto *II : LoadedModules) {
+ CI.KnownModules[II] = CI.getPreprocessor()
+ .getHeaderSearchInfo()
+ .getModuleMap()
+ .findModule(II->getName());
}
- ModuleNameStack.pop_back();
- ModuleFileStack.pop_back();
+ LoadedModules.clear();
}
- void ReadModuleName(StringRef ModuleName) override {
- if (ModuleFileStack.size() == 1)
- TopFileIsModule = true;
- ModuleNameStack.back() = ModuleName;
-
- auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
- if (!ModuleFile.empty() &&
- CI.getFileManager().getFile(ModuleFile) !=
- CI.getFileManager().getFile(ModuleFileStack.back()))
- CI.getDiagnostics().Report(SourceLocation(),
- diag::err_conflicting_module_files)
- << ModuleName << ModuleFile << ModuleFileStack.back();
- ModuleFile = ModuleFileStack.back();
+ void markAllUnavailable() {
+ for (auto *II : LoadedModules) {
+ if (Module *M = CI.getPreprocessor()
+ .getHeaderSearchInfo()
+ .getModuleMap()
+ .findModule(II->getName()))
+ M->HasIncompatibleModuleFile = true;
+ }
+ LoadedModules.clear();
}
- } RMN(*this);
+ };
// If we don't already have an ASTReader, create one now.
if (!ModuleManager)
createModuleManager();
- // Tell the module manager about this module file.
- if (getModuleManager()->getModuleManager().addKnownModuleFile(FileName)) {
- getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_found)
- << FileName;
- return false;
- }
+ auto Listener = llvm::make_unique<ReadModuleNames>(*this);
+ auto &ListenerRef = *Listener;
+ ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager,
+ std::move(Listener));
- // Build our mapping of module names to module files from this file
- // and its imports.
- RMN.visitImport(FileName);
+ // Try to load the module file.
+ switch (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule,
+ SourceLocation(),
+ ASTReader::ARR_ConfigurationMismatch)) {
+ case ASTReader::Success:
+ // We successfully loaded the module file; remember the set of provided
+ // modules so that we don't try to load implicit modules for them.
+ ListenerRef.registerAll();
+ return true;
- if (RMN.Failed)
- return false;
+ case ASTReader::ConfigurationMismatch:
+ // Ignore unusable module files.
+ getDiagnostics().Report(SourceLocation(), diag::warn_module_config_mismatch)
+ << FileName;
+ // All modules provided by any files we tried and failed to load are now
+ // unavailable; includes of those modules should now be handled textually.
+ ListenerRef.markAllUnavailable();
+ return true;
- // If we never found a module name for the top file, then it's not a module,
- // it's a PCH or preamble or something.
- if (!RMN.TopFileIsModule) {
- getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)
- << FileName;
+ default:
return false;
}
-
- return true;
}
ModuleLoadResult
@@ -1371,7 +1384,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// If we've already handled this import, just return the cached result.
// This one-element cache is important to eliminate redundant diagnostics
// when both the preprocessor and parser see the same import declaration.
- if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
+ if (ImportLoc.isValid() && LastModuleImportLoc == ImportLoc) {
// Make the named module visible.
if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule &&
ModuleName != getLangOpts().ImplementationOfModule)
@@ -1404,56 +1417,40 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
return ModuleLoadResult();
}
- auto Override = ModuleFileOverrides.find(ModuleName);
- bool Explicit = Override != ModuleFileOverrides.end();
- if (!Explicit && !getLangOpts().ImplicitModules) {
+ std::string ModuleFileName =
+ PP->getHeaderSearchInfo().getModuleFileName(Module);
+ if (ModuleFileName.empty()) {
+ if (Module->HasIncompatibleModuleFile) {
+ // We tried and failed to load a module file for this module. Fall
+ // back to textual inclusion for its headers.
+ return ModuleLoadResult(nullptr, /*missingExpected*/true);
+ }
+
getDiagnostics().Report(ModuleNameLoc, diag::err_module_build_disabled)
<< ModuleName;
ModuleBuildFailed = true;
return ModuleLoadResult();
}
- std::string ModuleFileName =
- Explicit ? Override->second
- : PP->getHeaderSearchInfo().getModuleFileName(Module);
-
// If we don't already have an ASTReader, create one now.
if (!ModuleManager)
createModuleManager();
- if (TheDependencyFileGenerator)
- TheDependencyFileGenerator->AttachToASTReader(*ModuleManager);
-
- if (ModuleDepCollector)
- ModuleDepCollector->attachToASTReader(*ModuleManager);
-
- for (auto &Listener : DependencyCollectors)
- Listener->attachToASTReader(*ModuleManager);
-
llvm::Timer Timer;
if (FrontendTimerGroup)
Timer.init("Loading " + ModuleFileName, *FrontendTimerGroup);
llvm::TimeRegion TimeLoading(FrontendTimerGroup ? &Timer : nullptr);
// Try to load the module file.
- unsigned ARRFlags =
- Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
+ unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
switch (ModuleManager->ReadAST(ModuleFileName,
- Explicit ? serialization::MK_ExplicitModule
- : serialization::MK_ImplicitModule,
+ serialization::MK_ImplicitModule,
ImportLoc, ARRFlags)) {
case ASTReader::Success:
break;
case ASTReader::OutOfDate:
case ASTReader::Missing: {
- if (Explicit) {
- // ReadAST has already complained for us.
- ModuleLoader::HadFatalFailure = true;
- KnownModules[Path[0].first] = nullptr;
- return ModuleLoadResult();
- }
-
// The module file is missing or out-of-date. Build it.
assert(Module && "missing module file");
// Check whether there is a cycle in the module graph.
@@ -1508,7 +1505,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
case ASTReader::ConfigurationMismatch:
case ASTReader::HadErrors:
ModuleLoader::HadFatalFailure = true;
- // FIXME: The ASTReader will already have complained, but can we showhorn
+ // FIXME: The ASTReader will already have complained, but can we shoehorn
// that diagnostic information into a more useful form?
KnownModules[Path[0].first] = nullptr;
return ModuleLoadResult();
@@ -1652,6 +1649,8 @@ void CompilerInstance::makeModuleVisible(Module *Mod,
GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
SourceLocation TriggerLoc) {
+ if (getPreprocessor().getHeaderSearchInfo().getModuleCachePath().empty())
+ return nullptr;
if (!ModuleManager)
createModuleManager();
// Can't do anything if we don't have the module manager.
@@ -1685,11 +1684,10 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
if (!Entry) {
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> Path;
Path.push_back(std::make_pair(
- getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));
+ getPreprocessor().getIdentifierInfo(TheModule->Name), TriggerLoc));
std::reverse(Path.begin(), Path.end());
- // Load a module as hidden. This also adds it to the global index.
- loadModule(TheModule->DefinitionLoc, Path,
- Module::Hidden, false);
+ // Load a module as hidden. This also adds it to the global index.
+ loadModule(TheModule->DefinitionLoc, Path, Module::Hidden, false);
RecreateIndex = true;
}
}
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index fbeba09e1cf1..d3870424b6bb 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1,4 +1,4 @@
-//===--- CompilerInvocation.cpp -------------------------------------------===//
+//===---
//
// The LLVM Compiler Infrastructure
//
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "TestModuleFileExtension.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/Version.h"
@@ -19,12 +20,14 @@
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Serialization/ASTReader.h"
+#include "clang/Serialization/ModuleFileExtension.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/Linker/Linker.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
@@ -35,6 +38,7 @@
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
+#include "llvm/Target/TargetOptions.h"
#include <atomic>
#include <memory>
#include <sys/stat.h>
@@ -53,7 +57,7 @@ CompilerInvocationBase::CompilerInvocationBase()
CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
: RefCountedBase<CompilerInvocation>(),
- LangOpts(new LangOptions(*X.getLangOpts())),
+ LangOpts(new LangOptions(*X.getLangOpts())),
TargetOpts(new TargetOptions(X.getTargetOpts())),
DiagnosticOpts(new DiagnosticOptions(X.getDiagnosticOpts())),
HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
@@ -361,6 +365,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
const TargetOptions &TargetOpts) {
using namespace options;
bool Success = true;
+ llvm::Triple Triple = llvm::Triple(TargetOpts.Triple);
unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
// TODO: This could be done in Driver
@@ -393,39 +398,36 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
}
- if (Args.hasArg(OPT_gline_tables_only)) {
- Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly);
- } else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) ||
- Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) {
- bool Default = false;
- // Until dtrace (via CTF) and LLDB can deal with distributed debug info,
- // Darwin and FreeBSD default to standalone/full debug info.
- if (llvm::Triple(TargetOpts.Triple).isOSDarwin() ||
- llvm::Triple(TargetOpts.Triple).isOSFreeBSD())
- Default = true;
-
- if (Args.hasFlag(OPT_fstandalone_debug, OPT_fno_standalone_debug, Default))
- Opts.setDebugInfo(CodeGenOptions::FullDebugInfo);
- else
- Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo);
+ if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
+ Opts.setDebugInfo(
+ llvm::StringSwitch<CodeGenOptions::DebugInfoKind>(A->getValue())
+ .Case("line-tables-only", CodeGenOptions::DebugLineTablesOnly)
+ .Case("limited", CodeGenOptions::LimitedDebugInfo)
+ .Case("standalone", CodeGenOptions::FullDebugInfo));
+ }
+ if (Arg *A = Args.getLastArg(OPT_debugger_tuning_EQ)) {
+ Opts.setDebuggerTuning(
+ llvm::StringSwitch<CodeGenOptions::DebuggerKind>(A->getValue())
+ .Case("gdb", CodeGenOptions::DebuggerKindGDB)
+ .Case("lldb", CodeGenOptions::DebuggerKindLLDB)
+ .Case("sce", CodeGenOptions::DebuggerKindSCE));
}
+ Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 0, Diags);
Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
+ Opts.EmitCodeView = Args.hasArg(OPT_gcodeview);
Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
- if (Args.hasArg(OPT_gdwarf_2))
- Opts.DwarfVersion = 2;
- else if (Args.hasArg(OPT_gdwarf_3))
- Opts.DwarfVersion = 3;
- else if (Args.hasArg(OPT_gdwarf_4))
- Opts.DwarfVersion = 4;
- else if (Opts.getDebugInfo() != CodeGenOptions::NoDebugInfo)
- // Default Dwarf version is 4 if we are generating debug information.
- Opts.DwarfVersion = 4;
+ Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
+ Opts.DebugExplicitImport = Triple.isPS4CPU();
+
+ for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
+ Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
if (const Arg *A =
Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
+ Opts.DisableLLVMPasses = Args.hasArg(OPT_disable_llvm_passes);
Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
Opts.UseRegisterSizedBitfieldAccess = Args.hasArg(
@@ -451,7 +453,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Args.hasArg(OPT_fprofile_instr_generate_EQ);
Opts.InstrProfileOutput = Args.getLastArgValue(OPT_fprofile_instr_generate_EQ);
Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
- Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping);
+ Opts.CoverageMapping =
+ Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
@@ -459,10 +462,25 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.CodeModel = getCodeModel(Args, Diags);
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
- Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
+ Opts.DisableFPElim =
+ (Args.hasArg(OPT_mdisable_fp_elim) || Args.hasArg(OPT_pg));
Opts.DisableFree = Args.hasArg(OPT_disable_free);
Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
+ if (Arg *A = Args.getLastArg(OPT_meabi)) {
+ StringRef Value = A->getValue();
+ llvm::EABI EABIVersion = llvm::StringSwitch<llvm::EABI>(Value)
+ .Case("default", llvm::EABI::Default)
+ .Case("4", llvm::EABI::EABI4)
+ .Case("5", llvm::EABI::EABI5)
+ .Case("gnu", llvm::EABI::GNU)
+ .Default(llvm::EABI::Unknown);
+ if (EABIVersion == llvm::EABI::Unknown)
+ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
+ << Value;
+ else
+ Opts.EABIVersion = Value;
+ }
Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable);
Opts.LimitFloatPrecision = Args.getLastArgValue(OPT_mlimit_float_precision);
Opts.NoInfsFPMath = (Args.hasArg(OPT_menable_no_infinities) ||
@@ -481,11 +499,14 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks);
Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
+ Opts.IncrementalLinkerCompatible =
+ Args.hasArg(OPT_mincremental_linker_compatible);
Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels);
Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
+ Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
@@ -508,7 +529,15 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);
- Opts.PrepareForLTO = Args.hasArg(OPT_flto);
+ Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
+ const Arg *A = Args.getLastArg(OPT_flto, OPT_flto_EQ);
+ Opts.EmitFunctionSummary = A && A->containsValue("thin");
+ if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
+ if (IK != IK_LLVM_IR)
+ Diags.Report(diag::err_drv_argument_only_allowed_with)
+ << A->getAsString(Args) << "-x ir";
+ Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ);
+ }
Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);
@@ -546,7 +575,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections);
Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
- Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
+ for (auto A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) {
+ unsigned LinkFlags = llvm::Linker::Flags::None;
+ if (A->getOption().matches(OPT_mlink_cuda_bitcode))
+ LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded |
+ llvm::Linker::Flags::InternalizeLinkedSymbols;
+ Opts.LinkBitcodeFiles.push_back(std::make_pair(LinkFlags, A->getValue()));
+ }
Opts.SanitizeCoverageType =
getLastArgIntValue(Args, OPT_fsanitize_coverage_type, 0, Diags);
Opts.SanitizeCoverageIndirectCalls =
@@ -559,6 +594,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
Opts.SanitizeMemoryUseAfterDtor =
Args.hasArg(OPT_fsanitize_memory_use_after_dtor);
+ Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso);
Opts.SSPBufferSize =
getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags);
Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
@@ -592,6 +628,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}
+ Opts.EmulatedTLS =
+ Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false);
+
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
StringRef Name = A->getValue();
unsigned Model = llvm::StringSwitch<unsigned>(Name)
@@ -695,6 +734,13 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Args.getLastArgValue(OPT_module_dependency_dir);
if (Args.hasArg(OPT_MV))
Opts.OutputFormat = DependencyOutputFormat::NMake;
+ // Add sanitizer blacklists as extra dependencies.
+ // They won't be discovered by the regular preprocessor, so
+ // we let make / ninja to know about this implicit dependency.
+ Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry);
+ auto ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
+ Opts.ExtraDeps.insert(Opts.ExtraDeps.end(), ModuleFiles.begin(),
+ ModuleFiles.end());
}
bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
@@ -822,6 +868,30 @@ static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) {
Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory);
}
+/// Parse the argument to the -ftest-module-file-extension
+/// command-line argument.
+///
+/// \returns true on error, false on success.
+static bool parseTestModuleFileExtensionArg(StringRef Arg,
+ std::string &BlockName,
+ unsigned &MajorVersion,
+ unsigned &MinorVersion,
+ bool &Hashed,
+ std::string &UserInfo) {
+ SmallVector<StringRef, 5> Args;
+ Arg.split(Args, ':', 5);
+ if (Args.size() < 5)
+ return true;
+
+ BlockName = Args[0];
+ if (Args[1].getAsInteger(10, MajorVersion)) return true;
+ if (Args[2].getAsInteger(10, MinorVersion)) return true;
+ if (Args[3].getAsInteger(2, Hashed)) return true;
+ if (Args.size() > 4)
+ UserInfo = Args[4];
+ return false;
+}
+
static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
using namespace options;
@@ -914,6 +984,26 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
if (A->getValue(0) == Opts.AddPluginActions[i])
Opts.AddPluginArgs[i].emplace_back(A->getValue(1));
+ for (const std::string &Arg :
+ Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
+ std::string BlockName;
+ unsigned MajorVersion;
+ unsigned MinorVersion;
+ bool Hashed;
+ std::string UserInfo;
+ if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
+ MinorVersion, Hashed, UserInfo)) {
+ Diags.Report(diag::err_test_module_file_extension_format) << Arg;
+
+ continue;
+ }
+
+ // Add the testing module file extension.
+ Opts.ModuleFileExtensions.push_back(
+ new TestModuleFileExtension(BlockName, MajorVersion, MinorVersion,
+ Hashed, UserInfo));
+ }
+
if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
Opts.CodeCompletionAt =
ParsedSourceLocation::FromString(A->getValue());
@@ -943,6 +1033,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
+ Opts.ModulesEmbedFiles = Args.getAllArgValues(OPT_fmodules_embed_file_EQ);
+ Opts.ModulesEmbedAllFiles = Args.hasArg(OPT_fmodules_embed_all_files);
Opts.CodeCompleteOpts.IncludeMacros
= Args.hasArg(OPT_code_completion_macros);
@@ -955,6 +1047,9 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.OverrideRecordLayoutsFile
= Args.getLastArgValue(OPT_foverride_record_layout_EQ);
+ Opts.AuxTriple =
+ llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple));
+
if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
OPT_arcmt_modify,
OPT_arcmt_migrate)) {
@@ -1076,13 +1171,11 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
// Compute the path to the resource directory.
StringRef ClangResourceDir(CLANG_RESOURCE_DIR);
SmallString<128> P(Dir);
- if (ClangResourceDir != "") {
+ if (ClangResourceDir != "")
llvm::sys::path::append(P, ClangResourceDir);
- } else {
- StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX);
- llvm::sys::path::append(P, "..", Twine("lib") + ClangLibdirSuffix, "clang",
- CLANG_VERSION_STRING);
- }
+ else
+ llvm::sys::path::append(P, "..", Twine("lib") + CLANG_LIBDIR_SUFFIX,
+ "clang", CLANG_VERSION_STRING);
return P.str();
}
@@ -1291,7 +1384,7 @@ static Visibility parseVisibility(Arg *arg, ArgList &args,
StringRef value = arg->getValue();
if (value == "default") {
return DefaultVisibility;
- } else if (value == "hidden") {
+ } else if (value == "hidden" || value == "internal") {
return HiddenVisibility;
} else if (value == "protected") {
// FIXME: diagnose if target does not support protected visibility
@@ -1364,7 +1457,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
.Case("CL1.2", LangStandard::lang_opencl12)
.Case("CL2.0", LangStandard::lang_opencl20)
.Default(LangStandard::lang_unspecified);
-
+
if (OpenCLLangStd == LangStandard::lang_unspecified) {
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
@@ -1372,7 +1465,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
else
LangStd = OpenCLLangStd;
}
-
+
CompilerInvocation::setLangDefaults(Opts, IK, LangStd);
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
@@ -1395,6 +1488,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (Args.hasArg(OPT_fcuda_disable_target_call_checks))
Opts.CUDADisableTargetCallChecks = 1;
+ if (Args.hasArg(OPT_fcuda_target_overloads))
+ Opts.CUDATargetOverloads = 1;
+
if (Opts.ObjC1) {
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
StringRef value = arg->getValue();
@@ -1410,22 +1506,41 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ObjCAutoRefCount = 1;
if (!Opts.ObjCRuntime.allowsARC())
Diags.Report(diag::err_arc_unsupported_on_runtime);
+ }
- // Only set ObjCARCWeak if ARC is enabled.
- if (Args.hasArg(OPT_fobjc_runtime_has_weak))
- Opts.ObjCARCWeak = 1;
- else
- Opts.ObjCARCWeak = Opts.ObjCRuntime.allowsWeak();
+ // ObjCWeakRuntime tracks whether the runtime supports __weak, not
+ // whether the feature is actually enabled. This is predominantly
+ // determined by -fobjc-runtime, but we allow it to be overridden
+ // from the command line for testing purposes.
+ if (Args.hasArg(OPT_fobjc_runtime_has_weak))
+ Opts.ObjCWeakRuntime = 1;
+ else
+ Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
+
+ // ObjCWeak determines whether __weak is actually enabled.
+ // Note that we allow -fno-objc-weak to disable this even in ARC mode.
+ if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
+ if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
+ assert(!Opts.ObjCWeak);
+ } else if (Opts.getGC() != LangOptions::NonGC) {
+ Diags.Report(diag::err_objc_weak_with_gc);
+ } else if (!Opts.ObjCWeakRuntime) {
+ Diags.Report(diag::err_objc_weak_unsupported);
+ } else {
+ Opts.ObjCWeak = 1;
+ }
+ } else if (Opts.ObjCAutoRefCount) {
+ Opts.ObjCWeak = Opts.ObjCWeakRuntime;
}
if (Args.hasArg(OPT_fno_objc_infer_related_result_type))
Opts.ObjCInferRelatedResultType = 0;
-
+
if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
Opts.ObjCSubscriptingLegacyRuntime =
(Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX);
}
-
+
if (Args.hasArg(OPT_fgnu89_inline)) {
if (Opts.CPlusPlus)
Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fgnu89-inline"
@@ -1525,14 +1640,13 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data);
Opts.Blocks = Args.hasArg(OPT_fblocks);
Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
+ Opts.Coroutines = Args.hasArg(OPT_fcoroutines);
Opts.Modules = Args.hasArg(OPT_fmodules);
Opts.ModulesStrictDeclUse = Args.hasArg(OPT_fmodules_strict_decluse);
Opts.ModulesDeclUse =
Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
Opts.ModulesLocalVisibility =
Args.hasArg(OPT_fmodules_local_submodule_visibility);
- Opts.ModulesHideInternalLinkage =
- !Args.hasArg(OPT_fno_modules_hide_internal_linkage);
Opts.ModulesSearchAll = Opts.Modules &&
!Args.hasArg(OPT_fno_modules_search_all) &&
Args.hasArg(OPT_fmodules_search_all);
@@ -1578,7 +1692,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags);
Opts.Static = Args.hasArg(OPT_static_define);
Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple);
- Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple
+ Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple
|| Args.hasArg(OPT_fdump_record_layouts);
Opts.DumpVTableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
Opts.SpellChecking = !Args.hasArg(OPT_fno_spell_checking);
@@ -1603,6 +1717,17 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);
Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
+ // __declspec is enabled by default for the PS4 by the driver, and also
+ // enabled for Microsoft Extensions or Borland Extensions, here.
+ //
+ // FIXME: __declspec is also currently enabled for CUDA, but isn't really a
+ // CUDA extension, however it is required for supporting cuda_builtin_vars.h,
+ // which uses __declspec(property). Once that has been rewritten in terms of
+ // something more generic, remove the Opts.CUDA term here.
+ Opts.DeclSpecKeyword =
+ Args.hasFlag(OPT_fdeclspec, OPT_fno_declspec,
+ (Opts.MicrosoftExt || Opts.Borland || Opts.CUDA));
+
if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() &&
Opts.CurrentModule != Opts.ImplementationOfModule) {
Diags.Report(diag::err_conflicting_module_names)
@@ -1622,7 +1747,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
.Case("yes", LangOptions::ASMM_On)
.Default(255)) {
default:
- Diags.Report(diag::err_drv_invalid_value)
+ Diags.Report(diag::err_drv_invalid_value)
<< "-faddress-space-map-mangling=" << A->getValue();
break;
case LangOptions::ASMM_Target:
@@ -1681,6 +1806,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only) ||
Args.hasArg(OPT_cl_finite_math_only) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
+ Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
+ Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
+ Args.hasArg(OPT_cl_fast_relaxed_math);
Opts.RetainCommentsFromSystemHeaders =
Args.hasArg(OPT_fretain_comments_from_system_headers);
@@ -1891,14 +2019,23 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
Res.getTargetOpts());
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
- if (DashX != IK_AST && DashX != IK_LLVM_IR) {
+ if (DashX == IK_AST || DashX == IK_LLVM_IR) {
+ // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
+ // PassManager in BackendUtil.cpp. They need to be initializd no matter
+ // what the input type is.
+ if (Args.hasArg(OPT_fobjc_arc))
+ Res.getLangOpts()->ObjCAutoRefCount = 1;
+ parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
+ Diags, Res.getLangOpts()->Sanitize);
+ } else {
+ // Other LangOpts are only initialzed when the input is not AST or LLVM IR.
ParseLangArgs(*Res.getLangOpts(), Args, DashX, Diags);
if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
Res.getLangOpts()->ObjCExceptions = 1;
}
// FIXME: ParsePreprocessorArgs uses the FileManager to read the contents of
// PCH file and find the original header name. Remove the need to do that in
- // ParsePreprocessorArgs and remove the FileManager
+ // ParsePreprocessorArgs and remove the FileManager
// parameters from the function and the "FileManager.h" #include.
FileManager FileMgr(Res.getFileSystemOpts());
ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, FileMgr, Diags);
@@ -1913,14 +2050,14 @@ namespace {
SmallVector<uint64_t, 16> Data;
unsigned CurBit;
uint64_t CurValue;
-
+
public:
ModuleSignature() : CurBit(0), CurValue(0) { }
-
+
void add(uint64_t Value, unsigned Bits);
void add(StringRef Value);
void flush();
-
+
llvm::APInt getAsInteger() const;
};
}
@@ -1931,10 +2068,10 @@ void ModuleSignature::add(uint64_t Value, unsigned int NumBits) {
CurBit += NumBits;
return;
}
-
+
// Add the current word.
Data.push_back(CurValue);
-
+
if (CurBit)
CurValue = Value >> (64-CurBit);
else
@@ -1945,15 +2082,15 @@ void ModuleSignature::add(uint64_t Value, unsigned int NumBits) {
void ModuleSignature::flush() {
if (CurBit == 0)
return;
-
+
Data.push_back(CurValue);
CurBit = 0;
CurValue = 0;
}
void ModuleSignature::add(StringRef Value) {
- for (StringRef::iterator I = Value.begin(), IEnd = Value.end(); I != IEnd;++I)
- add(*I, 8);
+ for (auto &c : Value)
+ add(c, 8);
}
llvm::APInt ModuleSignature::getAsInteger() const {
@@ -1983,7 +2120,7 @@ std::string CompilerInvocation::getModuleHash() const {
for (StringRef Feature : LangOpts->ModuleFeatures)
code = hash_combine(code, Feature);
-
+
// Extend the signature with the target options.
code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
TargetOpts->ABI);
@@ -1995,7 +2132,7 @@ std::string CompilerInvocation::getModuleHash() const {
const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord);
- for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
+ for (std::vector<std::pair<std::string, bool/*isUndef*/>>::const_iterator
I = getPreprocessorOpts().Macros.begin(),
IEnd = getPreprocessorOpts().Macros.end();
I != IEnd; ++I) {
@@ -2021,6 +2158,12 @@ std::string CompilerInvocation::getModuleHash() const {
// Extend the signature with the user build path.
code = hash_combine(code, hsOpts.ModuleUserBuildPath);
+ // Extend the signature with the module file extensions.
+ const FrontendOptions &frontendOpts = getFrontendOpts();
+ for (auto ext : frontendOpts.ModuleFileExtensions) {
+ code = ext->hashExtension(code);
+ }
+
// Darwin-specific hack: if we have a sysroot, use the contents and
// modification time of
// $sysroot/System/Library/CoreServices/SystemVersion.plist
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index 2afd23fcb9e8..301916422564 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -39,15 +39,13 @@ clang::createInvocationFromCommandLine(ArrayRef<const char *> ArgList,
Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions);
}
- SmallVector<const char *, 16> Args;
- Args.push_back("<clang>"); // FIXME: Remove dummy argument.
- Args.insert(Args.end(), ArgList.begin(), ArgList.end());
+ SmallVector<const char *, 16> Args(ArgList.begin(), ArgList.end());
// FIXME: Find a cleaner way to force the driver into restricted modes.
Args.push_back("-fsyntax-only");
// FIXME: We shouldn't have to pass in the path info.
- driver::Driver TheDriver("clang", llvm::sys::getDefaultTargetTriple(),
+ driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(),
*Diags);
// Don't check that inputs exist, they may have been remapped.
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 0995ab4bf077..93d4a8034696 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -18,6 +18,7 @@
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Serialization/ASTReader.h"
@@ -50,15 +51,8 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
if (!FE)
return;
- StringRef Filename = FE->getName();
-
- // Remove leading "./" (or ".//" or "././" etc.)
- while (Filename.size() > 2 && Filename[0] == '.' &&
- llvm::sys::path::is_separator(Filename[1])) {
- Filename = Filename.substr(1);
- while (llvm::sys::path::is_separator(Filename[0]))
- Filename = Filename.substr(1);
- }
+ StringRef Filename =
+ llvm::sys::path::remove_leading_dotslash(FE->getName());
DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
FileType != SrcMgr::C_User,
@@ -82,6 +76,20 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
}
};
+struct DepCollectorMMCallbacks : public ModuleMapCallbacks {
+ DependencyCollector &DepCollector;
+ DepCollectorMMCallbacks(DependencyCollector &DC) : DepCollector(DC) {}
+
+ void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry,
+ bool IsSystem) override {
+ StringRef Filename = Entry.getName();
+ DepCollector.maybeAddDependency(Filename, /*FromModule*/false,
+ /*IsSystem*/IsSystem,
+ /*IsModuleFile*/false,
+ /*IsMissing*/false);
+ }
+};
+
struct DepCollectorASTListener : public ASTReaderListener {
DependencyCollector &DepCollector;
DepCollectorASTListener(DependencyCollector &L) : DepCollector(L) { }
@@ -89,14 +97,15 @@ struct DepCollectorASTListener : public ASTReaderListener {
bool needsSystemInputFileVisitation() override {
return DepCollector.needSystemDependencies();
}
- void visitModuleFile(StringRef Filename) override {
+ void visitModuleFile(StringRef Filename,
+ serialization::ModuleKind Kind) override {
DepCollector.maybeAddDependency(Filename, /*FromModule*/true,
/*IsSystem*/false, /*IsModuleFile*/true,
/*IsMissing*/false);
}
bool visitInputFile(StringRef Filename, bool IsSystem,
- bool IsOverridden) override {
- if (IsOverridden)
+ bool IsOverridden, bool IsExplicitModule) override {
+ if (IsOverridden || IsExplicitModule)
return true;
DepCollector.maybeAddDependency(Filename, /*FromModule*/true, IsSystem,
@@ -132,6 +141,8 @@ DependencyCollector::~DependencyCollector() { }
void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
PP.addPPCallbacks(
llvm::make_unique<DepCollectorPPCallbacks>(*this, PP.getSourceManager()));
+ PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
+ llvm::make_unique<DepCollectorMMCallbacks>(*this));
}
void DependencyCollector::attachToASTReader(ASTReader &R) {
R.addListener(llvm::make_unique<DepCollectorASTListener>(*this));
@@ -165,7 +176,11 @@ public:
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
SeenMissingHeader(false),
IncludeModuleFiles(Opts.IncludeModuleFiles),
- OutputFormat(Opts.OutputFormat) {}
+ OutputFormat(Opts.OutputFormat) {
+ for (auto ExtraDep : Opts.ExtraDeps) {
+ AddFilename(ExtraDep);
+ }
+ }
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
@@ -185,6 +200,17 @@ public:
bool includeModuleFiles() const { return IncludeModuleFiles; }
};
+class DFGMMCallback : public ModuleMapCallbacks {
+ DFGImpl &Parent;
+public:
+ DFGMMCallback(DFGImpl &Parent) : Parent(Parent) {}
+ void moduleMapFileRead(SourceLocation Loc, const FileEntry &Entry,
+ bool IsSystem) override {
+ if (!IsSystem || Parent.includeSystemHeaders())
+ Parent.AddFilename(Entry.getName());
+ }
+};
+
class DFGASTReaderListener : public ASTReaderListener {
DFGImpl &Parent;
public:
@@ -194,9 +220,10 @@ public:
bool needsSystemInputFileVisitation() override {
return Parent.includeSystemHeaders();
}
- void visitModuleFile(StringRef Filename) override;
+ void visitModuleFile(StringRef Filename,
+ serialization::ModuleKind Kind) override;
bool visitInputFile(StringRef Filename, bool isSystem,
- bool isOverridden) override;
+ bool isOverridden, bool isExplicitModule) override;
};
}
@@ -217,6 +244,8 @@ DependencyFileGenerator *DependencyFileGenerator::CreateAndAttachToPreprocessor(
DFGImpl *Callback = new DFGImpl(&PP, Opts);
PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callback));
+ PP.getHeaderSearchInfo().getModuleMap().addModuleMapCallbacks(
+ llvm::make_unique<DFGMMCallback>(*Callback));
return new DependencyFileGenerator(Callback);
}
@@ -259,15 +288,7 @@ void DFGImpl::FileChanged(SourceLocation Loc,
if (!FileMatchesDepCriteria(Filename.data(), FileType))
return;
- // Remove leading "./" (or ".//" or "././" etc.)
- while (Filename.size() > 2 && Filename[0] == '.' &&
- llvm::sys::path::is_separator(Filename[1])) {
- Filename = Filename.substr(1);
- while (llvm::sys::path::is_separator(Filename[0]))
- Filename = Filename.substr(1);
- }
-
- AddFilename(Filename);
+ AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
}
void DFGImpl::InclusionDirective(SourceLocation HashLoc,
@@ -438,16 +459,18 @@ void DFGImpl::OutputDependencyFile() {
}
bool DFGASTReaderListener::visitInputFile(llvm::StringRef Filename,
- bool IsSystem, bool IsOverridden) {
+ bool IsSystem, bool IsOverridden,
+ bool IsExplicitModule) {
assert(!IsSystem || needsSystemInputFileVisitation());
- if (IsOverridden)
+ if (IsOverridden || IsExplicitModule)
return true;
Parent.AddFilename(Filename);
return true;
}
-void DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename) {
+void DFGASTReaderListener::visitModuleFile(llvm::StringRef Filename,
+ serialization::ModuleKind Kind) {
if (Parent.includeModuleFiles())
Parent.AddFilename(Filename);
}
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index c63e98dbe4f1..caf1f0dce99f 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -169,9 +169,7 @@ void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
// If this location is within a macro, walk from UnexpandedLoc up to Loc
// and produce a macro backtrace.
if (UnexpandedLoc.isValid() && UnexpandedLoc.isMacroID()) {
- unsigned MacroDepth = 0;
- emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM,
- MacroDepth);
+ emitMacroExpansions(UnexpandedLoc, Level, MutableRanges, FixItHints, *SM);
}
}
@@ -247,7 +245,7 @@ void DiagnosticRenderer::emitIncludeStackRecursively(SourceLocation Loc,
// import stack rather than the
// FIXME: We want submodule granularity here.
std::pair<SourceLocation, StringRef> Imported = SM.getModuleImportLoc(Loc);
- if (Imported.first.isValid()) {
+ if (!Imported.second.empty()) {
// This location was imported by a module. Emit the module import stack.
emitImportStackRecursively(Imported.first, Imported.second, SM);
return;
@@ -278,13 +276,11 @@ void DiagnosticRenderer::emitImportStack(SourceLocation Loc,
void DiagnosticRenderer::emitImportStackRecursively(SourceLocation Loc,
StringRef ModuleName,
const SourceManager &SM) {
- if (Loc.isInvalid()) {
+ if (ModuleName.empty()) {
return;
}
PresumedLoc PLoc = SM.getPresumedLoc(Loc, DiagOpts->ShowPresumedLoc);
- if (PLoc.isInvalid())
- return;
// Emit the other import frames first.
std::pair<SourceLocation, StringRef> NextImportLoc
@@ -310,6 +306,81 @@ void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
}
}
+/// A recursive function to trace all possible backtrace locations
+/// to match the \p CaretLocFileID.
+static SourceLocation
+retrieveMacroLocation(SourceLocation Loc, FileID MacroFileID,
+ FileID CaretFileID,
+ const SmallVectorImpl<FileID> &CommonArgExpansions,
+ bool IsBegin, const SourceManager *SM) {
+ assert(SM->getFileID(Loc) == MacroFileID);
+ if (MacroFileID == CaretFileID)
+ return Loc;
+ if (!Loc.isMacroID())
+ return SourceLocation();
+
+ SourceLocation MacroLocation, MacroArgLocation;
+
+ if (SM->isMacroArgExpansion(Loc)) {
+ // Only look at the immediate spelling location of this macro argument if
+ // the other location in the source range is also present in that expansion.
+ if (std::binary_search(CommonArgExpansions.begin(),
+ CommonArgExpansions.end(), MacroFileID))
+ MacroLocation = SM->getImmediateSpellingLoc(Loc);
+ MacroArgLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first
+ : SM->getImmediateExpansionRange(Loc).second;
+ } else {
+ MacroLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first
+ : SM->getImmediateExpansionRange(Loc).second;
+ MacroArgLocation = SM->getImmediateSpellingLoc(Loc);
+ }
+
+ if (MacroLocation.isValid()) {
+ MacroFileID = SM->getFileID(MacroLocation);
+ MacroLocation =
+ retrieveMacroLocation(MacroLocation, MacroFileID, CaretFileID,
+ CommonArgExpansions, IsBegin, SM);
+ if (MacroLocation.isValid())
+ return MacroLocation;
+ }
+
+ MacroFileID = SM->getFileID(MacroArgLocation);
+ return retrieveMacroLocation(MacroArgLocation, MacroFileID, CaretFileID,
+ CommonArgExpansions, IsBegin, SM);
+}
+
+/// Walk up the chain of macro expansions and collect the FileIDs identifying the
+/// expansions.
+static void getMacroArgExpansionFileIDs(SourceLocation Loc,
+ SmallVectorImpl<FileID> &IDs,
+ bool IsBegin, const SourceManager *SM) {
+ while (Loc.isMacroID()) {
+ if (SM->isMacroArgExpansion(Loc)) {
+ IDs.push_back(SM->getFileID(Loc));
+ Loc = SM->getImmediateSpellingLoc(Loc);
+ } else {
+ auto ExpRange = SM->getImmediateExpansionRange(Loc);
+ Loc = IsBegin ? ExpRange.first : ExpRange.second;
+ }
+ }
+}
+
+/// Collect the expansions of the begin and end locations and compute the set
+/// intersection. Produces a sorted vector of FileIDs in CommonArgExpansions.
+static void computeCommonMacroArgExpansionFileIDs(
+ SourceLocation Begin, SourceLocation End, const SourceManager *SM,
+ SmallVectorImpl<FileID> &CommonArgExpansions) {
+ SmallVector<FileID, 4> BeginArgExpansions;
+ SmallVector<FileID, 4> EndArgExpansions;
+ getMacroArgExpansionFileIDs(Begin, BeginArgExpansions, /*IsBegin=*/true, SM);
+ getMacroArgExpansionFileIDs(End, EndArgExpansions, /*IsBegin=*/false, SM);
+ std::sort(BeginArgExpansions.begin(), BeginArgExpansions.end());
+ std::sort(EndArgExpansions.begin(), EndArgExpansions.end());
+ std::set_intersection(BeginArgExpansions.begin(), BeginArgExpansions.end(),
+ EndArgExpansions.begin(), EndArgExpansions.end(),
+ std::back_inserter(CommonArgExpansions));
+}
+
// Helper function to fix up source ranges. It takes in an array of ranges,
// and outputs an array of ranges where we want to draw the range highlighting
// around the location specified by CaretLoc.
@@ -327,9 +398,9 @@ static void mapDiagnosticRanges(
const SourceManager *SM) {
FileID CaretLocFileID = SM->getFileID(CaretLoc);
- for (ArrayRef<CharSourceRange>::const_iterator I = Ranges.begin(),
- E = Ranges.end();
- I != E; ++I) {
+ for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
+ if (I->isInvalid()) continue;
+
SourceLocation Begin = I->getBegin(), End = I->getEnd();
bool IsTokenRange = I->isTokenRange();
@@ -358,27 +429,19 @@ static void mapDiagnosticRanges(
}
}
- while (Begin.isMacroID() && BeginFileID != CaretLocFileID) {
- if (SM->isMacroArgExpansion(Begin)) {
- Begin = SM->getImmediateSpellingLoc(Begin);
- End = SM->getImmediateSpellingLoc(End);
- } else {
- Begin = SM->getImmediateExpansionRange(Begin).first;
- End = SM->getImmediateExpansionRange(End).second;
- }
- BeginFileID = SM->getFileID(Begin);
- if (BeginFileID != SM->getFileID(End)) {
- // FIXME: Ugly hack to stop a crash; this code is making bad
- // assumptions and it's too complicated for me to reason
- // about.
- Begin = End = SourceLocation();
- break;
- }
- }
+ // Do the backtracking.
+ SmallVector<FileID, 4> CommonArgExpansions;
+ computeCommonMacroArgExpansionFileIDs(Begin, End, SM, CommonArgExpansions);
+ Begin = retrieveMacroLocation(Begin, BeginFileID, CaretLocFileID,
+ CommonArgExpansions, /*IsBegin=*/true, SM);
+ End = retrieveMacroLocation(End, BeginFileID, CaretLocFileID,
+ CommonArgExpansions, /*IsBegin=*/false, SM);
+ if (Begin.isInvalid() || End.isInvalid()) continue;
// Return the spelling location of the beginning and end of the range.
Begin = SM->getSpellingLoc(Begin);
End = SM->getSpellingLoc(End);
+
SpellingRanges.push_back(CharSourceRange(SourceRange(Begin, End),
IsTokenRange));
}
@@ -394,6 +457,96 @@ void DiagnosticRenderer::emitCaret(SourceLocation Loc,
emitCodeContext(Loc, Level, SpellingRanges, Hints, SM);
}
+/// \brief A helper function for emitMacroExpansion to print the
+/// macro expansion message
+void DiagnosticRenderer::emitSingleMacroExpansion(
+ SourceLocation Loc,
+ DiagnosticsEngine::Level Level,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager &SM) {
+ // Find the spelling location for the macro definition. We must use the
+ // spelling location here to avoid emitting a macro backtrace for the note.
+ SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
+
+ // Map the ranges into the FileID of the diagnostic location.
+ SmallVector<CharSourceRange, 4> SpellingRanges;
+ mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
+
+ SmallString<100> MessageStorage;
+ llvm::raw_svector_ostream Message(MessageStorage);
+ StringRef MacroName = getImmediateMacroName(Loc, SM, LangOpts);
+ if (MacroName.empty())
+ Message << "expanded from here";
+ else
+ Message << "expanded from macro '" << MacroName << "'";
+
+ emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, Message.str(),
+ SpellingRanges, None, &SM);
+}
+
+/// Check that the macro argument location of Loc starts with ArgumentLoc.
+/// The starting location of the macro expansions is used to differeniate
+/// different macro expansions.
+static bool checkLocForMacroArgExpansion(SourceLocation Loc,
+ const SourceManager &SM,
+ SourceLocation ArgumentLoc) {
+ SourceLocation MacroLoc;
+ if (SM.isMacroArgExpansion(Loc, &MacroLoc)) {
+ if (ArgumentLoc == MacroLoc) return true;
+ }
+
+ return false;
+}
+
+/// Check if all the locations in the range have the same macro argument
+/// expansion, and that that expansion starts with ArgumentLoc.
+static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
+ const SourceManager &SM,
+ SourceLocation ArgumentLoc) {
+ SourceLocation BegLoc = Range.getBegin(), EndLoc = Range.getEnd();
+ while (BegLoc != EndLoc) {
+ if (!checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc))
+ return false;
+ BegLoc.getLocWithOffset(1);
+ }
+
+ return checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc);
+}
+
+/// A helper function to check if the current ranges are all inside the same
+/// macro argument expansion as Loc.
+static bool checkRangesForMacroArgExpansion(SourceLocation Loc,
+ ArrayRef<CharSourceRange> Ranges,
+ const SourceManager &SM) {
+ assert(Loc.isMacroID() && "Must be a macro expansion!");
+
+ SmallVector<CharSourceRange, 4> SpellingRanges;
+ mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
+
+ /// Count all valid ranges.
+ unsigned ValidCount = 0;
+ for (auto I : Ranges)
+ if (I.isValid()) ValidCount++;
+
+ if (ValidCount > SpellingRanges.size())
+ return false;
+
+ /// To store the source location of the argument location.
+ SourceLocation ArgumentLoc;
+
+ /// Set the ArgumentLoc to the beginning location of the expansion of Loc
+ /// so to check if the ranges expands to the same beginning location.
+ if (!SM.isMacroArgExpansion(Loc,&ArgumentLoc))
+ return false;
+
+ for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) {
+ if (!checkRangeForMacroArgExpansion(*I, SM, ArgumentLoc))
+ return false;
+ }
+
+ return true;
+}
+
/// \brief Recursively emit notes for each macro expansion and caret
/// diagnostics where appropriate.
///
@@ -405,71 +558,68 @@ void DiagnosticRenderer::emitCaret(SourceLocation Loc,
/// \param Level The diagnostic level currently being emitted.
/// \param Ranges The underlined ranges for this code snippet.
/// \param Hints The FixIt hints active for this diagnostic.
-/// \param OnMacroInst The current depth of the macro expansion stack.
void DiagnosticRenderer::emitMacroExpansions(SourceLocation Loc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints,
- const SourceManager &SM,
- unsigned &MacroDepth,
- unsigned OnMacroInst) {
- assert(!Loc.isInvalid() && "must have a valid source location here");
-
- // Walk up to the caller of this macro, and produce a backtrace down to there.
- SourceLocation OneLevelUp = SM.getImmediateMacroCallerLoc(Loc);
- if (OneLevelUp.isMacroID())
- emitMacroExpansions(OneLevelUp, Level, Ranges, Hints, SM,
- MacroDepth, OnMacroInst + 1);
- else
- MacroDepth = OnMacroInst + 1;
-
- unsigned MacroSkipStart = 0, MacroSkipEnd = 0;
- if (MacroDepth > DiagOpts->MacroBacktraceLimit &&
- DiagOpts->MacroBacktraceLimit != 0) {
- MacroSkipStart = DiagOpts->MacroBacktraceLimit / 2 +
- DiagOpts->MacroBacktraceLimit % 2;
- MacroSkipEnd = MacroDepth - DiagOpts->MacroBacktraceLimit / 2;
+ const SourceManager &SM) {
+ assert(Loc.isValid() && "must have a valid source location here");
+
+ // Produce a stack of macro backtraces.
+ SmallVector<SourceLocation, 8> LocationStack;
+ unsigned IgnoredEnd = 0;
+ while (Loc.isMacroID()) {
+ // If this is the expansion of a macro argument, point the caret at the
+ // use of the argument in the definition of the macro, not the expansion.
+ if (SM.isMacroArgExpansion(Loc))
+ LocationStack.push_back(SM.getImmediateExpansionRange(Loc).first);
+ else
+ LocationStack.push_back(Loc);
+
+ if (checkRangesForMacroArgExpansion(Loc, Ranges, SM))
+ IgnoredEnd = LocationStack.size();
+
+ Loc = SM.getImmediateMacroCallerLoc(Loc);
+
+ // Once the location no longer points into a macro, try stepping through
+ // the last found location. This sometimes produces additional useful
+ // backtraces.
+ if (Loc.isFileID())
+ Loc = SM.getImmediateMacroCallerLoc(LocationStack.back());
+ assert(Loc.isValid() && "must have a valid source location here");
}
- // Whether to suppress printing this macro expansion.
- bool Suppressed = (OnMacroInst >= MacroSkipStart &&
- OnMacroInst < MacroSkipEnd);
-
- if (Suppressed) {
- // Tell the user that we've skipped contexts.
- if (OnMacroInst == MacroSkipStart) {
- SmallString<200> MessageStorage;
- llvm::raw_svector_ostream Message(MessageStorage);
- Message << "(skipping " << (MacroSkipEnd - MacroSkipStart)
- << " expansions in backtrace; use -fmacro-backtrace-limit=0 to "
- "see all)";
- emitBasicNote(Message.str());
- }
+ LocationStack.erase(LocationStack.begin(),
+ LocationStack.begin() + IgnoredEnd);
+
+ unsigned MacroDepth = LocationStack.size();
+ unsigned MacroLimit = DiagOpts->MacroBacktraceLimit;
+ if (MacroDepth <= MacroLimit || MacroLimit == 0) {
+ for (auto I = LocationStack.rbegin(), E = LocationStack.rend();
+ I != E; ++I)
+ emitSingleMacroExpansion(*I, Level, Ranges, SM);
return;
}
- // Find the spelling location for the macro definition. We must use the
- // spelling location here to avoid emitting a macro bactrace for the note.
- SourceLocation SpellingLoc = Loc;
- // If this is the expansion of a macro argument, point the caret at the
- // use of the argument in the definition of the macro, not the expansion.
- if (SM.isMacroArgExpansion(Loc))
- SpellingLoc = SM.getImmediateExpansionRange(Loc).first;
- SpellingLoc = SM.getSpellingLoc(SpellingLoc);
+ unsigned MacroStartMessages = MacroLimit / 2;
+ unsigned MacroEndMessages = MacroLimit / 2 + MacroLimit % 2;
- // Map the ranges into the FileID of the diagnostic location.
- SmallVector<CharSourceRange, 4> SpellingRanges;
- mapDiagnosticRanges(Loc, Ranges, SpellingRanges, &SM);
+ for (auto I = LocationStack.rbegin(),
+ E = LocationStack.rbegin() + MacroStartMessages;
+ I != E; ++I)
+ emitSingleMacroExpansion(*I, Level, Ranges, SM);
- SmallString<100> MessageStorage;
+ SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
- StringRef MacroName = getImmediateMacroName(Loc, SM, LangOpts);
- if (MacroName.empty())
- Message << "expanded from here";
- else
- Message << "expanded from macro '" << MacroName << "'";
- emitDiagnostic(SpellingLoc, DiagnosticsEngine::Note, Message.str(),
- SpellingRanges, None, &SM);
+ Message << "(skipping " << (MacroDepth - MacroLimit)
+ << " expansions in backtrace; use -fmacro-backtrace-limit=0 to "
+ "see all)";
+ emitBasicNote(Message.str());
+
+ for (auto I = LocationStack.rend() - MacroEndMessages,
+ E = LocationStack.rend();
+ I != E; ++I)
+ emitSingleMacroExpansion(*I, Level, Ranges, SM);
}
DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
@@ -492,8 +642,11 @@ void DiagnosticNoteRenderer::emitImportLocation(SourceLocation Loc,
// Generate a note indicating the include location.
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
- Message << "in module '" << ModuleName << "' imported from "
- << PLoc.getFilename() << ':' << PLoc.getLine() << ":";
+ Message << "in module '" << ModuleName;
+ if (PLoc.isValid())
+ Message << "' imported from " << PLoc.getFilename() << ':'
+ << PLoc.getLine();
+ Message << ":";
emitNote(Loc, Message.str(), &SM);
}
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 3e0f7a12c3b3..ecef92e0a7dd 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -190,9 +190,9 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
- std::unique_ptr<ASTUnit> AST =
- ASTUnit::LoadFromASTFile(InputFile, CI.getPCHContainerReader(),
- Diags, CI.getFileSystemOpts());
+ std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
+ InputFile, CI.getPCHContainerReader(), Diags, CI.getFileSystemOpts(),
+ CI.getCodeGenOpts().DebugTypeExtRefs);
if (!AST)
goto failure;
@@ -284,7 +284,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (!Found) {
CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
- return true;
+ goto failure;
}
}
}
@@ -375,7 +375,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (CI.getLangOpts().Modules)
CI.createModuleManager();
- PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
+ PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
PP.getLangOpts());
} else {
// FIXME: If this is a problem, recover from it by creating a multiplex
@@ -442,9 +442,11 @@ bool FrontendAction::Execute() {
// there were any module-build failures.
if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
CI.hasPreprocessor()) {
- GlobalModuleIndex::writeIndex(
- CI.getFileManager(), CI.getPCHContainerReader(),
- CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+ StringRef Cache =
+ CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
+ if (!Cache.empty())
+ GlobalModuleIndex::writeIndex(CI.getFileManager(),
+ CI.getPCHContainerReader(), Cache);
}
return true;
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 40277bdaa52d..d6c88d20fc2a 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -91,12 +91,10 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
auto Buffer = std::make_shared<PCHBuffer>();
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(llvm::make_unique<PCHGenerator>(
- CI.getPreprocessor(), OutputFile, nullptr, Sysroot, Buffer));
- Consumers.push_back(
- CI.getPCHContainerWriter().CreatePCHContainerGenerator(
- CI.getDiagnostics(), CI.getHeaderSearchOpts(),
- CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(),
- InFile, OutputFile, OS, Buffer));
+ CI.getPreprocessor(), OutputFile, nullptr, Sysroot,
+ Buffer, CI.getFrontendOpts().ModuleFileExtensions));
+ Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
+ CI, InFile, OutputFile, OS, Buffer));
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
}
@@ -136,13 +134,15 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
auto Buffer = std::make_shared<PCHBuffer>();
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+
Consumers.push_back(llvm::make_unique<PCHGenerator>(
- CI.getPreprocessor(), OutputFile, Module, Sysroot, Buffer));
- Consumers.push_back(
- CI.getPCHContainerWriter().CreatePCHContainerGenerator(
- CI.getDiagnostics(), CI.getHeaderSearchOpts(),
- CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(),
- InFile, OutputFile, OS, Buffer));
+ CI.getPreprocessor(), OutputFile, Module, Sysroot,
+ Buffer, CI.getFrontendOpts().ModuleFileExtensions,
+ /*AllowASTWithErrors=*/false,
+ /*IncludeTimestamps=*/
+ +CI.getFrontendOpts().BuildingImplicitModule));
+ Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
+ CI, InFile, OutputFile, OS, Buffer));
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
}
@@ -268,14 +268,26 @@ collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
StringRef Filename) {
- // Find the module map file.
- const FileEntry *ModuleMap = CI.getFileManager().getFile(Filename);
+ // Find the module map file.
+ const FileEntry *ModuleMap =
+ CI.getFileManager().getFile(Filename, /*openFile*/true);
if (!ModuleMap) {
CI.getDiagnostics().Report(diag::err_module_map_not_found)
<< Filename;
return false;
}
+ // Set up embedding for any specified files. Do this before we load any
+ // source files, including the primary module map for the compilation.
+ for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
+ if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true))
+ CI.getSourceManager().setFileIsTransient(FE);
+ else
+ CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
+ }
+ if (CI.getFrontendOpts().ModulesEmbedAllFiles)
+ CI.getSourceManager().setAllFilesAreTransient(true);
+
// Parse the module map file.
HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
if (HS.loadModuleMapFile(ModuleMap, IsSystem))
@@ -416,6 +428,7 @@ void VerifyPCHAction::ExecuteAction() {
const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
std::unique_ptr<ASTReader> Reader(new ASTReader(
CI.getPreprocessor(), CI.getASTContext(), CI.getPCHContainerReader(),
+ CI.getFrontendOpts().ModuleFileExtensions,
Sysroot.empty() ? "" : Sysroot.c_str(),
/*DisableValidation*/ false,
/*AllowPCHWithCompilerErrors*/ false,
@@ -559,6 +572,20 @@ namespace {
}
return false;
}
+
+ /// Indicates that a particular module file extension has been read.
+ void readModuleFileExtension(
+ const ModuleFileExtensionMetadata &Metadata) override {
+ Out.indent(2) << "Module file extension '"
+ << Metadata.BlockName << "' " << Metadata.MajorVersion
+ << "." << Metadata.MinorVersion;
+ if (!Metadata.UserInfo.empty()) {
+ Out << ": ";
+ Out.write_escaped(Metadata.UserInfo);
+ }
+
+ Out << "\n";
+ }
#undef DUMP_BOOLEAN
};
}
@@ -578,7 +605,8 @@ void DumpModuleInfoAction::ExecuteAction() {
DumpModuleInfoListener Listener(Out);
ASTReader::readASTFileControlBlock(
getCurrentFile(), getCompilerInstance().getFileManager(),
- getCompilerInstance().getPCHContainerReader(), Listener);
+ getCompilerInstance().getPCHContainerReader(),
+ /*FindModuleFileExtensions=*/true, Listener);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp
index 5732e5b3fb73..0bc1169ba0a9 100644
--- a/lib/Frontend/HeaderIncludeGen.cpp
+++ b/lib/Frontend/HeaderIncludeGen.cpp
@@ -46,7 +46,36 @@ public:
};
}
-void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
+static void PrintHeaderInfo(raw_ostream *OutputFile, const char* Filename,
+ bool ShowDepth, unsigned CurrentIncludeDepth,
+ bool MSStyle) {
+ // Write to a temporary string to avoid unnecessary flushing on errs().
+ SmallString<512> Pathname(Filename);
+ if (!MSStyle)
+ Lexer::Stringify(Pathname);
+
+ SmallString<256> Msg;
+ if (MSStyle)
+ Msg += "Note: including file:";
+
+ if (ShowDepth) {
+ // The main source file is at depth 1, so skip one dot.
+ for (unsigned i = 1; i != CurrentIncludeDepth; ++i)
+ Msg += MSStyle ? ' ' : '.';
+
+ if (!MSStyle)
+ Msg += ' ';
+ }
+ Msg += Pathname;
+ Msg += '\n';
+
+ OutputFile->write(Msg.data(), Msg.size());
+ OutputFile->flush();
+}
+
+void clang::AttachHeaderIncludeGen(Preprocessor &PP,
+ const std::vector<std::string> &ExtraHeaders,
+ bool ShowAllHeaders,
StringRef OutputPath, bool ShowDepth,
bool MSStyle) {
raw_ostream *OutputFile = MSStyle ? &llvm::outs() : &llvm::errs();
@@ -63,12 +92,19 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
delete OS;
} else {
OS->SetUnbuffered();
- OS->SetUseAtomicWrites(true);
OutputFile = OS;
OwnsOutputFile = true;
}
}
+ // Print header info for extra headers, pretending they were discovered
+ // by the regular preprocessor. The primary use case is to support
+ // proper generation of Make / Ninja file dependencies for implicit includes,
+ // such as sanitizer blacklists. It's only important for cl.exe
+ // compatibility, the GNU way to generate rules is -M / -MM / -MD / -MMD.
+ for (auto Header : ExtraHeaders) {
+ PrintHeaderInfo(OutputFile, Header.c_str(), ShowDepth, 2, MSStyle);
+ }
PP.addPPCallbacks(llvm::make_unique<HeaderIncludesCallback>(&PP,
ShowAllHeaders,
OutputFile,
@@ -112,27 +148,7 @@ void HeaderIncludesCallback::FileChanged(SourceLocation Loc,
// Dump the header include information we are past the predefines buffer or
// are showing all headers.
if (ShowHeader && Reason == PPCallbacks::EnterFile) {
- // Write to a temporary string to avoid unnecessary flushing on errs().
- SmallString<512> Filename(UserLoc.getFilename());
- if (!MSStyle)
- Lexer::Stringify(Filename);
-
- SmallString<256> Msg;
- if (MSStyle)
- Msg += "Note: including file:";
-
- if (ShowDepth) {
- // The main source file is at depth 1, so skip one dot.
- for (unsigned i = 1; i != CurrentIncludeDepth; ++i)
- Msg += MSStyle ? ' ' : '.';
-
- if (!MSStyle)
- Msg += ' ';
- }
- Msg += Filename;
- Msg += '\n';
-
- OutputFile->write(Msg.data(), Msg.size());
- OutputFile->flush();
+ PrintHeaderInfo(OutputFile, UserLoc.getFilename(),
+ ShowDepth, CurrentIncludeDepth, MSStyle);
}
}
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index e3a17c922fb8..26bab0db5347 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -15,6 +15,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Config/config.h" // C_INCLUDE_DIRS
+#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -215,6 +216,8 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::OpenBSD:
case llvm::Triple::Bitrig:
case llvm::Triple::NaCl:
+ case llvm::Triple::PS4:
+ case llvm::Triple::ELFIAMCU:
break;
case llvm::Triple::Win32:
if (triple.getEnvironment() != llvm::Triple::Cygnus)
@@ -246,10 +249,8 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
if (CIncludeDirs != "") {
SmallVector<StringRef, 5> dirs;
CIncludeDirs.split(dirs, ":");
- for (SmallVectorImpl<StringRef>::iterator i = dirs.begin();
- i != dirs.end();
- ++i)
- AddPath(*i, ExternCSystem, false);
+ for (StringRef dir : dirs)
+ AddPath(dir, ExternCSystem, false);
return;
}
@@ -319,7 +320,30 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::CloudABI:
case llvm::Triple::RTEMS:
case llvm::Triple::NaCl:
+ case llvm::Triple::ELFIAMCU:
break;
+ case llvm::Triple::PS4: {
+ // <isysroot> gets prepended later in AddPath().
+ std::string BaseSDKPath = "";
+ if (!HasSysroot) {
+ const char *envValue = getenv("SCE_PS4_SDK_DIR");
+ if (envValue)
+ BaseSDKPath = envValue;
+ else {
+ // HSOpts.ResourceDir variable contains the location of Clang's
+ // resource files.
+ // Assuming that Clang is configured for PS4 without
+ // --with-clang-resource-dir option, the location of Clang's resource
+ // files is <SDK_DIR>/host_tools/lib/clang
+ SmallString<128> P = StringRef(HSOpts.ResourceDir);
+ llvm::sys::path::append(P, "../../..");
+ BaseSDKPath = P.str();
+ }
+ }
+ AddPath(BaseSDKPath + "/target/include", System, false);
+ if (triple.isPS4CPU())
+ AddPath(BaseSDKPath + "/target/include_common", System, false);
+ }
default:
AddPath("/usr/include", ExternCSystem, false);
break;
@@ -387,10 +411,7 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
}
break;
case llvm::Triple::DragonFly:
- if (llvm::sys::fs::exists("/usr/lib/gcc47"))
- AddPath("/usr/include/c++/4.7", CXXSystem, false);
- else
- AddPath("/usr/include/c++/4.4", CXXSystem, false);
+ AddPath("/usr/include/c++/5.0", CXXSystem, false);
break;
case llvm::Triple::OpenBSD: {
std::string t = triple.getTriple();
@@ -404,10 +425,6 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
AddGnuCPlusPlusIncludePaths("/usr/gnu/include/c++/4.4.3",
"", "", "", triple);
break;
- case llvm::Triple::Solaris:
- AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/",
- "i386-pc-solaris2.11", "", "", triple);
- break;
default:
break;
}
@@ -453,11 +470,6 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
AddUnmappedPath(P, CXXSystem, false);
}
}
- // On Solaris, include the support directory for things like xlocale and
- // fudged system headers.
- if (triple.getOS() == llvm::Triple::Solaris)
- AddPath("/usr/include/c++/v1/support/solaris", CXXSystem, false);
-
AddPath("/usr/include/c++/v1", CXXSystem, false);
} else {
AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
@@ -568,39 +580,33 @@ void InitHeaderSearch::Realize(const LangOptions &Lang) {
SearchList.reserve(IncludePath.size());
// Quoted arguments go first.
- for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
- it != ie; ++it) {
- if (it->first == Quoted)
- SearchList.push_back(it->second);
- }
+ for (auto &Include : IncludePath)
+ if (Include.first == Quoted)
+ SearchList.push_back(Include.second);
+
// Deduplicate and remember index.
RemoveDuplicates(SearchList, 0, Verbose);
unsigned NumQuoted = SearchList.size();
- for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
- it != ie; ++it) {
- if (it->first == Angled || it->first == IndexHeaderMap)
- SearchList.push_back(it->second);
- }
+ for (auto &Include : IncludePath)
+ if (Include.first == Angled || Include.first == IndexHeaderMap)
+ SearchList.push_back(Include.second);
RemoveDuplicates(SearchList, NumQuoted, Verbose);
unsigned NumAngled = SearchList.size();
- for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
- it != ie; ++it) {
- if (it->first == System || it->first == ExternCSystem ||
- (!Lang.ObjC1 && !Lang.CPlusPlus && it->first == CSystem) ||
- (/*FIXME !Lang.ObjC1 && */Lang.CPlusPlus && it->first == CXXSystem) ||
- (Lang.ObjC1 && !Lang.CPlusPlus && it->first == ObjCSystem) ||
- (Lang.ObjC1 && Lang.CPlusPlus && it->first == ObjCXXSystem))
- SearchList.push_back(it->second);
- }
-
- for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
- it != ie; ++it) {
- if (it->first == After)
- SearchList.push_back(it->second);
- }
+ for (auto &Include : IncludePath)
+ if (Include.first == System || Include.first == ExternCSystem ||
+ (!Lang.ObjC1 && !Lang.CPlusPlus && Include.first == CSystem) ||
+ (/*FIXME !Lang.ObjC1 && */ Lang.CPlusPlus &&
+ Include.first == CXXSystem) ||
+ (Lang.ObjC1 && !Lang.CPlusPlus && Include.first == ObjCSystem) ||
+ (Lang.ObjC1 && Lang.CPlusPlus && Include.first == ObjCXXSystem))
+ SearchList.push_back(Include.second);
+
+ for (auto &Include : IncludePath)
+ if (Include.first == After)
+ SearchList.push_back(Include.second);
// Remove duplicates across both the Angled and System directories. GCC does
// this and failing to remove duplicates across these two groups breaks
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 0791494f7919..15aa54607ced 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -20,6 +20,7 @@
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/PTHManager.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/ASTReader.h"
@@ -323,15 +324,17 @@ static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts,
Out << "template<typename _Tp> struct __is_scalar;\n"
<< "\n";
+
+ if (LangOpts.ObjCAutoRefCount) {
+ Out << "template<typename _Tp>\n"
+ << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n"
+ << " enum { __value = 0 };\n"
+ << " typedef __false_type __type;\n"
+ << "};\n"
+ << "\n";
+ }
- Out << "template<typename _Tp>\n"
- << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n"
- << " enum { __value = 0 };\n"
- << " typedef __false_type __type;\n"
- << "};\n"
- << "\n";
-
- if (LangOpts.ObjCARCWeak) {
+ if (LangOpts.ObjCWeak) {
Out << "template<typename _Tp>\n"
<< "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n"
<< " enum { __value = 0 };\n"
@@ -340,13 +343,15 @@ static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts,
<< "\n";
}
- Out << "template<typename _Tp>\n"
- << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))"
- << " _Tp> {\n"
- << " enum { __value = 0 };\n"
- << " typedef __false_type __type;\n"
- << "};\n"
- << "\n";
+ if (LangOpts.ObjCAutoRefCount) {
+ Out << "template<typename _Tp>\n"
+ << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))"
+ << " _Tp> {\n"
+ << " enum { __value = 0 };\n"
+ << " typedef __false_type __type;\n"
+ << "};\n"
+ << "\n";
+ }
Out << "}\n";
}
@@ -406,6 +411,8 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// Not "standard" per se, but available even with the -undef flag.
if (LangOpts.AsmPreprocessor)
Builder.defineMacro("__ASSEMBLER__");
+ if (LangOpts.CUDA)
+ Builder.defineMacro("__CUDA__");
}
/// Initialize the predefined C++ language feature test macros defined in
@@ -456,6 +463,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
Builder.defineMacro("__cpp_sized_deallocation", "201309");
if (LangOpts.ConceptsTS)
Builder.defineMacro("__cpp_experimental_concepts", "1");
+ if (LangOpts.Coroutines)
+ Builder.defineMacro("__cpp_coroutines", "1");
}
static void InitializePredefinedMacros(const TargetInfo &TI,
@@ -849,9 +858,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
else if (LangOpts.getStackProtector() == LangOptions::SSPReq)
Builder.defineMacro("__SSP_ALL__", "3");
- if (FEOpts.ProgramAction == frontend::RewriteObjC)
- Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
-
// Define a macro that exists only when using the static analyzer.
if (FEOpts.ProgramAction == frontend::RunAnalysis)
Builder.defineMacro("__clang_analyzer__");
@@ -859,7 +865,13 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.FastRelaxedMath)
Builder.defineMacro("__FAST_RELAXED_MATH__");
- if (LangOpts.ObjCAutoRefCount) {
+ if (FEOpts.ProgramAction == frontend::RewriteObjC ||
+ LangOpts.getGC() != LangOptions::NonGC) {
+ Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
+ Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
+ Builder.defineMacro("__autoreleasing", "");
+ Builder.defineMacro("__unsafe_unretained", "");
+ } else if (LangOpts.ObjC1) {
Builder.defineMacro("__weak", "__attribute__((objc_ownership(weak)))");
Builder.defineMacro("__strong", "__attribute__((objc_ownership(strong)))");
Builder.defineMacro("__autoreleasing",
@@ -918,14 +930,19 @@ void clang::InitializePreprocessor(
// Install things like __POWERPC__, __GNUC__, etc into the macro table.
if (InitOpts.UsePredefines) {
+ if (LangOpts.CUDA && PP.getAuxTargetInfo())
+ InitializePredefinedMacros(*PP.getAuxTargetInfo(), LangOpts, FEOpts,
+ Builder);
+
InitializePredefinedMacros(PP.getTargetInfo(), LangOpts, FEOpts, Builder);
// Install definitions to make Objective-C++ ARC work well with various
// C++ Standard Library implementations.
- if (LangOpts.ObjC1 && LangOpts.CPlusPlus && LangOpts.ObjCAutoRefCount) {
+ if (LangOpts.ObjC1 && LangOpts.CPlusPlus &&
+ (LangOpts.ObjCAutoRefCount || LangOpts.ObjCWeak)) {
switch (InitOpts.ObjCXXARCStandardLibrary) {
case ARCXX_nolib:
- case ARCXX_libcxx:
+ case ARCXX_libcxx:
break;
case ARCXX_libstdcxx:
diff --git a/lib/Frontend/LogDiagnosticPrinter.cpp b/lib/Frontend/LogDiagnosticPrinter.cpp
index c6a18e0d80d2..9998f65457cf 100644
--- a/lib/Frontend/LogDiagnosticPrinter.cpp
+++ b/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -118,7 +118,7 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
if (MainFilename.empty() && Info.hasSourceManager()) {
const SourceManager &SM = Info.getSourceManager();
FileID FID = SM.getMainFileID();
- if (!FID.isInvalid()) {
+ if (FID.isValid()) {
const FileEntry *FE = SM.getFileEntryForID(FID);
if (FE && FE->isValid())
MainFilename = FE->getName();
@@ -147,7 +147,7 @@ void LogDiagnosticPrinter::HandleDiagnostic(DiagnosticsEngine::Level Level,
if (PLoc.isInvalid()) {
// At least print the file name if available:
FileID FID = SM.getFileID(Info.getLocation());
- if (!FID.isInvalid()) {
+ if (FID.isValid()) {
const FileEntry *FE = SM.getFileEntryForID(FID);
if (FE && FE->isValid())
DE.Filename = FE->getName();
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
index 67852dc02036..9768a164acbc 100644
--- a/lib/Frontend/ModuleDependencyCollector.cpp
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -32,8 +32,8 @@ public:
: Collector(Collector) {}
bool needsInputFileVisitation() override { return true; }
bool needsSystemInputFileVisitation() override { return true; }
- bool visitInputFile(StringRef Filename, bool IsSystem,
- bool IsOverridden) override;
+ bool visitInputFile(StringRef Filename, bool IsSystem, bool IsOverridden,
+ bool IsExplicitModule) override;
};
}
@@ -67,7 +67,7 @@ std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
path::native(AbsoluteSrc);
// TODO: We probably need to handle .. as well as . in order to have valid
// input to the YAMLVFSWriter.
- FileManager::removeDotPaths(AbsoluteSrc);
+ path::remove_dots(AbsoluteSrc);
// Build the destination path.
SmallString<256> Dest = Collector.getDest();
@@ -85,7 +85,8 @@ std::error_code ModuleDependencyListener::copyToRoot(StringRef Src) {
}
bool ModuleDependencyListener::visitInputFile(StringRef Filename, bool IsSystem,
- bool IsOverridden) {
+ bool IsOverridden,
+ bool IsExplicitModule) {
if (Collector.insertSeen(Filename))
if (copyToRoot(Filename))
Collector.setHasErrors();
diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp
index 91ee100f6394..12c85240bd75 100644
--- a/lib/Frontend/MultiplexConsumer.cpp
+++ b/lib/Frontend/MultiplexConsumer.cpp
@@ -122,9 +122,6 @@ public:
void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) override;
void FunctionDefinitionInstantiated(const FunctionDecl *D) override;
- void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
- const ObjCPropertyDecl *OrigProp,
- const ObjCCategoryDecl *ClassExt) override;
void DeclarationMarkedUsed(const Decl *D) override;
void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override;
@@ -207,13 +204,6 @@ void MultiplexASTMutationListener::FunctionDefinitionInstantiated(
for (auto &Listener : Listeners)
Listener->FunctionDefinitionInstantiated(D);
}
-void MultiplexASTMutationListener::AddedObjCPropertyInClassExtension(
- const ObjCPropertyDecl *Prop,
- const ObjCPropertyDecl *OrigProp,
- const ObjCCategoryDecl *ClassExt) {
- for (size_t i = 0, e = Listeners.size(); i != e; ++i)
- Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt);
-}
void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) {
for (size_t i = 0, e = Listeners.size(); i != e; ++i)
Listeners[i]->DeclarationMarkedUsed(D);
diff --git a/lib/Frontend/PCHContainerOperations.cpp b/lib/Frontend/PCHContainerOperations.cpp
index cde3ba139bcf..5e1d77205098 100644
--- a/lib/Frontend/PCHContainerOperations.cpp
+++ b/lib/Frontend/PCHContainerOperations.cpp
@@ -16,6 +16,7 @@
#include "llvm/Bitcode/BitstreamReader.h"
#include "llvm/Support/raw_ostream.h"
#include "clang/Lex/ModuleLoader.h"
+
using namespace clang;
namespace {
@@ -26,17 +27,11 @@ class RawPCHContainerGenerator : public ASTConsumer {
raw_pwrite_stream *OS;
public:
- RawPCHContainerGenerator(DiagnosticsEngine &Diags,
- const HeaderSearchOptions &HSO,
- const PreprocessorOptions &PPO,
- const TargetOptions &TO, const LangOptions &LO,
- const std::string &MainFileName,
- const std::string &OutputFileName,
- llvm::raw_pwrite_stream *OS,
+ RawPCHContainerGenerator(llvm::raw_pwrite_stream *OS,
std::shared_ptr<PCHBuffer> Buffer)
: Buffer(Buffer), OS(OS) {}
- virtual ~RawPCHContainerGenerator() {}
+ ~RawPCHContainerGenerator() override = default;
void HandleTranslationUnit(ASTContext &Ctx) override {
if (Buffer->IsComplete) {
@@ -49,16 +44,14 @@ public:
Buffer->Data = std::move(Empty);
}
};
-}
+
+} // anonymous namespace
std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator(
- DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO,
- const PreprocessorOptions &PPO, const TargetOptions &TO,
- const LangOptions &LO, const std::string &MainFileName,
+ CompilerInstance &CI, const std::string &MainFileName,
const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
std::shared_ptr<PCHBuffer> Buffer) const {
- return llvm::make_unique<RawPCHContainerGenerator>(
- Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer);
+ return llvm::make_unique<RawPCHContainerGenerator>(OS, Buffer);
}
void RawPCHContainerReader::ExtractPCH(
diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp
index dbc661b71905..8cf8adf37ed6 100644
--- a/lib/Frontend/Rewrite/FrontendActions.cpp
+++ b/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -78,7 +78,7 @@ public:
std::string RewriteFilename(const std::string &Filename, int &fd) override {
SmallString<128> Path;
llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename),
- llvm::sys::path::extension(Filename), fd,
+ llvm::sys::path::extension(Filename).drop_front(), fd,
Path);
return Path.str();
}
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
index 08d6cf1f92c2..ca8226251fd9 100644
--- a/lib/Frontend/Rewrite/InclusionRewriter.cpp
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -160,7 +160,7 @@ void InclusionRewriter::FileChanged(SourceLocation Loc,
void InclusionRewriter::FileSkipped(const FileEntry &/*SkippedFile*/,
const Token &/*FilenameTok*/,
SrcMgr::CharacteristicKind /*FileType*/) {
- assert(!LastInclusionLocation.isInvalid() &&
+ assert(LastInclusionLocation.isValid() &&
"A file, that wasn't found via an inclusion directive, was skipped");
LastInclusionLocation = SourceLocation();
}
@@ -389,9 +389,10 @@ bool InclusionRewriter::HandleHasInclude(
SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 1>
Includers;
Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir()));
+ // FIXME: Why don't we call PP.LookupFile here?
const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr,
- nullptr, nullptr, false);
+ nullptr, nullptr, nullptr, false);
FileExists = File != nullptr;
return true;
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 2902ba78c4ef..be68d42affa1 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -412,7 +412,7 @@ namespace {
// Misc. AST transformation routines. Sometimes they end up calling
// rewriting routines on the new ASTs.
CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
- Expr **args, unsigned nargs,
+ ArrayRef<Expr *> Args,
SourceLocation StartLoc=SourceLocation(),
SourceLocation EndLoc=SourceLocation());
@@ -2105,15 +2105,17 @@ Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
SmallVector<Expr*, 8> SelExprs;
SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size());
+ SelExprs);
ReplaceStmt(Exp, SelExp);
// delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
return SelExp;
}
-CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
- FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
- SourceLocation EndLoc) {
+CallExpr *
+RewriteModernObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+ ArrayRef<Expr *> Args,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
// Get the type, we will need to reference it in a couple spots.
QualType msgSendType = FD->getType();
@@ -2129,10 +2131,9 @@ CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
const FunctionType *FT = msgSendType->getAs<FunctionType>();
- CallExpr *Exp =
- new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
- FT->getCallResultType(*Context),
- VK_RValue, EndLoc);
+ CallExpr *Exp = new (Context) CallExpr(*Context, ICE, Args,
+ FT->getCallResultType(*Context),
+ VK_RValue, EndLoc);
return Exp;
}
@@ -2660,9 +2661,7 @@ Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
IdentifierInfo *clsName = BoxingClass->getIdentifier();
ClsExprs.push_back(getStringLiteral(clsName->getName()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
MsgExprs.push_back(Cls);
@@ -2672,8 +2671,7 @@ Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
SelExprs.push_back(
getStringLiteral(BoxingMethod->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size(),
- StartLoc, EndLoc);
+ SelExprs, StartLoc, EndLoc);
MsgExprs.push_back(SelExp);
// User provided sub-expression is the 3rd, and last, argument.
@@ -2788,9 +2786,7 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
IdentifierInfo *clsName = Class->getIdentifier();
ClsExprs.push_back(getStringLiteral(clsName->getName()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
MsgExprs.push_back(Cls);
@@ -2801,8 +2797,7 @@ Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
SelExprs.push_back(
getStringLiteral(ArrayMethod->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size(),
- StartLoc, EndLoc);
+ SelExprs, StartLoc, EndLoc);
MsgExprs.push_back(SelExp);
// (const id [])objects
@@ -2939,9 +2934,7 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
IdentifierInfo *clsName = Class->getIdentifier();
ClsExprs.push_back(getStringLiteral(clsName->getName()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
MsgExprs.push_back(Cls);
@@ -2951,8 +2944,7 @@ Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral
ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
SelExprs.push_back(getStringLiteral(DictMethod->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size(),
- StartLoc, EndLoc);
+ SelExprs, StartLoc, EndLoc);
MsgExprs.push_back(SelExp);
// (const id [])objects
@@ -3298,14 +3290,10 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
// (Class)objc_getClass("CurrentClass")
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc,
- EndLoc);
+ ClsExprs, StartLoc, EndLoc);
ClsExprs.clear();
ClsExprs.push_back(Cls);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
// (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
@@ -3366,9 +3354,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
= Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
IdentifierInfo *clsName = Class->getIdentifier();
ClsExprs.push_back(getStringLiteral(clsName->getName()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
Context->getObjCIdType(),
@@ -3398,14 +3384,11 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SmallVector<Expr*, 8> ClsExprs;
ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
// (Class)objc_getClass("CurrentClass")
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
ClsExprs.clear();
ClsExprs.push_back(Cls);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
// (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
@@ -3476,9 +3459,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SmallVector<Expr*, 8> SelExprs;
SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size(),
- StartLoc,
- EndLoc);
+ SelExprs, StartLoc, EndLoc);
MsgExprs.push_back(SelExp);
// Now push any user supplied arguments.
@@ -4862,7 +4843,7 @@ void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) {
std::string Str = "(";
Str += TypeString;
Str += ")";
- InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size());
+ InsertText(IC->getSubExpr()->getLocStart(), Str);
return;
}
@@ -5641,7 +5622,7 @@ Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
// FIXME: Missing definition of
// InsertText(clang::SourceLocation, char const*, unsigned int).
- // InsertText(startLoc, messString.c_str(), messString.size());
+ // InsertText(startLoc, messString);
// Tried this, but it didn't work either...
// ReplaceText(startLoc, 0, messString.c_str(), messString.size());
#endif
@@ -5767,7 +5748,7 @@ Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
const std::string &Str = Buf.str();
printf("CAST = %s\n", &Str[0]);
- InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+ InsertText(ICE->getSubExpr()->getLocStart(), Str);
delete S;
return Replacement;
}
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index 204820b3041a..e0ddadb12306 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -346,7 +346,7 @@ namespace {
// Misc. AST transformation routines. Sometimes they end up calling
// rewriting routines on the new ASTs.
CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
- Expr **args, unsigned nargs,
+ ArrayRef<Expr *> Args,
SourceLocation StartLoc=SourceLocation(),
SourceLocation EndLoc=SourceLocation());
CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
@@ -1997,15 +1997,17 @@ Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
SmallVector<Expr*, 8> SelExprs;
SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size());
+ SelExprs);
ReplaceStmt(Exp, SelExp);
// delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
return SelExp;
}
-CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
- FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
- SourceLocation EndLoc) {
+CallExpr *
+RewriteObjC::SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+ ArrayRef<Expr *> Args,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
// Get the type, we will need to reference it in a couple spots.
QualType msgSendType = FD->getType();
@@ -2021,10 +2023,9 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
const FunctionType *FT = msgSendType->getAs<FunctionType>();
- CallExpr *Exp =
- new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
- FT->getCallResultType(*Context),
- VK_RValue, EndLoc);
+ CallExpr *Exp = new (Context) CallExpr(*Context, ICE, Args,
+ FT->getCallResultType(*Context),
+ VK_RValue, EndLoc);
return Exp;
}
@@ -2680,20 +2681,15 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SmallVector<Expr*, 8> ClsExprs;
ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc,
- EndLoc);
+ ClsExprs, StartLoc, EndLoc);
// (Class)objc_getClass("CurrentClass")
CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
Context->getObjCClassType(),
CK_BitCast, Cls);
ClsExprs.clear();
ClsExprs.push_back(ArgExpr);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
-
// (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
// To turn off a warning, type-cast to 'id'
InitExprs.push_back( // set 'super class', using class_getSuperclass().
@@ -2752,9 +2748,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
= Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
IdentifierInfo *clsName = Class->getIdentifier();
ClsExprs.push_back(getStringLiteral(clsName->getName()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
MsgExprs.push_back(Cls);
break;
@@ -2780,9 +2774,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
// (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
SmallVector<Expr*, 8> ClsExprs;
ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
// (Class)objc_getClass("CurrentClass")
CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
@@ -2790,8 +2782,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
CK_BitCast, Cls);
ClsExprs.clear();
ClsExprs.push_back(ArgExpr);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl, ClsExprs,
StartLoc, EndLoc);
// (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
@@ -2862,9 +2853,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SmallVector<Expr*, 8> SelExprs;
SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size(),
- StartLoc,
- EndLoc);
+ SelExprs, StartLoc, EndLoc);
MsgExprs.push_back(SelExp);
// Now push any user supplied arguments.
@@ -4675,7 +4664,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
// FIXME: Missing definition of
// InsertText(clang::SourceLocation, char const*, unsigned int).
- // InsertText(startLoc, messString.c_str(), messString.size());
+ // InsertText(startLoc, messString);
// Tried this, but it didn't work either...
// ReplaceText(startLoc, 0, messString.c_str(), messString.size());
#endif
@@ -4790,7 +4779,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
const std::string &Str = Buf.str();
printf("CAST = %s\n", &Str[0]);
- InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+ InsertText(ICE->getSubExpr()->getLocStart(), Str);
delete S;
return Replacement;
}
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index d31b12e87a4e..1bf10d276945 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -51,6 +51,7 @@ public:
typedef SmallVector<uint64_t, 64> RecordData;
typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+typedef ArrayRef<uint64_t> RecordDataRef;
class SDiagsWriter;
@@ -393,13 +394,9 @@ unsigned SDiagsWriter::getEmitFile(const char *FileName){
// Lazily generate the record for the file.
entry = State->Files.size();
- RecordData Record;
- Record.push_back(RECORD_FILENAME);
- Record.push_back(entry);
- Record.push_back(0); // For legacy.
- Record.push_back(0); // For legacy.
StringRef Name(FileName);
- Record.push_back(Name.size());
+ RecordData::value_type Record[] = {RECORD_FILENAME, entry, 0 /* For legacy */,
+ 0 /* For legacy */, Name.size()};
State->Stream.EmitRecordWithBlob(State->Abbrevs.get(RECORD_FILENAME), Record,
Name);
@@ -478,7 +475,7 @@ void SDiagsWriter::EmitBlockInfoBlock() {
AddSourceLocationAbbrev(Abbrev);
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Category.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 10)); // Mapped Diag ID.
- Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Text size.
+ Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // Text size.
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Diagnostc text.
Abbrevs.set(RECORD_DIAG, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
@@ -531,14 +528,11 @@ void SDiagsWriter::EmitBlockInfoBlock() {
void SDiagsWriter::EmitMetaBlock() {
llvm::BitstreamWriter &Stream = State->Stream;
- RecordData &Record = State->Record;
AbbreviationMap &Abbrevs = State->Abbrevs;
Stream.EnterSubblock(BLOCK_META, 3);
- Record.clear();
- Record.push_back(RECORD_VERSION);
- Record.push_back(VersionNumber);
- Stream.EmitRecordWithAbbrev(Abbrevs.get(RECORD_VERSION), Record);
+ RecordData::value_type Record[] = {RECORD_VERSION, VersionNumber};
+ Stream.EmitRecordWithAbbrev(Abbrevs.get(RECORD_VERSION), Record);
Stream.ExitBlock();
}
@@ -548,11 +542,8 @@ unsigned SDiagsWriter::getEmitCategory(unsigned int category) {
// We use a local version of 'Record' so that we can be generating
// another record when we lazily generate one for the category entry.
- RecordData Record;
- Record.push_back(RECORD_CATEGORY);
- Record.push_back(category);
StringRef catName = DiagnosticIDs::getCategoryNameFromID(category);
- Record.push_back(catName.size());
+ RecordData::value_type Record[] = {RECORD_CATEGORY, category, catName.size()};
State->Stream.EmitRecordWithBlob(State->Abbrevs.get(RECORD_CATEGORY), Record,
catName);
@@ -581,10 +572,8 @@ unsigned SDiagsWriter::getEmitDiagnosticFlag(StringRef FlagName) {
entry.second = FlagName;
// Lazily emit the string in a separate record.
- RecordData Record;
- Record.push_back(RECORD_DIAG_FLAG);
- Record.push_back(entry.first);
- Record.push_back(FlagName.size());
+ RecordData::value_type Record[] = {RECORD_DIAG_FLAG, entry.first,
+ FlagName.size()};
State->Stream.EmitRecordWithBlob(State->Abbrevs.get(RECORD_DIAG_FLAG),
Record, FlagName);
}
@@ -844,17 +833,9 @@ std::error_code SDiagsMerger::visitEndOfDiagnostic() {
std::error_code
SDiagsMerger::visitSourceRangeRecord(const serialized_diags::Location &Start,
const serialized_diags::Location &End) {
- RecordData Record;
- Record.push_back(RECORD_SOURCE_RANGE);
- Record.push_back(FileLookup[Start.FileID]);
- Record.push_back(Start.Line);
- Record.push_back(Start.Col);
- Record.push_back(Start.Offset);
- Record.push_back(FileLookup[End.FileID]);
- Record.push_back(End.Line);
- Record.push_back(End.Col);
- Record.push_back(End.Offset);
-
+ RecordData::value_type Record[] = {
+ RECORD_SOURCE_RANGE, FileLookup[Start.FileID], Start.Line, Start.Col,
+ Start.Offset, FileLookup[End.FileID], End.Line, End.Col, End.Offset};
Writer.State->Stream.EmitRecordWithAbbrev(
Writer.State->Abbrevs.get(RECORD_SOURCE_RANGE), Record);
return std::error_code();
@@ -863,19 +844,13 @@ SDiagsMerger::visitSourceRangeRecord(const serialized_diags::Location &Start,
std::error_code SDiagsMerger::visitDiagnosticRecord(
unsigned Severity, const serialized_diags::Location &Location,
unsigned Category, unsigned Flag, StringRef Message) {
- RecordData MergedRecord;
- MergedRecord.push_back(RECORD_DIAG);
- MergedRecord.push_back(Severity);
- MergedRecord.push_back(FileLookup[Location.FileID]);
- MergedRecord.push_back(Location.Line);
- MergedRecord.push_back(Location.Col);
- MergedRecord.push_back(Location.Offset);
- MergedRecord.push_back(CategoryLookup[Category]);
- MergedRecord.push_back(Flag ? DiagFlagLookup[Flag] : 0);
- MergedRecord.push_back(Message.size());
+ RecordData::value_type Record[] = {
+ RECORD_DIAG, Severity, FileLookup[Location.FileID], Location.Line,
+ Location.Col, Location.Offset, CategoryLookup[Category],
+ Flag ? DiagFlagLookup[Flag] : 0, Message.size()};
Writer.State->Stream.EmitRecordWithBlob(
- Writer.State->Abbrevs.get(RECORD_DIAG), MergedRecord, Message);
+ Writer.State->Abbrevs.get(RECORD_DIAG), Record, Message);
return std::error_code();
}
@@ -883,17 +858,10 @@ std::error_code
SDiagsMerger::visitFixitRecord(const serialized_diags::Location &Start,
const serialized_diags::Location &End,
StringRef Text) {
- RecordData Record;
- Record.push_back(RECORD_FIXIT);
- Record.push_back(FileLookup[Start.FileID]);
- Record.push_back(Start.Line);
- Record.push_back(Start.Col);
- Record.push_back(Start.Offset);
- Record.push_back(FileLookup[End.FileID]);
- Record.push_back(End.Line);
- Record.push_back(End.Col);
- Record.push_back(End.Offset);
- Record.push_back(Text.size());
+ RecordData::value_type Record[] = {RECORD_FIXIT, FileLookup[Start.FileID],
+ Start.Line, Start.Col, Start.Offset,
+ FileLookup[End.FileID], End.Line, End.Col,
+ End.Offset, Text.size()};
Writer.State->Stream.EmitRecordWithBlob(
Writer.State->Abbrevs.get(RECORD_FIXIT), Record, Text);
diff --git a/lib/Frontend/TestModuleFileExtension.cpp b/lib/Frontend/TestModuleFileExtension.cpp
new file mode 100644
index 000000000000..d1b20c4a80b3
--- /dev/null
+++ b/lib/Frontend/TestModuleFileExtension.cpp
@@ -0,0 +1,123 @@
+//===-- TestModuleFileExtension.cpp - Module Extension Tester -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "TestModuleFileExtension.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Serialization/ASTReader.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+using namespace clang;
+using namespace clang::serialization;
+
+TestModuleFileExtension::Writer::~Writer() { }
+
+void TestModuleFileExtension::Writer::writeExtensionContents(
+ Sema &SemaRef,
+ llvm::BitstreamWriter &Stream) {
+ using namespace llvm;
+
+ // Write an abbreviation for this record.
+ BitCodeAbbrev *Abv = new llvm::BitCodeAbbrev();
+ Abv->Add(BitCodeAbbrevOp(FIRST_EXTENSION_RECORD_ID));
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // # of characters
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // message
+ auto Abbrev = Stream.EmitAbbrev(Abv);
+
+ // Write a message into the extension block.
+ SmallString<64> Message;
+ {
+ auto Ext = static_cast<TestModuleFileExtension *>(getExtension());
+ raw_svector_ostream OS(Message);
+ OS << "Hello from " << Ext->BlockName << " v" << Ext->MajorVersion << "."
+ << Ext->MinorVersion;
+ }
+ SmallVector<uint64_t, 4> Record;
+ Record.push_back(FIRST_EXTENSION_RECORD_ID);
+ Record.push_back(Message.size());
+ Stream.EmitRecordWithBlob(Abbrev, Record, Message);
+}
+
+TestModuleFileExtension::Reader::Reader(ModuleFileExtension *Ext,
+ const llvm::BitstreamCursor &InStream)
+ : ModuleFileExtensionReader(Ext), Stream(InStream)
+{
+ // Read the extension block.
+ SmallVector<uint64_t, 4> Record;
+ while (true) {
+ llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
+ switch (Entry.Kind) {
+ case llvm::BitstreamEntry::SubBlock:
+ case llvm::BitstreamEntry::EndBlock:
+ case llvm::BitstreamEntry::Error:
+ return;
+
+ case llvm::BitstreamEntry::Record:
+ break;
+ }
+
+ Record.clear();
+ StringRef Blob;
+ unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob);
+ switch (RecCode) {
+ case FIRST_EXTENSION_RECORD_ID: {
+ StringRef Message = Blob.substr(0, Record[0]);
+ fprintf(stderr, "Read extension block message: %s\n",
+ Message.str().c_str());
+ break;
+ }
+ }
+ }
+}
+
+TestModuleFileExtension::Reader::~Reader() { }
+
+TestModuleFileExtension::~TestModuleFileExtension() { }
+
+ModuleFileExtensionMetadata
+TestModuleFileExtension::getExtensionMetadata() const {
+ return { BlockName, MajorVersion, MinorVersion, UserInfo };
+}
+
+llvm::hash_code TestModuleFileExtension::hashExtension(
+ llvm::hash_code Code) const {
+ if (Hashed) {
+ Code = llvm::hash_combine(Code, BlockName);
+ Code = llvm::hash_combine(Code, MajorVersion);
+ Code = llvm::hash_combine(Code, MinorVersion);
+ Code = llvm::hash_combine(Code, UserInfo);
+ }
+
+ return Code;
+}
+
+std::unique_ptr<ModuleFileExtensionWriter>
+TestModuleFileExtension::createExtensionWriter(ASTWriter &) {
+ return std::unique_ptr<ModuleFileExtensionWriter>(new Writer(this));
+}
+
+std::unique_ptr<ModuleFileExtensionReader>
+TestModuleFileExtension::createExtensionReader(
+ const ModuleFileExtensionMetadata &Metadata,
+ ASTReader &Reader, serialization::ModuleFile &Mod,
+ const llvm::BitstreamCursor &Stream)
+{
+ assert(Metadata.BlockName == BlockName && "Wrong block name");
+ if (std::make_pair(Metadata.MajorVersion, Metadata.MinorVersion) !=
+ std::make_pair(MajorVersion, MinorVersion)) {
+ Reader.getDiags().Report(Mod.ImportLoc,
+ diag::err_test_module_file_extension_version)
+ << BlockName << Metadata.MajorVersion << Metadata.MinorVersion
+ << MajorVersion << MinorVersion;
+ return nullptr;
+ }
+
+ return std::unique_ptr<ModuleFileExtensionReader>(
+ new TestModuleFileExtension::Reader(this, Stream));
+}
diff --git a/lib/Frontend/TestModuleFileExtension.h b/lib/Frontend/TestModuleFileExtension.h
new file mode 100644
index 000000000000..41f3ca9f05fc
--- /dev/null
+++ b/lib/Frontend/TestModuleFileExtension.h
@@ -0,0 +1,72 @@
+//===-- TestModuleFileExtension.h - Module Extension Tester -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_FRONTEND_TESTMODULEFILEEXTENSION_H
+#define LLVM_CLANG_FRONTEND_TESTMODULEFILEEXTENSION_H
+
+#include "clang/Serialization/ModuleFileExtension.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include <string>
+
+namespace clang {
+
+/// A module file extension used for testing purposes.
+class TestModuleFileExtension : public ModuleFileExtension {
+ std::string BlockName;
+ unsigned MajorVersion;
+ unsigned MinorVersion;
+ bool Hashed;
+ std::string UserInfo;
+
+ class Writer : public ModuleFileExtensionWriter {
+ public:
+ Writer(ModuleFileExtension *Ext) : ModuleFileExtensionWriter(Ext) { }
+ ~Writer() override;
+
+ void writeExtensionContents(Sema &SemaRef,
+ llvm::BitstreamWriter &Stream) override;
+ };
+
+ class Reader : public ModuleFileExtensionReader {
+ llvm::BitstreamCursor Stream;
+
+ public:
+ ~Reader() override;
+
+ Reader(ModuleFileExtension *Ext, const llvm::BitstreamCursor &InStream);
+ };
+
+public:
+ TestModuleFileExtension(StringRef BlockName,
+ unsigned MajorVersion,
+ unsigned MinorVersion,
+ bool Hashed,
+ StringRef UserInfo)
+ : BlockName(BlockName),
+ MajorVersion(MajorVersion), MinorVersion(MinorVersion),
+ Hashed(Hashed), UserInfo(UserInfo) { }
+ ~TestModuleFileExtension() override;
+
+ ModuleFileExtensionMetadata getExtensionMetadata() const override;
+
+ llvm::hash_code hashExtension(llvm::hash_code Code) const override;
+
+ std::unique_ptr<ModuleFileExtensionWriter>
+ createExtensionWriter(ASTWriter &Writer) override;
+
+ std::unique_ptr<ModuleFileExtensionReader>
+ createExtensionReader(const ModuleFileExtensionMetadata &Metadata,
+ ASTReader &Reader, serialization::ModuleFile &Mod,
+ const llvm::BitstreamCursor &Stream) override;
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_FRONTEND_TESTMODULEFILEEXTENSION_H
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index aaf17a983371..d4e156d44582 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -777,7 +777,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
if (PLoc.isInvalid()) {
// At least print the file name if available:
FileID FID = SM.getFileID(Loc);
- if (!FID.isInvalid()) {
+ if (FID.isValid()) {
const FileEntry* FE = SM.getFileEntryForID(FID);
if (FE && FE->isValid()) {
OS << FE->getName();
@@ -875,7 +875,7 @@ void TextDiagnostic::emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
PresumedLoc PLoc,
const SourceManager &SM) {
- if (DiagOpts->ShowLocation)
+ if (DiagOpts->ShowLocation && PLoc.getFilename())
OS << "In file included from " << PLoc.getFilename() << ':'
<< PLoc.getLine() << ":\n";
else
@@ -885,11 +885,11 @@ void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
void TextDiagnostic::emitImportLocation(SourceLocation Loc, PresumedLoc PLoc,
StringRef ModuleName,
const SourceManager &SM) {
- if (DiagOpts->ShowLocation)
+ if (DiagOpts->ShowLocation && PLoc.getFilename())
OS << "In module '" << ModuleName << "' imported from "
<< PLoc.getFilename() << ':' << PLoc.getLine() << ":\n";
else
- OS << "In module " << ModuleName << "':\n";
+ OS << "In module '" << ModuleName << "':\n";
}
void TextDiagnostic::emitBuildingModuleLocation(SourceLocation Loc,
@@ -1060,7 +1060,7 @@ void TextDiagnostic::emitSnippetAndCaret(
SmallVectorImpl<CharSourceRange>& Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM) {
- assert(!Loc.isInvalid() && "must have a valid source location here");
+ assert(Loc.isValid() && "must have a valid source location here");
assert(Loc.isFileID() && "must have a file location here");
// If caret diagnostics are enabled and we have location, we want to
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 55df9361b58e..7331d77d1c18 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -186,9 +186,7 @@ public:
Regex(RegexStr) { }
bool isValid(std::string &Error) override {
- if (Regex.isValid(Error))
- return true;
- return false;
+ return Regex.isValid(Error);
}
bool match(StringRef S) override {