aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Frontend
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Frontend
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
downloadsrc-486754660bb926339aefcf012a3f848592babb8b.tar.gz
src-486754660bb926339aefcf012a3f848592babb8b.zip
Vendor import of clang trunk r338150:vendor/clang/clang-trunk-r338150
Notes
Notes: svn path=/vendor/clang/dist/; revision=336815 svn path=/vendor/clang/clang-trunk-r338150/; revision=336816; tag=vendor/clang/clang-trunk-r338150
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTConsumers.cpp19
-rw-r--r--lib/Frontend/ASTMerge.cpp2
-rw-r--r--lib/Frontend/ASTUnit.cpp524
-rw-r--r--lib/Frontend/CMakeLists.txt1
-rw-r--r--lib/Frontend/CacheTokens.cpp32
-rw-r--r--lib/Frontend/CodeGenOptions.cpp2
-rw-r--r--lib/Frontend/CompilerInstance.cpp181
-rw-r--r--lib/Frontend/CompilerInvocation.cpp576
-rw-r--r--lib/Frontend/DependencyFile.cpp45
-rw-r--r--lib/Frontend/DependencyGraph.cpp23
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp168
-rw-r--r--lib/Frontend/FrontendAction.cpp41
-rw-r--r--lib/Frontend/FrontendActions.cpp254
-rw-r--r--lib/Frontend/FrontendOptions.cpp3
-rw-r--r--lib/Frontend/FrontendTiming.cpp20
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp16
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp94
-rw-r--r--lib/Frontend/InitPreprocessor.cpp235
-rw-r--r--lib/Frontend/LayoutOverrideSource.cpp2
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp6
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp24
-rw-r--r--lib/Frontend/PCHContainerOperations.cpp2
-rw-r--r--lib/Frontend/PrecompiledPreamble.cpp60
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp25
-rw-r--r--lib/Frontend/Rewrite/FixItRewriter.cpp31
-rw-r--r--lib/Frontend/Rewrite/HTMLPrint.cpp7
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp38
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp31
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp30
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp76
-rw-r--r--lib/Frontend/SerializedDiagnosticReader.cpp31
-rw-r--r--lib/Frontend/TextDiagnostic.cpp70
-rw-r--r--lib/Frontend/TextDiagnosticBuffer.cpp21
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp2
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp133
35 files changed, 1798 insertions, 1027 deletions
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 7dc475e26f76..b67c019baed8 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -87,9 +87,10 @@ namespace {
<< DC->getPrimaryContext() << "\n";
} else
Out << "Not a DeclContext\n";
- } else if (OutputKind == Print)
- D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
- else if (OutputKind != None)
+ } else if (OutputKind == Print) {
+ PrintingPolicy Policy(D->getASTContext().getLangOpts());
+ D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
+ } else if (OutputKind != None)
D->dump(Out, OutputKind == DumpFull);
}
@@ -138,12 +139,14 @@ clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
FilterString);
}
-std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,
- bool DumpDecls,
- bool Deserialize,
- bool DumpLookups) {
+std::unique_ptr<ASTConsumer>
+clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out,
+ StringRef FilterString,
+ bool DumpDecls,
+ bool Deserialize,
+ bool DumpLookups) {
assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
- return llvm::make_unique<ASTPrinter>(nullptr,
+ return llvm::make_unique<ASTPrinter>(std::move(Out),
Deserialize ? ASTPrinter::DumpFull :
DumpDecls ? ASTPrinter::Dump :
ASTPrinter::None,
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index 354527db7bad..6ec0e2a98c1b 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -1,4 +1,4 @@
-//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
+//===-- ASTMerge.cpp - AST Merging Frontend Action --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 1160df15a920..e4c313fed30f 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -1,4 +1,4 @@
-//===--- ASTUnit.cpp - ASTUnit utility --------------------------*- C++ -*-===//
+//===- ASTUnit.cpp - ASTUnit utility --------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,45 +14,99 @@
#include "clang/Frontend/ASTUnit.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
#include "clang/Basic/MemoryBufferCache.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/FrontendAction.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/MultiplexConsumer.h"
+#include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/Frontend/PrecompiledPreamble.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/HeaderSearchOptions.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Lex/Token.h"
+#include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/CodeCompleteOptions.h"
#include "clang/Sema/Sema.h"
+#include "clang/Serialization/ASTBitCodes.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
+#include "clang/Serialization/ContinuousRangeMap.h"
+#include "clang/Serialization/Module.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CrashRecoveryContext.h"
-#include "llvm/Support/Host.h"
+#include "llvm/Support/DJB.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
#include <atomic>
+#include <cassert>
+#include <cstdint>
#include <cstdio>
#include <cstdlib>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
using namespace clang;
using llvm::TimeRecord;
namespace {
+
class SimpleTimer {
bool WantTiming;
TimeRecord Start;
@@ -64,11 +118,6 @@ namespace {
Start = TimeRecord::getCurrentTime();
}
- void setOutput(const Twine &Output) {
- if (WantTiming)
- this->Output = Output.str();
- }
-
~SimpleTimer() {
if (WantTiming) {
TimeRecord Elapsed = TimeRecord::getCurrentTime();
@@ -78,29 +127,37 @@ namespace {
llvm::errs() << '\n';
}
}
+
+ void setOutput(const Twine &Output) {
+ if (WantTiming)
+ this->Output = Output.str();
+ }
};
- template <class T>
- std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
- if (!Val)
- return nullptr;
- return std::move(*Val);
- }
+} // namespace
- template <class T>
- bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
- if (!Val)
- return false;
- Output = std::move(*Val);
- return true;
- }
+template <class T>
+static std::unique_ptr<T> valueOrNull(llvm::ErrorOr<std::unique_ptr<T>> Val) {
+ if (!Val)
+ return nullptr;
+ return std::move(*Val);
+}
+
+template <class T>
+static bool moveOnNoError(llvm::ErrorOr<T> Val, T &Output) {
+ if (!Val)
+ return false;
+ Output = std::move(*Val);
+ return true;
+}
-/// \brief Get a source buffer for \p MainFilePath, handling all file-to-file
+/// Get a source buffer for \p MainFilePath, handling all file-to-file
/// and file-to-buffer remappings inside \p Invocation.
static std::unique_ptr<llvm::MemoryBuffer>
getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
vfs::FileSystem *VFS,
- StringRef FilePath) {
+ StringRef FilePath,
+ bool isVolatile) {
const auto &PreprocessorOpts = Invocation.getPreprocessorOpts();
// Try to determine if the main file has been remapped, either from the
@@ -120,7 +177,7 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
llvm::sys::fs::UniqueID MID = MPathStatus->getUniqueID();
if (MainFileID == MID) {
// We found a remapping. Try to load the resulting, remapped source.
- BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second));
+ BufferOwner = valueOrNull(VFS->getBufferForFile(RF.second, -1, true, isVolatile));
if (!BufferOwner)
return nullptr;
}
@@ -145,7 +202,7 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
// If the main source file was not remapped, load it now.
if (!Buffer && !BufferOwner) {
- BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath));
+ BufferOwner = valueOrNull(VFS->getBufferForFile(FilePath, -1, true, isVolatile));
if (!BufferOwner)
return nullptr;
}
@@ -156,7 +213,6 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
return nullptr;
return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
}
-}
struct ASTUnit::ASTWriterData {
SmallString<128> Buffer;
@@ -171,32 +227,22 @@ void ASTUnit::clearFileLevelDecls() {
llvm::DeleteContainerSeconds(FileDecls);
}
-/// \brief After failing to build a precompiled preamble (due to
+/// After failing to build a precompiled preamble (due to
/// errors in the source that occurs in the preamble), the number of
/// reparses during which we'll skip even trying to precompile the
/// preamble.
const unsigned DefaultPreambleRebuildInterval = 5;
-/// \brief Tracks the number of ASTUnit objects that are currently active.
+/// Tracks the number of ASTUnit objects that are currently active.
///
/// Used for debugging purposes only.
static std::atomic<unsigned> ActiveASTUnitObjects;
ASTUnit::ASTUnit(bool _MainFileIsAST)
- : Reader(nullptr), HadModuleLoaderFatalFailure(false),
- OnlyLocalDecls(false), CaptureDiagnostics(false),
- MainFileIsAST(_MainFileIsAST),
- TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),
- OwnsRemappedFileBuffers(true),
- NumStoredDiagnosticsFromDriver(0),
- PreambleRebuildCounter(0),
- NumWarningsInPreamble(0),
- ShouldCacheCodeCompletionResults(false),
- IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
- CompletionCacheTopLevelHashValue(0),
- PreambleTopLevelHashValue(0),
- CurrentTopLevelHashValue(0),
- UnsafeToFree(false) {
+ : MainFileIsAST(_MainFileIsAST), WantTiming(getenv("LIBCLANG_TIMING")),
+ ShouldCacheCodeCompletionResults(false),
+ IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
+ UnsafeToFree(false) {
if (getenv("LIBCLANG_OBJTRACKING"))
fprintf(stderr, "+++ %u translation units\n", ++ActiveASTUnitObjects);
}
@@ -219,8 +265,8 @@ ASTUnit::~ASTUnit() {
delete RB.second;
}
- ClearCachedCompletionResults();
-
+ ClearCachedCompletionResults();
+
if (getenv("LIBCLANG_OBJTRACKING"))
fprintf(stderr, "--- %u translation units\n", --ActiveASTUnitObjects);
}
@@ -229,20 +275,26 @@ void ASTUnit::setPreprocessor(std::shared_ptr<Preprocessor> PP) {
this->PP = std::move(PP);
}
-/// \brief Determine the set of code-completion contexts in which this
+void ASTUnit::enableSourceFileDiagnostics() {
+ assert(getDiagnostics().getClient() && Ctx &&
+ "Bad context for source file");
+ getDiagnostics().getClient()->BeginSourceFile(Ctx->getLangOpts(), PP.get());
+}
+
+/// Determine the set of code-completion contexts in which this
/// declaration should be shown.
static unsigned getDeclShowContexts(const NamedDecl *ND,
const LangOptions &LangOpts,
bool &IsNestedNameSpecifier) {
IsNestedNameSpecifier = false;
-
+
if (isa<UsingShadowDecl>(ND))
- ND = dyn_cast<NamedDecl>(ND->getUnderlyingDecl());
+ ND = ND->getUnderlyingDecl();
if (!ND)
return 0;
-
+
uint64_t Contexts = 0;
- if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||
+ if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) ||
isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) ||
isa<TypeAliasTemplateDecl>(ND)) {
// Types can appear in these contexts.
@@ -257,12 +309,12 @@ static unsigned getDeclShowContexts(const NamedDecl *ND,
// In C++, types can appear in expressions contexts (for functional casts).
if (LangOpts.CPlusPlus)
Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
-
+
// In Objective-C, message sends can send interfaces. In Objective-C++,
// all types are available due to functional casts.
if (LangOpts.CPlusPlus || isa<ObjCInterfaceDecl>(ND))
Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
-
+
// In Objective-C, you can only be a subclass of another Objective-C class
if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
// Objective-C interfaces can be used in a class property expression.
@@ -274,16 +326,16 @@ static unsigned getDeclShowContexts(const NamedDecl *ND,
// Deal with tag names.
if (isa<EnumDecl>(ND)) {
Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);
-
+
// Part of the nested-name-specifier in C++0x.
if (LangOpts.CPlusPlus11)
IsNestedNameSpecifier = true;
- } else if (const RecordDecl *Record = dyn_cast<RecordDecl>(ND)) {
+ } else if (const auto *Record = dyn_cast<RecordDecl>(ND)) {
if (Record->isUnion())
Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);
else
Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
-
+
if (LangOpts.CPlusPlus)
IsNestedNameSpecifier = true;
} else if (isa<ClassTemplateDecl>(ND))
@@ -300,37 +352,37 @@ static unsigned getDeclShowContexts(const NamedDecl *ND,
Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName);
} else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
Contexts = (1LL << CodeCompletionContext::CCC_Namespace);
-
+
// Part of the nested-name-specifier.
IsNestedNameSpecifier = true;
}
-
+
return Contexts;
}
void ASTUnit::CacheCodeCompletionResults() {
if (!TheSema)
return;
-
+
SimpleTimer Timer(WantTiming);
Timer.setOutput("Cache global code completions for " + getMainFileName());
// Clear out the previous results.
ClearCachedCompletionResults();
-
+
// Gather the set of global code completions.
- typedef CodeCompletionResult Result;
+ using Result = CodeCompletionResult;
SmallVector<Result, 8> Results;
CachedCompletionAllocator = std::make_shared<GlobalCodeCompletionAllocator>();
CodeCompletionTUInfo CCTUInfo(CachedCompletionAllocator);
TheSema->GatherGlobalCodeCompletions(*CachedCompletionAllocator,
CCTUInfo, Results);
-
+
// Translate global code completions into cached completions.
llvm::DenseMap<CanQualType, unsigned> CompletionTypes;
CodeCompletionContext CCContext(CodeCompletionContext::CCC_TopLevel);
- for (Result &R : Results) {
+ for (auto &R : Results) {
switch (R.Kind) {
case Result::RK_Declaration: {
bool IsNestedNameSpecifier = false;
@@ -344,7 +396,7 @@ void ASTUnit::CacheCodeCompletionResults() {
CachedResult.Kind = R.CursorKind;
CachedResult.Availability = R.Availability;
- // Keep track of the type of this completion in an ASTContext-agnostic
+ // Keep track of the type of this completion in an ASTContext-agnostic
// way.
QualType UsageType = getDeclUsageType(*Ctx, R.Declaration);
if (UsageType.isNull()) {
@@ -356,7 +408,7 @@ void ASTUnit::CacheCodeCompletionResults() {
CachedResult.TypeClass = getSimplifiedTypeClass(CanUsageType);
// Determine whether we have already seen this type. If so, we save
- // ourselves the work of formatting the type string by using the
+ // ourselves the work of formatting the type string by using the
// temporary, CanQualType-based hash table to find the associated value.
unsigned &TypeValue = CompletionTypes[CanUsageType];
if (TypeValue == 0) {
@@ -364,12 +416,12 @@ void ASTUnit::CacheCodeCompletionResults() {
CachedCompletionTypes[QualType(CanUsageType).getAsString()]
= TypeValue;
}
-
+
CachedResult.Type = TypeValue;
}
-
+
CachedCompletionResults.push_back(CachedResult);
-
+
/// Handle nested-name-specifiers in C++.
if (TheSema->Context.getLangOpts().CPlusPlus && IsNestedNameSpecifier &&
!R.StartsNestedNameSpecifier) {
@@ -392,10 +444,10 @@ void ASTUnit::CacheCodeCompletionResults() {
isa<NamespaceAliasDecl>(R.Declaration))
NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);
- if (unsigned RemainingContexts
+ if (unsigned RemainingContexts
= NNSContexts & ~CachedResult.ShowInContexts) {
- // If there any contexts where this completion can be a
- // nested-name-specifier but isn't already an option, create a
+ // If there any contexts where this completion can be a
+ // nested-name-specifier but isn't already an option, create a
// nested-name-specifier completion.
R.StartsNestedNameSpecifier = true;
CachedResult.Completion = R.CreateCodeCompletionString(
@@ -410,13 +462,13 @@ void ASTUnit::CacheCodeCompletionResults() {
}
break;
}
-
+
case Result::RK_Keyword:
case Result::RK_Pattern:
// Ignore keywords and patterns; we don't care, since they are so
// easily regenerated.
break;
-
+
case Result::RK_Macro: {
CachedCodeCompletionResult CachedResult;
CachedResult.Completion = R.CreateCodeCompletionString(
@@ -446,7 +498,7 @@ void ASTUnit::CacheCodeCompletionResults() {
}
}
}
-
+
// Save the current top-level hash value.
CompletionCacheTopLevelHashValue = CurrentTopLevelHashValue;
}
@@ -459,7 +511,7 @@ void ASTUnit::ClearCachedCompletionResults() {
namespace {
-/// \brief Gathers information from ASTReader that will be used to initialize
+/// Gathers information from ASTReader that will be used to initialize
/// a Preprocessor.
class ASTInfoCollector : public ASTReaderListener {
Preprocessor &PP;
@@ -470,8 +522,8 @@ class ASTInfoCollector : public ASTReaderListener {
std::shared_ptr<TargetOptions> &TargetOpts;
IntrusiveRefCntPtr<TargetInfo> &Target;
unsigned &Counter;
+ bool InitializedLanguage = false;
- bool InitializedLanguage;
public:
ASTInfoCollector(Preprocessor &PP, ASTContext *Context,
HeaderSearchOptions &HSOpts, PreprocessorOptions &PPOpts,
@@ -480,30 +532,29 @@ public:
IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter)
: PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),
LangOpt(LangOpt), TargetOpts(TargetOpts), Target(Target),
- Counter(Counter), InitializedLanguage(false) {}
+ Counter(Counter) {}
bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
bool AllowCompatibleDifferences) override {
if (InitializedLanguage)
return false;
-
+
LangOpt = LangOpts;
InitializedLanguage = true;
-
+
updated();
return false;
}
- virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
- StringRef SpecificModuleCachePath,
- bool Complain) override {
+ bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
+ StringRef SpecificModuleCachePath,
+ bool Complain) override {
this->HSOpts = HSOpts;
return false;
}
- virtual bool
- ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
- std::string &SuggestedPredefines) override {
+ bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain,
+ std::string &SuggestedPredefines) override {
this->PPOpts = PPOpts;
return false;
}
@@ -557,19 +608,18 @@ private:
}
};
- /// \brief Diagnostic consumer that saves each diagnostic it is given.
+/// Diagnostic consumer that saves each diagnostic it is given.
class StoredDiagnosticConsumer : public DiagnosticConsumer {
SmallVectorImpl<StoredDiagnostic> *StoredDiags;
SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags;
- const LangOptions *LangOpts;
- SourceManager *SourceMgr;
+ const LangOptions *LangOpts = nullptr;
+ SourceManager *SourceMgr = nullptr;
public:
StoredDiagnosticConsumer(
SmallVectorImpl<StoredDiagnostic> *StoredDiags,
SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
- : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags),
- LangOpts(nullptr), SourceMgr(nullptr) {
+ : StoredDiags(StoredDiags), StandaloneDiags(StandaloneDiags) {
assert((StoredDiags || StandaloneDiags) &&
"No output collections were passed to StoredDiagnosticConsumer.");
}
@@ -585,20 +635,20 @@ public:
const Diagnostic &Info) override;
};
-/// \brief RAII object that optionally captures diagnostics, if
+/// RAII object that optionally captures diagnostics, if
/// there is no diagnostic client to capture them already.
class CaptureDroppedDiagnostics {
DiagnosticsEngine &Diags;
StoredDiagnosticConsumer Client;
- DiagnosticConsumer *PreviousClient;
+ DiagnosticConsumer *PreviousClient = nullptr;
std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
public:
- CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags,
- SmallVectorImpl<StoredDiagnostic> *StoredDiags,
- SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
- : Diags(Diags), Client(StoredDiags, StandaloneDiags), PreviousClient(nullptr)
- {
+ CaptureDroppedDiagnostics(
+ bool RequestCapture, DiagnosticsEngine &Diags,
+ SmallVectorImpl<StoredDiagnostic> *StoredDiags,
+ SmallVectorImpl<ASTUnit::StandaloneDiagnostic> *StandaloneDiags)
+ : Diags(Diags), Client(StoredDiags, StandaloneDiags) {
if (RequestCapture || Diags.getClient() == nullptr) {
OwningPreviousClient = Diags.takeClient();
PreviousClient = Diags.getClient();
@@ -612,7 +662,7 @@ public:
}
};
-} // anonymous namespace
+} // namespace
static ASTUnit::StandaloneDiagnostic
makeStandaloneDiagnostic(const LangOptions &LangOpts,
@@ -634,7 +684,7 @@ void StoredDiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level Level,
}
if (StandaloneDiags) {
- llvm::Optional<StoredDiagnostic> StoredDiag = llvm::None;
+ llvm::Optional<StoredDiagnostic> StoredDiag = None;
if (!ResultDiag) {
StoredDiag.emplace(Level, Info);
ResultDiag = StoredDiag.getPointer();
@@ -664,7 +714,7 @@ ASTDeserializationListener *ASTUnit::getDeserializationListener() {
std::unique_ptr<llvm::MemoryBuffer>
ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
assert(FileMgr);
- auto Buffer = FileMgr->getBufferForFile(Filename);
+ auto Buffer = FileMgr->getBufferForFile(Filename, UserFilesAreVolatile);
if (Buffer)
return std::move(*Buffer);
if (ErrorStr)
@@ -672,7 +722,7 @@ ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
return nullptr;
}
-/// \brief Configure the diagnostics object for use with ASTUnit.
+/// Configure the diagnostics object for use with ASTUnit.
void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
ASTUnit &AST, bool CaptureDiagnostics) {
assert(Diags.get() && "no DiagnosticsEngine was provided");
@@ -693,7 +743,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
ASTUnitCleanup(AST.get());
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
- llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
+ llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
DiagCleanup(Diags.get());
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
@@ -741,7 +791,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
bool disableValid = false;
if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
disableValid = true;
- AST->Reader = new ASTReader(PP, AST->Ctx.get(), PCHContainerRdr, { },
+ AST->Reader = new ASTReader(PP, AST->Ctx.get(), PCHContainerRdr, {},
/*isysroot=*/"",
/*DisableValidation=*/disableValid,
AllowPCHWithCompilerErrors);
@@ -794,20 +844,20 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
return AST;
}
-namespace {
-
-/// \brief Add the given macro to the hash of all top-level entities.
-void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
- Hash = llvm::HashString(MacroNameTok.getIdentifierInfo()->getName(), Hash);
+/// Add the given macro to the hash of all top-level entities.
+static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
+ Hash = llvm::djbHash(MacroNameTok.getIdentifierInfo()->getName(), Hash);
}
-/// \brief Preprocessor callback class that updates a hash value with the names
+namespace {
+
+/// Preprocessor callback class that updates a hash value with the names
/// of all macros that have been defined by the translation unit.
class MacroDefinitionTrackerPPCallbacks : public PPCallbacks {
unsigned &Hash;
-
+
public:
- explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) { }
+ explicit MacroDefinitionTrackerPPCallbacks(unsigned &Hash) : Hash(Hash) {}
void MacroDefined(const Token &MacroNameTok,
const MacroDirective *MD) override {
@@ -815,55 +865,59 @@ public:
}
};
-/// \brief Add the given declaration to the hash of all top-level entities.
-void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
+} // namespace
+
+/// Add the given declaration to the hash of all top-level entities.
+static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
if (!D)
return;
-
+
DeclContext *DC = D->getDeclContext();
if (!DC)
return;
-
+
if (!(DC->isTranslationUnit() || DC->getLookupParent()->isTranslationUnit()))
return;
- if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
- if (EnumDecl *EnumD = dyn_cast<EnumDecl>(D)) {
+ if (const auto *ND = dyn_cast<NamedDecl>(D)) {
+ if (const auto *EnumD = dyn_cast<EnumDecl>(D)) {
// For an unscoped enum include the enumerators in the hash since they
// enter the top-level namespace.
if (!EnumD->isScoped()) {
for (const auto *EI : EnumD->enumerators()) {
if (EI->getIdentifier())
- Hash = llvm::HashString(EI->getIdentifier()->getName(), Hash);
+ Hash = llvm::djbHash(EI->getIdentifier()->getName(), Hash);
}
}
}
if (ND->getIdentifier())
- Hash = llvm::HashString(ND->getIdentifier()->getName(), Hash);
+ Hash = llvm::djbHash(ND->getIdentifier()->getName(), Hash);
else if (DeclarationName Name = ND->getDeclName()) {
std::string NameStr = Name.getAsString();
- Hash = llvm::HashString(NameStr, Hash);
+ Hash = llvm::djbHash(NameStr, Hash);
}
return;
}
- if (ImportDecl *ImportD = dyn_cast<ImportDecl>(D)) {
- if (Module *Mod = ImportD->getImportedModule()) {
+ if (const auto *ImportD = dyn_cast<ImportDecl>(D)) {
+ if (const Module *Mod = ImportD->getImportedModule()) {
std::string ModName = Mod->getFullModuleName();
- Hash = llvm::HashString(ModName, Hash);
+ Hash = llvm::djbHash(ModName, Hash);
}
return;
}
}
+namespace {
+
class TopLevelDeclTrackerConsumer : public ASTConsumer {
ASTUnit &Unit;
unsigned &Hash;
-
+
public:
TopLevelDeclTrackerConsumer(ASTUnit &_Unit, unsigned &Hash)
- : Unit(_Unit), Hash(Hash) {
+ : Unit(_Unit), Hash(Hash) {
Hash = 0;
}
@@ -886,14 +940,14 @@ public:
void handleFileLevelDecl(Decl *D) {
Unit.addFileLevelDecl(D);
- if (NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(D)) {
+ if (auto *NSD = dyn_cast<NamespaceDecl>(D)) {
for (auto *I : NSD->decls())
handleFileLevelDecl(I);
}
}
bool HandleTopLevelDecl(DeclGroupRef D) override {
- for (Decl *TopLevelDecl : D)
+ for (auto *TopLevelDecl : D)
handleTopLevelDecl(TopLevelDecl);
return true;
}
@@ -902,7 +956,7 @@ public:
void HandleInterestingDecl(DeclGroupRef) override {}
void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
- for (Decl *TopLevelDecl : D)
+ for (auto *TopLevelDecl : D)
handleTopLevelDecl(TopLevelDecl);
}
@@ -932,8 +986,9 @@ public:
TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
bool hasCodeCompletionSupport() const override { return false; }
+
TranslationUnitKind getTranslationUnitKind() override {
- return Unit.getTranslationUnitKind();
+ return Unit.getTranslationUnitKind();
}
};
@@ -949,7 +1004,7 @@ public:
void AfterPCHEmitted(ASTWriter &Writer) override {
TopLevelDeclIDs.reserve(TopLevelDecls.size());
- for (Decl *D : TopLevelDecls) {
+ for (const auto *D : TopLevelDecls) {
// Invalid top-level decls may not have been serialized.
if (D->isInvalidDecl())
continue;
@@ -958,7 +1013,7 @@ public:
}
void HandleTopLevelDecl(DeclGroupRef DG) override {
- for (Decl *D : DG) {
+ for (auto *D : DG) {
// FIXME: Currently ObjC method declarations are incorrectly being
// reported as top-level declarations, even though their DeclContext
// is the containing ObjC @interface/@implementation. This is a
@@ -981,7 +1036,7 @@ private:
llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
};
-} // anonymous namespace
+} // namespace
static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
return StoredDiag.getLocation().isValid();
@@ -1004,7 +1059,7 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
// been careful to make sure that the source manager's state
// before and after are identical, so that we can reuse the source
// location itself.
- for (StoredDiagnostic &SD : StoredDiagnostics) {
+ for (auto &SD : StoredDiagnostics) {
if (SD.getLocation().isValid()) {
FullSourceLoc Loc(SD.getLocation(), SM);
SD.setLocation(Loc);
@@ -1052,11 +1107,11 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
Clang->setInvocation(CCInvocation);
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
-
+
// Set up diagnostics, capturing any diagnostics that would
// otherwise be dropped.
Clang->setDiagnostics(&getDiagnostics());
-
+
// Create the target instance.
Clang->setTarget(TargetInfo::CreateTargetInfo(
Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
@@ -1068,7 +1123,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
// FIXME: We shouldn't need to do this, the target should be immutable once
// created. This complexity should be lifted elsewhere.
Clang->getTarget().adjust(Clang->getLangOpts());
-
+
assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
"Invocation must have exactly one source file!");
assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
@@ -1097,10 +1152,10 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
// Create a file manager object to provide access to and cache the filesystem.
Clang->setFileManager(&getFileManager());
-
+
// Create the source manager.
Clang->setSourceManager(&getSourceManager());
-
+
// If the main file has been overridden due to the use of a preamble,
// make that override happen and introduce the preamble.
if (OverrideMainBuffer) {
@@ -1135,7 +1190,7 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
goto error;
transferASTDataFromCompilerInstance(*Clang);
-
+
Act->EndSourceFile();
FailedParseDiagnostics.clear();
@@ -1192,22 +1247,22 @@ makeStandaloneDiagnostic(const LangOptions &LangOpts,
if (OutDiag.Filename.empty())
return OutDiag;
OutDiag.LocOffset = SM.getFileOffset(FileLoc);
- for (const CharSourceRange &Range : InDiag.getRanges())
+ for (const auto &Range : InDiag.getRanges())
OutDiag.Ranges.push_back(makeStandaloneRange(Range, SM, LangOpts));
- for (const FixItHint &FixIt : InDiag.getFixIts())
+ for (const auto &FixIt : InDiag.getFixIts())
OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, FixIt));
return OutDiag;
}
-/// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing
+/// Attempt to build or re-use a precompiled preamble when (re-)parsing
/// the source file.
///
/// This routine will compute the preamble of the main source file. If a
-/// non-trivial preamble is found, it will precompile that preamble into a
+/// non-trivial preamble is found, it will precompile that preamble into a
/// precompiled header so that the precompiled preamble can be used to reduce
/// reparsing time. If a precompiled preamble has already been constructed,
-/// this routine will determine if it is still valid and, if so, avoid
+/// this routine will determine if it is still valid and, if so, avoid
/// rebuilding the precompiled preamble.
///
/// \param AllowRebuild When true (the default), this routine is
@@ -1223,15 +1278,14 @@ makeStandaloneDiagnostic(const LangOptions &LangOpts,
std::unique_ptr<llvm::MemoryBuffer>
ASTUnit::getMainBufferWithPrecompiledPreamble(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
- const CompilerInvocation &PreambleInvocationIn,
+ CompilerInvocation &PreambleInvocationIn,
IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild,
unsigned MaxLines) {
-
auto MainFilePath =
PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
getBufferForFileHandlingRemapping(PreambleInvocationIn, VFS.get(),
- MainFilePath);
+ MainFilePath, UserFilesAreVolatile);
if (!MainFileBuffer)
return nullptr;
@@ -1259,6 +1313,7 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
Preamble.reset();
PreambleDiagnostics.clear();
TopLevelDeclsInPreamble.clear();
+ PreambleSrcLocCache.clear();
PreambleRebuildCounter = 1;
}
}
@@ -1290,9 +1345,18 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
SimpleTimer PreambleTimer(WantTiming);
PreambleTimer.setOutput("Precompiling preamble");
+ const bool PreviousSkipFunctionBodies =
+ PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies;
+ if (SkipFunctionBodies == SkipFunctionBodiesScope::Preamble)
+ PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies = true;
+
llvm::ErrorOr<PrecompiledPreamble> NewPreamble = PrecompiledPreamble::Build(
PreambleInvocationIn, MainFileBuffer.get(), Bounds, *Diagnostics, VFS,
PCHContainerOps, /*StoreInMemory=*/false, Callbacks);
+
+ PreambleInvocationIn.getFrontendOpts().SkipFunctionBodies =
+ PreviousSkipFunctionBodies;
+
if (NewPreamble) {
Preamble = std::move(*NewPreamble);
PreambleRebuildCounter = 1;
@@ -1306,7 +1370,6 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
case BuildPreambleError::CouldntCreateTargetInfo:
case BuildPreambleError::BeginSourceFileFailed:
case BuildPreambleError::CouldntEmitPCH:
- case BuildPreambleError::CouldntCreateVFSOverlay:
// These erros are more likely to repeat, retry after some period.
PreambleRebuildCounter = DefaultPreambleRebuildInterval;
return nullptr;
@@ -1344,7 +1407,7 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() {
std::vector<Decl *> Resolved;
Resolved.reserve(TopLevelDeclsInPreamble.size());
ExternalASTSource &Source = *getASTContext().getExternalSource();
- for (serialization::DeclID TopLevelDecl : TopLevelDeclsInPreamble) {
+ for (const auto TopLevelDecl : TopLevelDeclsInPreamble) {
// Resolve the declaration ID to an actual declaration, possibly
// deserializing the declaration in the process.
if (Decl *D = Source.GetExternalDecl(TopLevelDecl))
@@ -1388,12 +1451,12 @@ StringRef ASTUnit::getMainFileName() const {
return FE->getName();
}
- return StringRef();
+ return {};
}
StringRef ASTUnit::getASTFileName() const {
if (!isMainFileAST())
- return StringRef();
+ return {};
serialization::ModuleFile &
Mod = Reader->getModuleManager().getPrimaryModule();
@@ -1408,8 +1471,6 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
IntrusiveRefCntPtr<vfs::FileSystem> VFS =
createVFSFromCompilerInvocation(*CI, *Diags);
- if (!VFS)
- return nullptr;
AST->Diagnostics = Diags;
AST->FileSystemOpts = CI->getFileSystemOpts();
AST->Invocation = std::move(CI);
@@ -1442,7 +1503,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
if (!AST)
return nullptr;
}
-
+
if (!ResourceFilesPath.empty()) {
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
@@ -1460,7 +1521,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
ASTUnitCleanup(OwnAST.get());
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
- llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
+ llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
DiagCleanup(Diags.get());
// We'll manage file buffers ourselves.
@@ -1478,11 +1539,11 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
Clang->setInvocation(std::move(CI));
AST->OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
-
+
// Set up diagnostics, capturing any diagnostics that would
// otherwise be dropped.
Clang->setDiagnostics(&AST->getDiagnostics());
-
+
// Create the target instance.
Clang->setTarget(TargetInfo::CreateTargetInfo(
Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
@@ -1494,7 +1555,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
// FIXME: We shouldn't need to do this, the target should be immutable once
// created. This complexity should be lifted elsewhere.
Clang->getTarget().adjust(Clang->getLangOpts());
-
+
assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
"Invocation must have exactly one source file!");
assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
@@ -1512,7 +1573,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
// Create a file manager object to provide access to and cache the filesystem.
Clang->setFileManager(&AST->getFileManager());
-
+
// Create the source manager.
Clang->setSourceManager(&AST->getSourceManager());
@@ -1558,7 +1619,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
// Steal the created target, context, and preprocessor.
AST->transferASTDataFromCompilerInstance(*Clang);
-
+
Act->EndSourceFile();
if (OwnAST)
@@ -1623,12 +1684,12 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
AST->FileSystemOpts = FileMgr->getFileSystemOpts();
AST->FileMgr = FileMgr;
AST->UserFilesAreVolatile = UserFilesAreVolatile;
-
+
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
ASTUnitCleanup(AST.get());
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
- llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
+ llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
DiagCleanup(Diags.get());
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
@@ -1646,7 +1707,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
unsigned PrecompilePreambleAfterNParses, TranslationUnitKind TUKind,
bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
- bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,
+ bool AllowPCHWithCompilerErrors, SkipFunctionBodiesScope SkipFunctionBodies,
bool SingleFileParse, bool UserFilesAreVolatile, bool ForSerialization,
llvm::Optional<StringRef> ModuleFormat, std::unique_ptr<ASTUnit> *ErrAST,
IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
@@ -1657,11 +1718,10 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
std::shared_ptr<CompilerInvocation> CI;
{
-
CaptureDroppedDiagnostics Capture(CaptureDiagnostics, *Diags,
&StoredDiagnostics, nullptr);
- CI = clang::createInvocationFromCommandLine(
+ CI = createInvocationFromCommandLine(
llvm::makeArrayRef(ArgBegin, ArgEnd), Diags, VFS);
if (!CI)
return nullptr;
@@ -1676,11 +1736,12 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
PPOpts.RemappedFilesKeepOriginalName = RemappedFilesKeepOriginalName;
PPOpts.AllowPCHWithCompilerErrors = AllowPCHWithCompilerErrors;
PPOpts.SingleFileParseMode = SingleFileParse;
-
+
// Override the resources path.
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
- CI->getFrontendOpts().SkipFunctionBodies = SkipFunctionBodies;
+ CI->getFrontendOpts().SkipFunctionBodies =
+ SkipFunctionBodies == SkipFunctionBodiesScope::PreambleAndMainFile;
if (ModuleFormat)
CI->getHeaderSearchOpts().ModuleFormat = ModuleFormat.getValue();
@@ -1688,14 +1749,14 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
// Create the AST unit.
std::unique_ptr<ASTUnit> AST;
AST.reset(new ASTUnit(false));
+ AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
+ AST->StoredDiagnostics.swap(StoredDiagnostics);
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
AST->Diagnostics = Diags;
AST->FileSystemOpts = CI->getFileSystemOpts();
if (!VFS)
VFS = vfs::getRealFileSystem();
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
- if (!VFS)
- return nullptr;
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
AST->PCMCache = new MemoryBufferCache;
AST->OnlyLocalDecls = OnlyLocalDecls;
@@ -1705,9 +1766,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
AST->IncludeBriefCommentsInCodeCompletion
= IncludeBriefCommentsInCodeCompletion;
AST->UserFilesAreVolatile = UserFilesAreVolatile;
- AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
- AST->StoredDiagnostics.swap(StoredDiagnostics);
AST->Invocation = CI;
+ AST->SkipFunctionBodies = SkipFunctionBodies;
if (ForSerialization)
AST->WriterData.reset(new ASTWriterData(*AST->PCMCache));
// Zero out now to ease cleanup during crash recovery.
@@ -1745,7 +1805,7 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
}
clearFileLevelDecls();
-
+
SimpleTimer ParsingTimer(WantTiming);
ParsingTimer.setOutput("Reparsing " + getMainFileName());
@@ -1767,7 +1827,6 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
OverrideMainBuffer =
getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
-
// Clear out the diagnostics state.
FileMgr.reset();
getDiagnostics().Reset();
@@ -1779,7 +1838,7 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
bool Result =
Parse(std::move(PCHContainerOps), std::move(OverrideMainBuffer), VFS);
- // If we're caching global code-completion results, and the top-level
+ // If we're caching global code-completion results, and the top-level
// declarations have changed, clear out the code-completion cache.
if (!Result && ShouldCacheCodeCompletionResults &&
CurrentTopLevelHashValue != CompletionCacheTopLevelHashValue)
@@ -1788,7 +1847,7 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
// We now need to clear out the completion info related to this translation
// unit; it'll be recreated if necessary.
CCTUInfo.reset();
-
+
return Result;
}
@@ -1810,23 +1869,23 @@ void ASTUnit::ResetForParse() {
//----------------------------------------------------------------------------//
namespace {
- /// \brief Code completion consumer that combines the cached code-completion
+
+ /// Code completion consumer that combines the cached code-completion
/// results from an ASTUnit with the code-completion results provided to it,
- /// then passes the result on to
+ /// then passes the result on to
class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
uint64_t NormalContexts;
ASTUnit &AST;
CodeCompleteConsumer &Next;
-
+
public:
AugmentedCodeCompleteConsumer(ASTUnit &AST, CodeCompleteConsumer &Next,
const CodeCompleteOptions &CodeCompleteOpts)
- : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()),
- AST(AST), Next(Next)
- {
+ : CodeCompleteConsumer(CodeCompleteOpts, Next.isOutputBinary()),
+ AST(AST), Next(Next) {
// Compute the set of contexts in which we will look when we don't have
// any information about the specific context.
- NormalContexts
+ NormalContexts
= (1LL << CodeCompletionContext::CCC_TopLevel)
| (1LL << CodeCompletionContext::CCC_ObjCInterface)
| (1LL << CodeCompletionContext::CCC_ObjCImplementation)
@@ -1865,9 +1924,10 @@ namespace {
return Next.getCodeCompletionTUInfo();
}
};
-} // anonymous namespace
-/// \brief Helper function that computes which global names are hidden by the
+} // namespace
+
+/// Helper function that computes which global names are hidden by the
/// local code-completion results.
static void CalculateHiddenNames(const CodeCompletionContext &Context,
CodeCompletionResult *Results,
@@ -1895,13 +1955,13 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
case CodeCompletionContext::CCC_ParenthesizedExpression:
case CodeCompletionContext::CCC_ObjCInterfaceName:
break;
-
+
case CodeCompletionContext::CCC_EnumTag:
case CodeCompletionContext::CCC_UnionTag:
case CodeCompletionContext::CCC_ClassOrStructTag:
OnlyTagNames = true;
break;
-
+
case CodeCompletionContext::CCC_ObjCProtocolName:
case CodeCompletionContext::CCC_MacroName:
case CodeCompletionContext::CCC_MacroNameUse:
@@ -1919,12 +1979,12 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
// be hidden.
return;
}
-
- typedef CodeCompletionResult Result;
+
+ using Result = CodeCompletionResult;
for (unsigned I = 0; I != NumResults; ++I) {
if (Results[I].Kind != Result::RK_Declaration)
continue;
-
+
unsigned IDNS
= Results[I].Declaration->getUnderlyingDecl()->getIdentifierNamespace();
@@ -1932,17 +1992,17 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
if (OnlyTagNames)
Hiding = (IDNS & Decl::IDNS_Tag);
else {
- unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
+ unsigned HiddenIDNS = (Decl::IDNS_Type | Decl::IDNS_Member |
Decl::IDNS_Namespace | Decl::IDNS_Ordinary |
Decl::IDNS_NonMemberOperator);
if (Ctx.getLangOpts().CPlusPlus)
HiddenIDNS |= Decl::IDNS_Tag;
Hiding = (IDNS & HiddenIDNS);
}
-
+
if (!Hiding)
continue;
-
+
DeclarationName Name = Results[I].Declaration->getDeclName();
if (IdentifierInfo *Identifier = Name.getAsIdentifierInfo())
HiddenNames.insert(Identifier->getName());
@@ -1954,7 +2014,7 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
CodeCompletionContext Context,
CodeCompletionResult *Results,
- unsigned NumResults) {
+ unsigned NumResults) {
// Merge the results we were given with the results we cached.
bool AddedResult = false;
uint64_t InContexts =
@@ -1962,31 +2022,31 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
? NormalContexts : (1LL << Context.getKind());
// Contains the set of names that are hidden by "local" completion results.
llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
- typedef CodeCompletionResult Result;
+ using Result = CodeCompletionResult;
SmallVector<Result, 8> AllResults;
- for (ASTUnit::cached_completion_iterator
+ for (ASTUnit::cached_completion_iterator
C = AST.cached_completion_begin(),
CEnd = AST.cached_completion_end();
C != CEnd; ++C) {
- // If the context we are in matches any of the contexts we are
+ // If the context we are in matches any of the contexts we are
// interested in, we'll add this result.
if ((C->ShowInContexts & InContexts) == 0)
continue;
-
+
// If we haven't added any results previously, do so now.
if (!AddedResult) {
- CalculateHiddenNames(Context, Results, NumResults, S.Context,
+ CalculateHiddenNames(Context, Results, NumResults, S.Context,
HiddenNames);
AllResults.insert(AllResults.end(), Results, Results + NumResults);
AddedResult = true;
}
-
+
// Determine whether this global completion result is hidden by a local
// completion result. If so, skip it.
if (C->Kind != CXCursor_MacroDefinition &&
HiddenNames.count(C->Completion->getTypedText()))
continue;
-
+
// Adjust priority based on similar type classes.
unsigned Priority = C->Priority;
CodeCompletionString *Completion = C->Completion;
@@ -1994,7 +2054,7 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
if (C->Kind == CXCursor_MacroDefinition) {
Priority = getMacroUsagePriority(C->Completion->getTypedText(),
S.getLangOpts(),
- Context.getPreferredType()->isAnyPointerType());
+ Context.getPreferredType()->isAnyPointerType());
} else if (C->Type) {
CanQualType Expected
= S.Context.getCanonicalType(
@@ -2013,7 +2073,7 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
}
}
}
-
+
// Adjust the completion string, if required.
if (C->Kind == CXCursor_MacroDefinition &&
Context.getKind() == CodeCompletionContext::CCC_MacroNameUse) {
@@ -2025,18 +2085,18 @@ void AugmentedCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &S,
Priority = CCP_CodePattern;
Completion = Builder.TakeString();
}
-
+
AllResults.push_back(Result(Completion, Priority, C->Kind,
C->Availability));
}
-
+
// If we did not add any cached completion results, just forward the
// results we were given to the next consumer.
if (!AddedResult) {
Next.ProcessCodeCompleteResults(S, Context, Results, NumResults);
return;
}
-
+
Next.ProcessCodeCompleteResults(S, Context, AllResults.data(),
AllResults.size());
}
@@ -2068,6 +2128,8 @@ void ASTUnit::CodeComplete(
CodeCompleteOpts.IncludeCodePatterns = IncludeCodePatterns;
CodeCompleteOpts.IncludeGlobals = CachedCompletionResults.empty();
CodeCompleteOpts.IncludeBriefComments = IncludeBriefComments;
+ CodeCompleteOpts.LoadExternal = Consumer.loadExternal();
+ CodeCompleteOpts.IncludeFixIts = Consumer.includeFixIts();
assert(IncludeBriefComments == this->IncludeBriefCommentsInCodeCompletion);
@@ -2092,11 +2154,11 @@ void ASTUnit::CodeComplete(
auto &Inv = *CCInvocation;
Clang->setInvocation(std::move(CCInvocation));
OriginalSourceFile = Clang->getFrontendOpts().Inputs[0].getFile();
-
+
// Set up diagnostics, capturing any diagnostics produced.
Clang->setDiagnostics(&Diag);
- CaptureDroppedDiagnostics Capture(true,
- Clang->getDiagnostics(),
+ CaptureDroppedDiagnostics Capture(true,
+ Clang->getDiagnostics(),
&StoredDiagnostics, nullptr);
ProcessWarningOptions(Diag, Inv.getDiagnosticOpts());
@@ -2107,13 +2169,13 @@ void ASTUnit::CodeComplete(
Clang->setInvocation(nullptr);
return;
}
-
+
// Inform the target of the language options.
//
// FIXME: We shouldn't need to do this, the target should be immutable once
// created. This complexity should be lifted elsewhere.
Clang->getTarget().adjust(Clang->getLangOpts());
-
+
assert(Clang->getFrontendOpts().Inputs.size() == 1 &&
"Invocation must have exactly one source file!");
assert(Clang->getFrontendOpts().Inputs[0].getKind().getFormat() ==
@@ -2122,7 +2184,7 @@ void ASTUnit::CodeComplete(
assert(Clang->getFrontendOpts().Inputs[0].getKind().getLanguage() !=
InputKind::LLVM_IR &&
"IR inputs not support here!");
-
+
// Use the source and file managers that we were given.
Clang->setFileManager(&FileMgr);
Clang->setSourceManager(&SourceMgr);
@@ -2209,7 +2271,7 @@ bool ASTUnit::Save(StringRef File) {
if (llvm::sys::fs::createUniqueFile(TempPath, fd, TempPath))
return true;
- // FIXME: Can we somehow regenerate the stat cache here, or do we need to
+ // FIXME: Can we somehow regenerate the stat cache here, or do we need to
// unconditionally create a stat cache when we parse the file?
llvm::raw_fd_ostream Out(fd, /*shouldClose=*/true);
@@ -2257,7 +2319,7 @@ bool ASTUnit::serialize(raw_ostream &OS) {
return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
}
-typedef ContinuousRangeMap<unsigned, int, 2> SLocRemap;
+using SLocRemap = ContinuousRangeMap<unsigned, int, 2>;
void ASTUnit::TranslateStoredDiagnostics(
FileManager &FileMgr,
@@ -2271,7 +2333,7 @@ void ASTUnit::TranslateStoredDiagnostics(
SmallVector<StoredDiagnostic, 4> Result;
Result.reserve(Diags.size());
- for (const StandaloneDiagnostic &SD : Diags) {
+ for (const auto &SD : Diags) {
// Rebuild the StoredDiagnostic.
if (SD.Filename.empty())
continue;
@@ -2303,7 +2365,7 @@ void ASTUnit::TranslateStoredDiagnostics(
SmallVector<FixItHint, 2> FixIts;
FixIts.reserve(SD.FixIts.size());
- for (const StandaloneFixIt &FixIt : SD.FixIts) {
+ for (const auto &FixIt : SD.FixIts) {
FixIts.push_back(FixItHint());
FixItHint &FH = FixIts.back();
FH.CodeToInsert = FixIt.CodeToInsert;
@@ -2312,7 +2374,7 @@ void ASTUnit::TranslateStoredDiagnostics(
FH.RemoveRange = CharSourceRange::getCharRange(BL, EL);
}
- Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
+ Result.push_back(StoredDiagnostic(SD.Level, SD.ID,
SD.Message, Loc, Ranges, FixIts));
}
Result.swap(Out);
@@ -2320,7 +2382,7 @@ void ASTUnit::TranslateStoredDiagnostics(
void ASTUnit::addFileLevelDecl(Decl *D) {
assert(D);
-
+
// We only care about local declarations.
if (D->isFromASTFile())
return;
@@ -2397,7 +2459,7 @@ void ASTUnit::findFileRegionDecls(FileID File, unsigned Offset, unsigned Length,
std::make_pair(Offset + Length, (Decl *)nullptr), llvm::less_first());
if (EndIt != LocDecls.end())
++EndIt;
-
+
for (LocDeclsTy::iterator DIt = BeginIt; DIt != EndIt; ++DIt)
Decls.push_back(DIt->second);
}
@@ -2416,7 +2478,7 @@ SourceLocation ASTUnit::getLocation(const FileEntry *File,
return SM.getMacroArgExpandedLocation(FileLoc.getLocWithOffset(Offset));
}
-/// \brief If \arg Loc is a loaded location from the preamble, returns
+/// If \arg Loc is a loaded location from the preamble, returns
/// the corresponding local location of the main file, otherwise it returns
/// \arg Loc.
SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {
@@ -2437,7 +2499,7 @@ SourceLocation ASTUnit::mapLocationFromPreamble(SourceLocation Loc) const {
return Loc;
}
-/// \brief If \arg Loc is a local location of the main file but inside the
+/// If \arg Loc is a local location of the main file but inside the
/// preamble chunk, returns the corresponding loaded location from the
/// preamble, otherwise it returns \arg Loc.
SourceLocation ASTUnit::mapLocationToPreamble(SourceLocation Loc) const {
@@ -2462,10 +2524,10 @@ bool ASTUnit::isInPreambleFileID(SourceLocation Loc) const {
FileID FID;
if (SourceMgr)
FID = SourceMgr->getPreambleFileID();
-
+
if (Loc.isInvalid() || FID.isInvalid())
return false;
-
+
return SourceMgr->isInFileID(Loc, FID);
}
@@ -2473,10 +2535,10 @@ bool ASTUnit::isInMainFileID(SourceLocation Loc) const {
FileID FID;
if (SourceMgr)
FID = SourceMgr->getMainFileID();
-
+
if (Loc.isInvalid() || FID.isInvalid())
return false;
-
+
return SourceMgr->isInFileID(Loc, FID);
}
@@ -2484,9 +2546,9 @@ SourceLocation ASTUnit::getEndOfPreambleFileID() const {
FileID FID;
if (SourceMgr)
FID = SourceMgr->getPreambleFileID();
-
+
if (FID.isInvalid())
- return SourceLocation();
+ return {};
return SourceMgr->getLocForEndOfFile(FID);
}
@@ -2495,10 +2557,10 @@ SourceLocation ASTUnit::getStartOfMainFileID() const {
FileID FID;
if (SourceMgr)
FID = SourceMgr->getMainFileID();
-
+
if (FID.isInvalid())
- return SourceLocation();
-
+ return {};
+
return SourceMgr->getLocForStartOfFile(FID);
}
@@ -2521,7 +2583,7 @@ bool ASTUnit::visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn) {
if (isMainFileAST()) {
serialization::ModuleFile &
Mod = Reader->getModuleManager().getPrimaryModule();
- for (const Decl *D : Reader->getModuleFileLevelDecls(Mod)) {
+ for (const auto *D : Reader->getModuleFileLevelDecls(Mod)) {
if (!Fn(context, D))
return false;
}
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index ba3bd7d28c70..6161b46a9dc5 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -29,6 +29,7 @@ add_clang_library(clangFrontend
FrontendAction.cpp
FrontendActions.cpp
FrontendOptions.cpp
+ FrontendTiming.cpp
HeaderIncludeGen.cpp
InitHeaderSearch.cpp
InitPreprocessor.cpp
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 72e8f68dc051..c4504a14456d 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -21,8 +21,8 @@
#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"
+#include "llvm/Support/DJB.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -88,7 +88,7 @@ public:
void EmitData(raw_ostream& Out) {
using namespace llvm::support;
- endian::Writer<little> LE(Out);
+ endian::Writer LE(Out, little);
switch (Kind) {
case IsFE: {
// Emit stat information.
@@ -128,14 +128,14 @@ public:
typedef unsigned offset_type;
static hash_value_type ComputeHash(PTHEntryKeyVariant V) {
- return llvm::HashString(V.getString());
+ return llvm::djbHash(V.getString());
}
static std::pair<unsigned,unsigned>
EmitKeyDataLength(raw_ostream& Out, PTHEntryKeyVariant V,
const PTHEntry& E) {
using namespace llvm::support;
- endian::Writer<little> LE(Out);
+ endian::Writer LE(Out, little);
unsigned n = V.getString().size() + 1 + 1;
LE.write<uint16_t>(n);
@@ -149,7 +149,7 @@ public:
static void EmitKey(raw_ostream& Out, PTHEntryKeyVariant V, unsigned n){
using namespace llvm::support;
// Emit the entry kind.
- endian::Writer<little>(Out).write<uint8_t>((unsigned)V.getKind());
+ Out << char(V.getKind());
// Emit the string.
Out.write(V.getString().data(), n - 1);
}
@@ -157,7 +157,7 @@ public:
static void EmitData(raw_ostream& Out, PTHEntryKeyVariant V,
const PTHEntry& E, unsigned) {
using namespace llvm::support;
- endian::Writer<little> LE(Out);
+ endian::Writer LE(Out, little);
// For file entries emit the offsets into the PTH file for token data
// and the preprocessor blocks table.
@@ -205,18 +205,17 @@ class PTHWriter {
void EmitToken(const Token& T);
void Emit8(uint32_t V) {
- using namespace llvm::support;
- endian::Writer<little>(Out).write<uint8_t>(V);
+ Out << char(V);
}
void Emit16(uint32_t V) {
using namespace llvm::support;
- endian::Writer<little>(Out).write<uint16_t>(V);
+ endian::write<uint16_t>(Out, V, little);
}
void Emit32(uint32_t V) {
using namespace llvm::support;
- endian::Writer<little>(Out).write<uint32_t>(V);
+ endian::write<uint32_t>(Out, V, little);
}
void EmitBuf(const char *Ptr, unsigned NumBytes) {
@@ -225,7 +224,7 @@ class PTHWriter {
void EmitString(StringRef V) {
using namespace llvm::support;
- endian::Writer<little>(Out).write<uint16_t>(V.size());
+ endian::write<uint16_t>(Out, V.size(), little);
EmitBuf(V.data(), V.size());
}
@@ -299,7 +298,7 @@ PTHEntry PTHWriter::LexTokens(Lexer& L) {
// Pad 0's so that we emit tokens to a 4-byte alignment.
// This speed up reading them back in.
using namespace llvm::support;
- endian::Writer<little> LE(Out);
+ endian::Writer LE(Out, little);
uint32_t TokenOff = Out.tell();
for (uint64_t N = llvm::OffsetToAlignment(TokenOff, 4); N; --N, ++TokenOff)
LE.write<uint8_t>(0);
@@ -625,14 +624,14 @@ public:
typedef unsigned offset_type;
static hash_value_type ComputeHash(PTHIdKey* key) {
- return llvm::HashString(key->II->getName());
+ return llvm::djbHash(key->II->getName());
}
static std::pair<unsigned,unsigned>
EmitKeyDataLength(raw_ostream& Out, const PTHIdKey* key, uint32_t) {
using namespace llvm::support;
unsigned n = key->II->getLength() + 1;
- endian::Writer<little>(Out).write<uint16_t>(n);
+ endian::write<uint16_t>(Out, n, little);
return std::make_pair(n, sizeof(uint32_t));
}
@@ -646,7 +645,7 @@ public:
static void EmitData(raw_ostream& Out, PTHIdKey*, uint32_t pID,
unsigned) {
using namespace llvm::support;
- endian::Writer<little>(Out).write<uint32_t>(pID);
+ endian::write<uint32_t>(Out, pID, little);
}
};
} // end anonymous namespace
@@ -662,7 +661,8 @@ std::pair<Offset,Offset> PTHWriter::EmitIdentifierTable() {
// (2) a map from (IdentifierInfo*, Offset)* -> persistent IDs
// Note that we use 'calloc', so all the bytes are 0.
- PTHIdKey *IIDMap = (PTHIdKey*)calloc(idcount, sizeof(PTHIdKey));
+ PTHIdKey *IIDMap = static_cast<PTHIdKey*>(
+ llvm::safe_calloc(idcount, sizeof(PTHIdKey)));
// Create the hashtable.
llvm::OnDiskChainedHashTableGenerator<PTHIdentifierTableTrait> IIOffMap;
diff --git a/lib/Frontend/CodeGenOptions.cpp b/lib/Frontend/CodeGenOptions.cpp
index 50bb9f951be4..84a39f2d570d 100644
--- a/lib/Frontend/CodeGenOptions.cpp
+++ b/lib/Frontend/CodeGenOptions.cpp
@@ -17,7 +17,7 @@ CodeGenOptions::CodeGenOptions() {
#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default);
#include "clang/Frontend/CodeGenOptions.def"
- RelocationModel = "pic";
+ RelocationModel = llvm::Reloc::PIC_;
memcpy(CoverageVersion, "402*", 4);
}
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 7208177aa012..155ead4ac8e8 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -16,6 +16,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/MemoryBufferCache.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Config/config.h"
@@ -302,11 +303,9 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
FileManager *CompilerInstance::createFileManager() {
if (!hasVirtualFileSystem()) {
- if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
- createVFSFromCompilerInvocation(getInvocation(), getDiagnostics()))
- setVirtualFileSystem(VFS);
- else
- return nullptr;
+ IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+ createVFSFromCompilerInvocation(getInvocation(), getDiagnostics());
+ setVirtualFileSystem(VFS);
}
FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem);
return FileMgr.get();
@@ -464,7 +463,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
/*ShowDepth=*/false);
}
- if (DepOpts.PrintShowIncludes) {
+ if (DepOpts.ShowIncludesDest != ShowIncludesDestination::None) {
AttachHeaderIncludeGen(*PP, DepOpts,
/*ShowAllHeaders=*/true, /*OutputPath=*/"",
/*ShowDepth=*/true, /*MSStyle=*/true);
@@ -854,36 +853,7 @@ bool CompilerInstance::InitializeSourceManager(
// Figure out where to get and map in the main file.
if (InputFile != "-") {
- const FileEntry *File;
- if (Opts.FindPchSource.empty()) {
- File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
- } else {
- // When building a pch file in clang-cl mode, the .h file is built as if
- // it was included by a cc file. Since the driver doesn't know about
- // all include search directories, the frontend must search the input
- // file through HeaderSearch here, as if it had been included by the
- // cc file at Opts.FindPchSource.
- const FileEntry *FindFile = FileMgr.getFile(Opts.FindPchSource);
- if (!FindFile) {
- Diags.Report(diag::err_fe_error_reading) << Opts.FindPchSource;
- return false;
- }
- const DirectoryLookup *UnusedCurDir;
- SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 16>
- Includers;
- Includers.push_back(std::make_pair(FindFile, FindFile->getDir()));
- File = HS->LookupFile(InputFile, SourceLocation(), /*isAngled=*/false,
- /*FromDir=*/nullptr,
- /*CurDir=*/UnusedCurDir, Includers,
- /*SearchPath=*/nullptr,
- /*RelativePath=*/nullptr,
- /*RequestingModule=*/nullptr,
- /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr,
- /*SkipCache=*/true);
- // Also add the header to /showIncludes output.
- if (File)
- DepOpts.ShowIncludesPretendHeader = File->getName();
- }
+ const FileEntry *File = FileMgr.getFile(InputFile, /*OpenFile=*/true);
if (!File) {
Diags.Report(diag::err_fe_error_reading) << InputFile;
return false;
@@ -1044,7 +1014,7 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
return !getDiagnostics().getClient()->getNumErrors();
}
-/// \brief Determine the appropriate source input kind based on language
+/// Determine the appropriate source input kind based on language
/// options.
static InputKind::Language getLanguageFromOptions(const LangOptions &LangOpts) {
if (LangOpts.OpenCL)
@@ -1056,7 +1026,7 @@ static InputKind::Language getLanguageFromOptions(const LangOptions &LangOpts) {
return LangOpts.CPlusPlus ? InputKind::CXX : InputKind::C;
}
-/// \brief Compile a module file for the given module, using the options
+/// Compile a module file for the given module, using the options
/// provided by the importing compiler instance. Returns true if the module
/// was built without errors.
static bool
@@ -1090,6 +1060,10 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
}),
PPOpts.Macros.end());
+ // If the original compiler invocation had -fmodule-name, pass it through.
+ Invocation->getLangOpts()->ModuleName =
+ ImportingInstance.getInvocation().getLangOpts()->ModuleName;
+
// Note the name of the module we're building.
Invocation->getLangOpts()->CurrentModule = ModuleName;
@@ -1162,14 +1136,13 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
// Execute the action to actually build the module in-place. Use a separate
// thread so that we get a stack large enough.
- const unsigned ThreadStackSize = 8 << 20;
llvm::CrashRecoveryContext CRC;
CRC.RunSafelyOnThread(
[&]() {
GenerateModuleFromModuleMapAction Action;
Instance.ExecuteAction(Action);
},
- ThreadStackSize);
+ DesiredStackSize);
PostBuildStep(Instance);
@@ -1186,7 +1159,20 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
return !Instance.getDiagnostics().hasErrorOccurred();
}
-/// \brief Compile a module file for the given module, using the options
+static const FileEntry *getPublicModuleMap(const FileEntry *File,
+ FileManager &FileMgr) {
+ StringRef Filename = llvm::sys::path::filename(File->getName());
+ SmallString<128> PublicFilename(File->getDir()->getName());
+ if (Filename == "module_private.map")
+ llvm::sys::path::append(PublicFilename, "module.map");
+ else if (Filename == "module.private.modulemap")
+ llvm::sys::path::append(PublicFilename, "module.modulemap");
+ else
+ return nullptr;
+ return FileMgr.getFile(PublicFilename);
+}
+
+/// Compile a module file for the given module, using the options
/// provided by the importing compiler instance. Returns true if the module
/// was built without errors.
static bool compileModuleImpl(CompilerInstance &ImportingInstance,
@@ -1202,6 +1188,13 @@ static bool compileModuleImpl(CompilerInstance &ImportingInstance,
bool Result;
if (const FileEntry *ModuleMapFile =
ModMap.getContainingModuleMapFile(Module)) {
+ // Canonicalize compilation to start with the public module map. This is
+ // vital for submodules declarations in the private module maps to be
+ // correctly parsed when depending on a top level module in the public one.
+ if (const FileEntry *PublicMMFile = getPublicModuleMap(
+ ModuleMapFile, ImportingInstance.getFileManager()))
+ ModuleMapFile = PublicMMFile;
+
// Use the module map where this module resides.
Result = compileModuleImpl(
ImportingInstance, ImportLoc, Module->getTopLevelModuleName(),
@@ -1298,7 +1291,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
// case of timeout, build it ourselves.
Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
<< Module->Name;
- // Clear the lock file so that future invokations can make progress.
+ // Clear the lock file so that future invocations can make progress.
Locked.unsafeRemoveLockFile();
continue;
}
@@ -1328,7 +1321,7 @@ static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
}
}
-/// \brief Diagnose differences between the current definition of the given
+/// Diagnose differences between the current definition of the given
/// configuration macro and the definition provided on the command line.
static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
Module *Mod, SourceLocation ImportLoc) {
@@ -1386,13 +1379,13 @@ static void checkConfigMacro(Preprocessor &PP, StringRef ConfigMacro,
}
}
-/// \brief Write a new timestamp file with the given path.
+/// Write a new timestamp file with the given path.
static void writeTimestampFile(StringRef TimestampFile) {
std::error_code EC;
llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
}
-/// \brief Prune the module cache of modules that haven't been accessed in
+/// Prune the module cache of modules that haven't been accessed in
/// a long time.
static void pruneModuleCache(const HeaderSearchOptions &HSOpts) {
struct stat StatBuf;
@@ -1580,15 +1573,22 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
if (!ModuleManager)
createModuleManager();
+ // If -Wmodule-file-config-mismatch is mapped as an error or worse, allow the
+ // ASTReader to diagnose it, since it can produce better errors that we can.
+ bool ConfigMismatchIsRecoverable =
+ getDiagnostics().getDiagnosticLevel(diag::warn_module_config_mismatch,
+ SourceLocation())
+ <= DiagnosticsEngine::Warning;
+
auto Listener = llvm::make_unique<ReadModuleNames>(*this);
auto &ListenerRef = *Listener;
ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager,
std::move(Listener));
// Try to load the module file.
- switch (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule,
- SourceLocation(),
- ASTReader::ARR_ConfigurationMismatch)) {
+ switch (ModuleManager->ReadAST(
+ FileName, serialization::MK_ExplicitModule, SourceLocation(),
+ ConfigMismatchIsRecoverable ? ASTReader::ARR_ConfigurationMismatch : 0)) {
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.
@@ -1653,8 +1653,10 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
// Retrieve the cached top-level module.
Module = Known->second;
} else if (ModuleName == getLangOpts().CurrentModule) {
- // This is the module we're building.
- Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
+ // This is the module we're building.
+ Module = PP->getHeaderSearchInfo().lookupModule(
+ ModuleName, /*AllowSearch*/ true,
+ /*AllowExtraModuleMapSearch*/ !IsInclusionDirective);
/// FIXME: perhaps we should (a) look for a module using the module name
// to file map (PrebuiltModuleFiles) and (b) diagnose if still not found?
//if (Module == nullptr) {
@@ -1666,7 +1668,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
} else {
// Search for a module with the given name.
- Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
+ Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true,
+ !IsInclusionDirective);
HeaderSearchOptions &HSOpts =
PP->getHeaderSearchInfo().getHeaderSearchOpts();
@@ -1743,7 +1746,8 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
ImportLoc, ARRFlags)) {
case ASTReader::Success: {
if (Source != ModuleCache && !Module) {
- Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
+ Module = PP->getHeaderSearchInfo().lookupModule(ModuleName, true,
+ !IsInclusionDirective);
if (!Module || !Module->getASTFile() ||
FileMgr->getFile(ModuleFileName) != Module->getASTFile()) {
// Error out if Module does not refer to the file in the prebuilt
@@ -1859,6 +1863,40 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
for (unsigned I = 1, N = Path.size(); I != N; ++I) {
StringRef Name = Path[I].first->getName();
clang::Module *Sub = Module->findSubmodule(Name);
+
+ // If the user is requesting Foo.Private and it doesn't exist, try to
+ // match Foo_Private and emit a warning asking for the user to write
+ // @import Foo_Private instead. FIXME: remove this when existing clients
+ // migrate off of Foo.Private syntax.
+ if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" &&
+ Module == Module->getTopLevelModule()) {
+ SmallString<128> PrivateModule(Module->Name);
+ PrivateModule.append("_Private");
+
+ SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;
+ auto &II = PP->getIdentifierTable().get(
+ PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());
+ PrivPath.push_back(std::make_pair(&II, Path[0].second));
+
+ if (PP->getHeaderSearchInfo().lookupModule(PrivateModule, true,
+ !IsInclusionDirective))
+ Sub =
+ loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective);
+ if (Sub) {
+ MapPrivateSubModToTopLevel = true;
+ if (!getDiagnostics().isIgnored(
+ diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
+ getDiagnostics().Report(Path[I].second,
+ diag::warn_no_priv_submodule_use_toplevel)
+ << Path[I].first << Module->getFullModuleName() << PrivateModule
+ << SourceRange(Path[0].second, Path[I].second)
+ << FixItHint::CreateReplacement(SourceRange(Path[0].second),
+ PrivateModule);
+ getDiagnostics().Report(Sub->DefinitionLoc,
+ diag::note_private_top_level_defined);
+ }
+ }
+ }
if (!Sub) {
// Attempt to perform typo correction to find a module name that works.
@@ -1894,39 +1932,6 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
}
}
- // If the user is requesting Foo.Private and it doesn't exist, try to
- // match Foo_Private and emit a warning asking for the user to write
- // @import Foo_Private instead. FIXME: remove this when existing clients
- // migrate off of Foo.Private syntax.
- if (!Sub && PP->getLangOpts().ImplicitModules && Name == "Private" &&
- Module == Module->getTopLevelModule()) {
- SmallString<128> PrivateModule(Module->Name);
- PrivateModule.append("_Private");
-
- SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> PrivPath;
- auto &II = PP->getIdentifierTable().get(
- PrivateModule, PP->getIdentifierInfo(Module->Name)->getTokenID());
- PrivPath.push_back(std::make_pair(&II, Path[0].second));
-
- if (PP->getHeaderSearchInfo().lookupModule(PrivateModule))
- Sub =
- loadModule(ImportLoc, PrivPath, Visibility, IsInclusionDirective);
- if (Sub) {
- MapPrivateSubModToTopLevel = true;
- if (!getDiagnostics().isIgnored(
- diag::warn_no_priv_submodule_use_toplevel, ImportLoc)) {
- getDiagnostics().Report(Path[I].second,
- diag::warn_no_priv_submodule_use_toplevel)
- << Path[I].first << Module->getFullModuleName() << PrivateModule
- << SourceRange(Path[0].second, Path[I].second)
- << FixItHint::CreateReplacement(SourceRange(Path[0].second),
- PrivateModule);
- getDiagnostics().Report(Sub->DefinitionLoc,
- diag::note_private_top_level_defined);
- }
- }
- }
-
if (!Sub) {
// No submodule by this name. Complain, and don't look for further
// submodules.
@@ -1977,6 +1982,12 @@ CompilerInstance::loadModule(SourceLocation ImportLoc,
Module, ImportLoc);
}
+ // Resolve any remaining module using export_as for this one.
+ getPreprocessor()
+ .getHeaderSearchInfo()
+ .getModuleMap()
+ .resolveLinkAsDependencies(TopModule);
+
LastModuleImportLoc = ImportLoc;
LastModuleImportResult = ModuleLoadResult(Module);
return LastModuleImportResult;
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 2e8a737de4e4..78e6babd0251 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1,4 +1,4 @@
-//===--- CompilerInvocation.cpp -------------------------------------------===//
+//===- CompilerInvocation.cpp ---------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,54 +10,99 @@
#include "clang/Frontend/CompilerInvocation.h"
#include "TestModuleFileExtension.h"
#include "clang/Basic/Builtins.h"
-#include "clang/Basic/FileManager.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/DebugInfoOptions.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileSystemOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/Version.h"
+#include "clang/Basic/VirtualFileSystem.h"
+#include "clang/Basic/Visibility.h"
+#include "clang/Basic/XRayInstr.h"
#include "clang/Config/config.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
-#include "clang/Driver/Util.h"
+#include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/FrontendOptions.h"
#include "clang/Frontend/LangStandard.h"
+#include "clang/Frontend/MigratorOptions.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "clang/Lex/PreprocessorOptions.h"
-#include "clang/Serialization/ASTReader.h"
+#include "clang/Sema/CodeCompleteOptions.h"
#include "clang/Serialization/ModuleFileExtension.h"
+#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/CachedHashString.h"
#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Linker/Linker.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Option/OptSpecifier.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/CodeGen.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/VersionTuple.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Support/ScopedPrinter.h"
+#include <algorithm>
#include <atomic>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
#include <memory>
-#include <sys/stat.h>
-#include <system_error>
+#include <string>
+#include <tuple>
+#include <utility>
+#include <vector>
+
using namespace clang;
+using namespace driver;
+using namespace options;
+using namespace llvm::opt;
//===----------------------------------------------------------------------===//
// Initialization.
//===----------------------------------------------------------------------===//
CompilerInvocationBase::CompilerInvocationBase()
- : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()),
- DiagnosticOpts(new DiagnosticOptions()),
- HeaderSearchOpts(new HeaderSearchOptions()),
- PreprocessorOpts(new PreprocessorOptions()) {}
+ : LangOpts(new LangOptions()), TargetOpts(new TargetOptions()),
+ DiagnosticOpts(new DiagnosticOptions()),
+ HeaderSearchOpts(new HeaderSearchOptions()),
+ PreprocessorOpts(new PreprocessorOptions()) {}
CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
: LangOpts(new LangOptions(*X.getLangOpts())),
@@ -66,18 +111,12 @@ CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
HeaderSearchOpts(new HeaderSearchOptions(X.getHeaderSearchOpts())),
PreprocessorOpts(new PreprocessorOptions(X.getPreprocessorOpts())) {}
-CompilerInvocationBase::~CompilerInvocationBase() {}
+CompilerInvocationBase::~CompilerInvocationBase() = default;
//===----------------------------------------------------------------------===//
// Deserialization (from args)
//===----------------------------------------------------------------------===//
-using namespace clang::driver;
-using namespace clang::driver::options;
-using namespace llvm::opt;
-
-//
-
static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags) {
unsigned DefaultOpt = 0;
@@ -91,7 +130,7 @@ static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
if (A->getOption().matches(options::OPT_Ofast))
return 3;
- assert (A->getOption().matches(options::OPT_O));
+ assert(A->getOption().matches(options::OPT_O));
StringRef S(A->getValue());
if (S == "s" || S == "z" || S.empty())
@@ -125,7 +164,7 @@ static unsigned getOptimizationLevelSize(ArgList &Args) {
static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
OptSpecifier GroupWithValue,
std::vector<std::string> &Diagnostics) {
- for (Arg *A : Args.filtered(Group)) {
+ for (auto *A : Args.filtered(Group)) {
if (A->getOption().getKind() == Option::FlagClass) {
// The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
// its name (minus the "W" or "R" at the beginning) to the warning list.
@@ -135,7 +174,7 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-"));
} else {
// Otherwise, add its value (for OPT_W_Joined and similar).
- for (const char *Arg : A->getValues())
+ for (const auto *Arg : A->getValues())
Diagnostics.emplace_back(Arg);
}
}
@@ -157,7 +196,6 @@ static void getAllNoBuiltinFuncValues(ArgList &Args,
static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
- using namespace options;
bool Success = true;
if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
StringRef Name = A->getValue();
@@ -273,31 +311,31 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
StringRef checkerList = A->getValue();
SmallVector<StringRef, 4> checkers;
checkerList.split(checkers, ",");
- for (StringRef checker : checkers)
+ for (auto checker : checkers)
Opts.CheckersControlList.emplace_back(checker, enable);
}
// Go through the analyzer configuration options.
- for (const Arg *A : Args.filtered(OPT_analyzer_config)) {
+ for (const auto *A : Args.filtered(OPT_analyzer_config)) {
A->claim();
// We can have a list of comma separated config names, e.g:
// '-analyzer-config key1=val1,key2=val2'
StringRef configList = A->getValue();
SmallVector<StringRef, 4> configVals;
configList.split(configVals, ",");
- for (unsigned i = 0, e = configVals.size(); i != e; ++i) {
+ for (const auto &configVal : configVals) {
StringRef key, val;
- std::tie(key, val) = configVals[i].split("=");
+ std::tie(key, val) = configVal.split("=");
if (val.empty()) {
Diags.Report(SourceLocation(),
- diag::err_analyzer_config_no_value) << configVals[i];
+ diag::err_analyzer_config_no_value) << configVal;
Success = false;
break;
}
if (val.find('=') != StringRef::npos) {
Diags.Report(SourceLocation(),
diag::err_analyzer_config_multiple_values)
- << configVals[i];
+ << configVal;
Success = false;
break;
}
@@ -305,6 +343,14 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
}
}
+ llvm::raw_string_ostream os(Opts.FullCompilerInvocation);
+ for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {
+ if (i != 0)
+ os << " ";
+ os << Args.getArgString(i);
+ }
+ os.flush();
+
return Success;
}
@@ -330,18 +376,26 @@ static StringRef getCodeModel(ArgList &Args, DiagnosticsEngine &Diags) {
return "default";
}
-static StringRef getRelocModel(ArgList &Args, DiagnosticsEngine &Diags) {
+static llvm::Reloc::Model getRelocModel(ArgList &Args,
+ DiagnosticsEngine &Diags) {
if (Arg *A = Args.getLastArg(OPT_mrelocation_model)) {
StringRef Value = A->getValue();
- if (Value == "static" || Value == "pic" || Value == "ropi" ||
- Value == "rwpi" || Value == "ropi-rwpi" || Value == "dynamic-no-pic")
- return Value;
+ auto RM = llvm::StringSwitch<llvm::Optional<llvm::Reloc::Model>>(Value)
+ .Case("static", llvm::Reloc::Static)
+ .Case("pic", llvm::Reloc::PIC_)
+ .Case("ropi", llvm::Reloc::ROPI)
+ .Case("rwpi", llvm::Reloc::RWPI)
+ .Case("ropi-rwpi", llvm::Reloc::ROPI_RWPI)
+ .Case("dynamic-no-pic", llvm::Reloc::DynamicNoPIC)
+ .Default(None);
+ if (RM.hasValue())
+ return *RM;
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Value;
}
- return "pic";
+ return llvm::Reloc::PIC_;
}
-/// \brief Create a new Regex instance out of the string value in \p RpassArg.
+/// Create a new Regex instance out of the string value in \p RpassArg.
/// It returns a pointer to the newly generated Regex instance.
static std::shared_ptr<llvm::Regex>
GenerateOptimizationRemarkRegex(DiagnosticsEngine &Diags, ArgList &Args,
@@ -392,6 +446,25 @@ static void parseSanitizerKinds(StringRef FlagName,
}
}
+static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
+ ArgList &Args, DiagnosticsEngine &D,
+ XRayInstrSet &S) {
+ llvm::SmallVector<StringRef, 2> BundleParts;
+ llvm::SplitString(Bundle, BundleParts, ",");
+ for (const auto B : BundleParts) {
+ auto Mask = parseXRayInstrValue(B);
+ if (Mask == XRayInstrKind::None)
+ if (B != "none")
+ D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
+ else
+ S.Mask = Mask;
+ else if (Mask == XRayInstrKind::All)
+ S.Mask = Mask;
+ else
+ S.set(Mask, true);
+ }
+}
+
// Set the profile kind for fprofile-instrument.
static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
@@ -409,8 +482,7 @@ static void setPGOInstrumentor(CodeGenOptions &Opts, ArgList &Args,
<< S;
return;
}
- CodeGenOptions::ProfileInstrKind Instrumentor =
- static_cast<CodeGenOptions::ProfileInstrKind>(I);
+ auto Instrumentor = static_cast<CodeGenOptions::ProfileInstrKind>(I);
Opts.setProfileInstr(Instrumentor);
}
@@ -434,8 +506,8 @@ static void setPGOUseInstrumentor(CodeGenOptions &Opts,
static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags,
- const TargetOptions &TargetOpts) {
- using namespace options;
+ const TargetOptions &TargetOpts,
+ const FrontendOptions &FrontendOpts) {
bool Success = true;
llvm::Triple Triple = llvm::Triple(TargetOpts.Triple);
@@ -474,7 +546,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.ExperimentalNewPassManager = Args.hasFlag(
OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager,
- /* Default */ false);
+ /* Default */ ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER);
Opts.DebugPassManager =
Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager,
@@ -529,6 +601,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import);
Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params);
+ Opts.EmbedSource = Args.hasArg(OPT_gembed_source);
for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ))
Opts.DebugPrefixMap.insert(StringRef(Arg).split('='));
@@ -552,7 +625,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Args.hasFlag(OPT_ffine_grained_bitfield_accesses,
OPT_fno_fine_grained_bitfield_accesses, false);
Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags);
- Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
+ Opts.MergeAllConstants = Args.hasArg(OPT_fmerge_all_constants);
Opts.NoCommon = Args.hasArg(OPT_fno_common);
Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
Opts.OptimizeSize = getOptimizationLevelSize(Args);
@@ -580,33 +653,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
if (!Opts.ProfileInstrumentUsePath.empty())
setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
- if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
- Opts.setClangABICompat(CodeGenOptions::ClangABI::Latest);
-
- StringRef Ver = A->getValue();
- std::pair<StringRef, StringRef> VerParts = Ver.split('.');
- unsigned Major, Minor = 0;
-
- // Check the version number is valid: either 3.x (0 <= x <= 9) or
- // y or y.0 (4 <= y <= current version).
- if (!VerParts.first.startswith("0") &&
- !VerParts.first.getAsInteger(10, Major) &&
- 3 <= Major && Major <= CLANG_VERSION_MAJOR &&
- (Major == 3 ? VerParts.second.size() == 1 &&
- !VerParts.second.getAsInteger(10, Minor)
- : VerParts.first.size() == Ver.size() ||
- VerParts.second == "0")) {
- // Got a valid version number.
- if (Major == 3 && Minor <= 8)
- Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver3_8);
- else if (Major <= 4)
- Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver4);
- } else if (Ver != "latest") {
- Diags.Report(diag::err_drv_invalid_value)
- << A->getAsString(Args) << A->getValue();
- }
- }
-
Opts.CoverageMapping =
Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
@@ -615,6 +661,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
+ Opts.RegisterGlobalDtorsWithAtExit =
+ Args.hasArg(OPT_fregister_global_dtors_with_atexit);
Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.CodeModel = getCodeModel(Args, Diags);
Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass);
@@ -623,6 +671,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DisableFree = Args.hasArg(OPT_disable_free);
Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names);
Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
+ Opts.NoEscapingBlockTailCalls =
+ Args.hasArg(OPT_fno_escaping_block_tail_calls);
Opts.FloatABI = Args.getLastArgValue(OPT_mfloat_abi);
Opts.LessPreciseFPMAD = Args.hasArg(OPT_cl_mad_enable) ||
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
@@ -640,14 +690,20 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math));
Opts.Reassociate = Args.hasArg(OPT_mreassociate);
- Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero);
+ Opts.FlushDenorm = Args.hasArg(OPT_cl_denorms_are_zero) ||
+ (Args.hasArg(OPT_fcuda_is_device) &&
+ Args.hasArg(OPT_fcuda_flush_denormals_to_zero));
Opts.CorrectlyRoundedDivSqrt =
Args.hasArg(OPT_cl_fp32_correctly_rounded_divide_sqrt);
+ Opts.UniformWGSize =
+ Args.hasArg(OPT_cl_uniform_work_group_size);
Opts.Reciprocals = Args.getAllArgValues(OPT_mrecip_EQ);
Opts.ReciprocalMath = Args.hasArg(OPT_freciprocal_math);
Opts.NoTrappingMath = Args.hasArg(OPT_fno_trapping_math);
+ Opts.StrictFloatCastOverflow =
+ !Args.hasArg(OPT_fno_strict_float_cast_overflow);
+
Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
- Opts.BackendOptions = Args.getAllArgValues(OPT_backend_option);
Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags);
Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
@@ -665,6 +721,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.StrictEnums = Args.hasArg(OPT_fstrict_enums);
Opts.StrictReturn = !Args.hasArg(OPT_fno_strict_return);
Opts.StrictVTablePointers = Args.hasArg(OPT_fstrict_vtable_pointers);
+ Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
@@ -682,6 +739,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
OPT_fno_function_sections, false);
Opts.DataSections = Args.hasFlag(OPT_fdata_sections,
OPT_fno_data_sections, false);
+ Opts.StackSizeSection =
+ Args.hasFlag(OPT_fstack_size_section, OPT_fno_stack_size_section, false);
Opts.UniqueSectionNames = Args.hasFlag(OPT_funique_section_names,
OPT_fno_unique_section_names, true);
@@ -689,14 +748,16 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables);
+ Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks);
+
Opts.ProfileSampleAccurate = Args.hasArg(OPT_fprofile_sample_accurate);
Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
- Opts.EmitSummaryIndex = false;
+ Opts.PrepareForThinLTO = false;
if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
StringRef S = A->getValue();
if (S == "thin")
- Opts.EmitSummaryIndex = true;
+ Opts.PrepareForThinLTO = true;
else if (S != "full")
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
}
@@ -707,6 +768,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
<< A->getAsString(Args) << "-x ir";
Opts.ThinLTOIndexFile = Args.getLastArgValue(OPT_fthinlto_index_EQ);
}
+ if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
+ Opts.SaveTempsFilePrefix =
+ llvm::StringSwitch<std::string>(A->getValue())
+ .Case("obj", FrontendOpts.OutputFile)
+ .Default(llvm::sys::path::filename(FrontendOpts.OutputFile).str());
+
Opts.ThinLinkBitcodeFile = Args.getLastArgValue(OPT_fthin_link_bitcode_EQ);
Opts.MSVolatile = Args.hasArg(OPT_fms_volatile);
@@ -719,6 +786,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.MainFileName = Args.getLastArgValue(OPT_main_file_name);
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
+ Opts.ControlFlowGuard = Args.hasArg(OPT_cfguard);
+
Opts.DisableGCov = Args.hasArg(OPT_test_coverage);
Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
@@ -741,7 +810,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}
}
- // Handle -fembed-bitcode option.
+ // Handle -fembed-bitcode option.
if (Arg *A = Args.getLastArg(OPT_fembed_bitcode_EQ)) {
StringRef Name = A->getValue();
unsigned Model = llvm::StringSwitch<unsigned>(Name)
@@ -787,15 +856,44 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Args.hasArg(OPT_finstrument_functions_after_inlining);
Opts.InstrumentFunctionEntryBare =
Args.hasArg(OPT_finstrument_function_entry_bare);
- Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument);
+
+ Opts.XRayInstrumentFunctions =
+ Args.hasArg(OPT_fxray_instrument);
Opts.XRayAlwaysEmitCustomEvents =
Args.hasArg(OPT_fxray_always_emit_customevents);
+ Opts.XRayAlwaysEmitTypedEvents =
+ Args.hasArg(OPT_fxray_always_emit_typedevents);
Opts.XRayInstructionThreshold =
getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
+
+ auto XRayInstrBundles =
+ Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
+ if (XRayInstrBundles.empty())
+ Opts.XRayInstrumentationBundle.Mask = XRayInstrKind::All;
+ else
+ for (const auto &A : XRayInstrBundles)
+ parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
+ Diags, Opts.XRayInstrumentationBundle);
+
Opts.InstrumentForProfiling = Args.hasArg(OPT_pg);
Opts.CallFEntry = Args.hasArg(OPT_mfentry);
Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info);
+ if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
+ StringRef Name = A->getValue();
+ if (Name == "full") {
+ Opts.CFProtectionReturn = 1;
+ Opts.CFProtectionBranch = 1;
+ } else if (Name == "return")
+ Opts.CFProtectionReturn = 1;
+ else if (Name == "branch")
+ Opts.CFProtectionBranch = 1;
+ else if (Name != "none") {
+ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+ Success = false;
+ }
+ }
+
if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections,
OPT_compress_debug_sections_EQ)) {
if (A->getOption().getID() == OPT_compress_debug_sections) {
@@ -813,7 +911,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations);
Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
- for (auto A : Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) {
+ for (auto *A :
+ Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_cuda_bitcode)) {
CodeGenOptions::BitcodeFileToLink F;
F.Filename = A->getValue();
if (A->getOption().matches(OPT_mlink_cuda_bitcode)) {
@@ -855,6 +954,13 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.SanitizeCfiICallGeneralizePointers =
Args.hasArg(OPT_fsanitize_cfi_icall_generalize_pointers);
Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats);
+ if (Arg *A = Args.getLastArg(
+ OPT_fsanitize_address_poison_class_member_array_new_cookie,
+ OPT_fno_sanitize_address_poison_class_member_array_new_cookie)) {
+ Opts.SanitizeAddressPoisonClassMemberArrayNewCookie =
+ A->getOption().getID() ==
+ OPT_fsanitize_address_poison_class_member_array_new_cookie;
+ }
if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope,
OPT_fno_sanitize_address_use_after_scope)) {
Opts.SanitizeAddressUseAfterScope =
@@ -879,6 +985,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.StackProbeSize = StackProbeSize;
}
+ Opts.NoStackArgProbe = Args.hasArg(OPT_mno_stack_arg_probe);
+
if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
StringRef Name = A->getValue();
unsigned Method = llvm::StringSwitch<unsigned>(Name)
@@ -895,8 +1003,12 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}
- Opts.EmulatedTLS =
- Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false);
+ if (Args.getLastArg(OPT_femulated_tls) ||
+ Args.getLastArg(OPT_fno_emulated_tls)) {
+ Opts.ExplicitEmulatedTLS = true;
+ Opts.EmulatedTLS =
+ Args.hasFlag(OPT_femulated_tls, OPT_fno_emulated_tls, false);
+ }
if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
StringRef Name = A->getValue();
@@ -967,7 +1079,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
bool UsingProfile = UsingSampleProfile ||
(Opts.getProfileUse() != CodeGenOptions::ProfileNone);
- if (Opts.DiagnosticsWithHotness && !UsingProfile)
+ if (Opts.DiagnosticsWithHotness && !UsingProfile &&
+ // An IR file will contain PGO as metadata
+ IK.getLanguage() != InputKind::LLVM_IR)
Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
<< "-fdiagnostics-show-hotness";
@@ -999,20 +1113,23 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
Opts.SanitizeTrap);
- Opts.CudaGpuBinaryFileNames =
- Args.getAllArgValues(OPT_fcuda_include_gpubinary);
+ Opts.CudaGpuBinaryFileName =
+ Args.getLastArgValue(OPT_fcuda_include_gpubinary);
Opts.Backchain = Args.hasArg(OPT_mbackchain);
Opts.EmitCheckPathComponentsToStrip = getLastArgIntValue(
Args, OPT_fsanitize_undefined_strip_path_components_EQ, 0, Diags);
+ Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
+
+ Opts.Addrsig = Args.hasArg(OPT_faddrsig);
+
return Success;
}
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
ArgList &Args) {
- using namespace options;
Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
Opts.Targets = Args.getAllArgValues(OPT_MT);
Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
@@ -1021,7 +1138,17 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
Opts.ShowHeaderIncludes = Args.hasArg(OPT_H);
Opts.HeaderIncludeOutputFile = Args.getLastArgValue(OPT_header_include_file);
Opts.AddMissingHeaderDeps = Args.hasArg(OPT_MG);
- Opts.PrintShowIncludes = Args.hasArg(OPT_show_includes);
+ if (Args.hasArg(OPT_show_includes)) {
+ // Writing both /showIncludes and preprocessor output to stdout
+ // would produce interleaved output, so use stderr for /showIncludes.
+ // This behaves the same as cl.exe, when /E, /EP or /P are passed.
+ if (Args.hasArg(options::OPT_E) || Args.hasArg(options::OPT_P))
+ Opts.ShowIncludesDest = ShowIncludesDestination::Stderr;
+ else
+ Opts.ShowIncludesDest = ShowIncludesDestination::Stdout;
+ } else {
+ Opts.ShowIncludesDest = ShowIncludesDestination::None;
+ }
Opts.DOTOutputFile = Args.getLastArgValue(OPT_dependency_dot);
Opts.ModuleDependencyOutputDir =
Args.getLastArgValue(OPT_module_dependency_dir);
@@ -1032,7 +1159,7 @@ static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
// we let make / ninja to know about this implicit dependency.
Opts.ExtraDeps = Args.getAllArgValues(OPT_fdepfile_entry);
// Only the -fmodule-file=<file> form.
- for (const Arg *A : Args.filtered(OPT_fmodule_file)) {
+ for (const auto *A : Args.filtered(OPT_fmodule_file)) {
StringRef Val = A->getValue();
if (Val.find('=') == StringRef::npos)
Opts.ExtraDeps.push_back(Val);
@@ -1049,7 +1176,7 @@ static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
Colors_Off,
Colors_Auto
} ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
- for (Arg *A : Args) {
+ for (auto *A : Args) {
const Option &O = A->getOption();
if (O.matches(options::OPT_fcolor_diagnostics) ||
O.matches(options::OPT_fdiagnostics_color)) {
@@ -1095,7 +1222,6 @@ static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
DiagnosticsEngine *Diags,
bool DefaultDiagColor, bool DefaultShowOpt) {
- using namespace options;
bool Success = true;
Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file);
@@ -1190,7 +1316,7 @@ bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Success = false;
}
else
- std::sort(Opts.VerifyPrefixes.begin(), Opts.VerifyPrefixes.end());
+ llvm::sort(Opts.VerifyPrefixes.begin(), Opts.VerifyPrefixes.end());
DiagnosticLevelMask DiagMask = DiagnosticLevelMask::None;
Success &= parseDiagnosticLevelMask("-verify-ignore-unexpected=",
Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ),
@@ -1262,7 +1388,6 @@ static bool parseTestModuleFileExtensionArg(StringRef Arg,
static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags,
bool &IsHeaderFile) {
- using namespace options;
Opts.ProgramAction = frontend::ParseSyntaxOnly;
if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
switch (A->getOption().getID()) {
@@ -1278,6 +1403,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ProgramAction = frontend::ASTPrint; break;
case OPT_ast_view:
Opts.ProgramAction = frontend::ASTView; break;
+ case OPT_compiler_options_dump:
+ Opts.ProgramAction = frontend::DumpCompilerOptions; break;
case OPT_dump_raw_tokens:
Opts.ProgramAction = frontend::DumpRawTokens; break;
case OPT_dump_tokens:
@@ -1323,6 +1450,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ProgramAction = frontend::PrintPreamble; break;
case OPT_E:
Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
+ case OPT_templight_dump:
+ Opts.ProgramAction = frontend::TemplightDump; break;
case OPT_rewrite_macros:
Opts.ProgramAction = frontend::RewriteMacros; break;
case OPT_rewrite_objc:
@@ -1344,7 +1473,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.ActionName = A->getValue();
}
Opts.AddPluginActions = Args.getAllArgValues(OPT_add_plugin);
- for (const Arg *AA : Args.filtered(OPT_plugin_arg))
+ for (const auto *AA : Args.filtered(OPT_plugin_arg))
Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
for (const std::string &Arg :
@@ -1397,7 +1526,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
Opts.ModuleMapFiles = Args.getAllArgValues(OPT_fmodule_map_file);
// Only the -fmodule-file=<file> form.
- for (const Arg *A : Args.filtered(OPT_fmodule_file)) {
+ for (const auto *A : Args.filtered(OPT_fmodule_file)) {
StringRef Val = A->getValue();
if (Val.find('=') == StringRef::npos)
Opts.ModuleFiles.push_back(Val);
@@ -1416,12 +1545,13 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
= !Args.hasArg(OPT_no_code_completion_ns_level_decls);
Opts.CodeCompleteOpts.IncludeBriefComments
= Args.hasArg(OPT_code_completion_brief_comments);
+ Opts.CodeCompleteOpts.IncludeFixIts
+ = Args.hasArg(OPT_code_completion_with_fixits);
Opts.OverrideRecordLayoutsFile
= Args.getLastArgValue(OPT_foverride_record_layout_EQ);
Opts.AuxTriple =
llvm::Triple::normalize(Args.getLastArgValue(OPT_aux_triple));
- Opts.FindPchSource = Args.getLastArgValue(OPT_find_pch_source_EQ);
Opts.StatsFile = Args.getLastArgValue(OPT_stats_file);
if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
@@ -1502,6 +1632,7 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
.Case("c", InputKind::C)
.Case("cl", InputKind::OpenCL)
.Case("cuda", InputKind::CUDA)
+ .Case("hip", InputKind::HIP)
.Case("c++", InputKind::CXX)
.Case("objective-c", InputKind::ObjC)
.Case("objective-c++", InputKind::ObjCXX)
@@ -1585,7 +1716,6 @@ std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
const std::string &WorkingDir) {
- using namespace options;
Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
Opts.Verbose = Args.hasArg(OPT_v);
Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc);
@@ -1608,12 +1738,12 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
// Only the -fmodule-file=<name>=<file> form.
- for (const Arg *A : Args.filtered(OPT_fmodule_file)) {
+ for (const auto *A : Args.filtered(OPT_fmodule_file)) {
StringRef Val = A->getValue();
if (Val.find('=') != StringRef::npos)
Opts.PrebuiltModuleFiles.insert(Val.split('='));
}
- for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path))
+ for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
Opts.AddPrebuiltModulePath(A->getValue());
Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
@@ -1634,7 +1764,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ))
Opts.ModuleFormat = A->getValue();
- for (const Arg *A : Args.filtered(OPT_fmodules_ignore_macro)) {
+ for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
StringRef MacroDef = A->getValue();
Opts.ModulesIgnoreMacros.insert(
llvm::CachedHashString(MacroDef.split('=').first));
@@ -1644,7 +1774,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
bool IsIndexHeaderMap = false;
bool IsSysrootSpecified =
Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
- for (const Arg *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) {
+ for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) {
if (A->getOption().matches(OPT_index_header_map)) {
// -index-header-map applies to the next -I or -F.
IsIndexHeaderMap = true;
@@ -1671,7 +1801,7 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
// Add -iprefix/-iwithprefix/-iwithprefixbefore options.
StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
- for (const Arg *A :
+ for (const auto *A :
Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
if (A->getOption().matches(OPT_iprefix))
Prefix = A->getValue();
@@ -1681,31 +1811,31 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
}
- for (const Arg *A : Args.filtered(OPT_idirafter))
+ for (const auto *A : Args.filtered(OPT_idirafter))
Opts.AddPath(A->getValue(), frontend::After, false, true);
- for (const Arg *A : Args.filtered(OPT_iquote))
+ for (const auto *A : Args.filtered(OPT_iquote))
Opts.AddPath(A->getValue(), frontend::Quoted, false, true);
- for (const Arg *A : Args.filtered(OPT_isystem, OPT_iwithsysroot))
+ for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot))
Opts.AddPath(A->getValue(), frontend::System, false,
!A->getOption().matches(OPT_iwithsysroot));
- for (const Arg *A : Args.filtered(OPT_iframework))
+ for (const auto *A : Args.filtered(OPT_iframework))
Opts.AddPath(A->getValue(), frontend::System, true, true);
- for (const Arg *A : Args.filtered(OPT_iframeworkwithsysroot))
+ for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
/*IgnoreSysRoot=*/false);
// Add the paths for the various language specific isystem flags.
- for (const Arg *A : Args.filtered(OPT_c_isystem))
+ for (const auto *A : Args.filtered(OPT_c_isystem))
Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
- for (const Arg *A : Args.filtered(OPT_cxx_isystem))
+ for (const auto *A : Args.filtered(OPT_cxx_isystem))
Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
- for (const Arg *A : Args.filtered(OPT_objc_isystem))
+ for (const auto *A : Args.filtered(OPT_objc_isystem))
Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
- for (const Arg *A : Args.filtered(OPT_objcxx_isystem))
+ for (const auto *A : Args.filtered(OPT_objcxx_isystem))
Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
// Add the internal paths from a driver that detects standard include paths.
- for (const Arg *A :
+ for (const auto *A :
Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
frontend::IncludeDirGroup Group = frontend::System;
if (A->getOption().matches(OPT_internal_externc_isystem))
@@ -1714,12 +1844,12 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
}
// Add the path prefixes which are implicitly treated as being system headers.
- for (const Arg *A :
+ for (const auto *A :
Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
Opts.AddSystemHeaderPrefix(
A->getValue(), A->getOption().matches(OPT_system_header_prefix));
- for (const Arg *A : Args.filtered(OPT_ivfsoverlay))
+ for (const auto *A : Args.filtered(OPT_ivfsoverlay))
Opts.AddVFSOverlayFile(A->getValue());
}
@@ -1754,22 +1884,37 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
break;
case InputKind::Asm:
case InputKind::C:
+#if defined(CLANG_DEFAULT_STD_C)
+ LangStd = CLANG_DEFAULT_STD_C;
+#else
// The PS4 uses C99 as the default C standard.
if (T.isPS4())
LangStd = LangStandard::lang_gnu99;
else
LangStd = LangStandard::lang_gnu11;
+#endif
break;
case InputKind::ObjC:
+#if defined(CLANG_DEFAULT_STD_C)
+ LangStd = CLANG_DEFAULT_STD_C;
+#else
LangStd = LangStandard::lang_gnu11;
+#endif
break;
case InputKind::CXX:
case InputKind::ObjCXX:
+#if defined(CLANG_DEFAULT_STD_CXX)
+ LangStd = CLANG_DEFAULT_STD_CXX;
+#else
LangStd = LangStandard::lang_gnucxx14;
+#endif
break;
case InputKind::RenderScript:
LangStd = LangStandard::lang_c99;
break;
+ case InputKind::HIP:
+ LangStd = LangStandard::lang_hip;
+ break;
}
}
@@ -1799,6 +1944,8 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.OpenCLVersion = 120;
else if (LangStd == LangStandard::lang_opencl20)
Opts.OpenCLVersion = 200;
+ else if (LangStd == LangStandard::lang_openclcpp)
+ Opts.OpenCLCPlusPlusVersion = 100;
// OpenCL has some additional defaults.
if (Opts.OpenCL) {
@@ -1808,13 +1955,15 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.setDefaultFPContractMode(LangOptions::FPC_On);
Opts.NativeHalfType = 1;
Opts.NativeHalfArgsAndReturns = 1;
+ Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
// Include default header file for OpenCL.
if (Opts.IncludeDefaultHeader) {
PPOpts.Includes.push_back("opencl-c.h");
}
}
- Opts.CUDA = IK.getLanguage() == InputKind::CUDA;
+ Opts.HIP = IK.getLanguage() == InputKind::HIP;
+ Opts.CUDA = IK.getLanguage() == InputKind::CUDA || Opts.HIP;
if (Opts.CUDA)
// Set default FP_CONTRACT to FAST.
Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
@@ -1885,6 +2034,10 @@ static bool IsInputCompatibleWithStandard(InputKind IK,
return S.getLanguage() == InputKind::CUDA ||
S.getLanguage() == InputKind::CXX;
+ case InputKind::HIP:
+ return S.getLanguage() == InputKind::CXX ||
+ S.getLanguage() == InputKind::HIP;
+
case InputKind::Asm:
// Accept (and ignore) all -std= values.
// FIXME: The -std= value is not ignored; it affects the tokenization
@@ -1912,6 +2065,8 @@ static const StringRef GetInputKindName(InputKind IK) {
return "CUDA";
case InputKind::RenderScript:
return "RenderScript";
+ case InputKind::HIP:
+ return "HIP";
case InputKind::Asm:
return "Asm";
@@ -1975,6 +2130,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
}
}
+ if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
+ StringRef Name = A->getValue();
+ if (Name == "full" || Name == "branch") {
+ Opts.CFProtectionBranch = 1;
+ }
+ }
// -cl-std only applies for OpenCL language standards.
// Override the -std option in this case.
if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
@@ -1984,6 +2145,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
.Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
.Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
.Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
+ .Case("c++", LangStandard::lang_openclcpp)
.Default(LangStandard::lang_unspecified);
if (OpenCLLangStd == LangStandard::lang_unspecified) {
@@ -2004,11 +2166,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// this option was added for compatibility with OpenCL 1.0.
if (Args.getLastArg(OPT_cl_strict_aliasing)
&& Opts.OpenCLVersion > 100) {
- std::string VerSpec = llvm::to_string(Opts.OpenCLVersion / 100) +
- std::string(".") +
- llvm::to_string((Opts.OpenCLVersion % 100) / 10);
Diags.Report(diag::warn_option_invalid_ocl_version)
- << VerSpec << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
+ << Opts.getOpenCLVersionTuple().getAsString()
+ << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
}
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
@@ -2019,6 +2179,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
Opts.GNUKeywords);
+ Opts.Digraphs = Args.hasFlag(OPT_fdigraphs, OPT_fno_digraphs, Opts.Digraphs);
+
if (Args.hasArg(OPT_fno_operator_names))
Opts.CXXOperatorNames = 0;
@@ -2031,12 +2193,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (Args.hasArg(OPT_fno_cuda_host_device_constexpr))
Opts.CUDAHostDeviceConstexpr = 0;
- if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_flush_denormals_to_zero))
- Opts.CUDADeviceFlushDenormalsToZero = 1;
-
if (Opts.CUDAIsDevice && Args.hasArg(OPT_fcuda_approx_transcendentals))
Opts.CUDADeviceApproxTranscendentals = 1;
+ Opts.CUDARelocatableDeviceCode = Args.hasArg(OPT_fcuda_rdc);
+
if (Opts.ObjC1) {
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
StringRef value = arg->getValue();
@@ -2177,12 +2338,27 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
+ // -ffixed-point
+ Opts.FixedPoint =
+ Args.hasFlag(OPT_ffixed_point, OPT_fno_fixed_point, /*Default=*/false) &&
+ !Opts.CPlusPlus;
+ Opts.PaddingOnUnsignedFixedPoint =
+ Args.hasFlag(OPT_fpadding_on_unsigned_fixed_point,
+ OPT_fno_padding_on_unsigned_fixed_point,
+ /*Default=*/false) &&
+ Opts.FixedPoint;
+
// Handle exception personalities
Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
options::OPT_fseh_exceptions,
options::OPT_fdwarf_exceptions);
if (A) {
const Option &Opt = A->getOption();
+ llvm::Triple T(TargetOpts.Triple);
+ if (T.isWindowsMSVCEnvironment())
+ Diags.Report(diag::err_fe_invalid_exception_model)
+ << Opt.getName() << T.str();
+
Opts.SjLjExceptions = Opt.matches(options::OPT_fsjlj_exceptions);
Opts.SEHExceptions = Opt.matches(options::OPT_fseh_exceptions);
Opts.DWARFExceptions = Opt.matches(options::OPT_fdwarf_exceptions);
@@ -2194,7 +2370,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti);
Opts.RTTIData = Opts.RTTI && !Args.hasArg(OPT_fno_rtti_data);
Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
- && Opts.OpenCLVersion >= 200);
+ && Opts.OpenCLVersion == 200);
Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional);
Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts);
@@ -2219,6 +2395,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules);
Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
+ Opts.Char8 = Args.hasArg(OPT_fchar8__t);
if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) {
Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue())
.Case("char", 1)
@@ -2297,10 +2474,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
- Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name_EQ);
+ Opts.ModuleName = Args.getLastArgValue(OPT_fmodule_name_EQ);
+ Opts.CurrentModule = Opts.ModuleName;
Opts.AppExt = Args.hasArg(OPT_fapplication_extension);
Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
- std::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end());
+ llvm::sort(Opts.ModuleFeatures.begin(), Opts.ModuleFeatures.end());
Opts.NativeHalfType |= Args.hasArg(OPT_fnative_half_type);
Opts.NativeHalfArgsAndReturns |= Args.hasArg(OPT_fnative_half_arguments_and_returns);
// Enable HalfArgsAndReturns if present in Args or if NativeHalfArgsAndReturns
@@ -2407,16 +2585,25 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// Check if -fopenmp is specified.
Opts.OpenMP = Args.hasArg(options::OPT_fopenmp) ? 1 : 0;
+ // Check if -fopenmp-simd is specified.
+ bool IsSimdSpecified =
+ Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
+ /*Default=*/false);
+ Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
Opts.OpenMPUseTLS =
Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
Opts.OpenMPIsDevice =
Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_device);
+ bool IsTargetSpecified =
+ Opts.OpenMPIsDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ);
- if (Opts.OpenMP) {
- int Version =
- getLastArgIntValue(Args, OPT_fopenmp_version_EQ, Opts.OpenMP, Diags);
- if (Version != 0)
+ if (Opts.OpenMP || Opts.OpenMPSimd) {
+ if (int Version = getLastArgIntValue(
+ Args, OPT_fopenmp_version_EQ,
+ (IsSimdSpecified || IsTargetSpecified) ? 45 : Opts.OpenMP, Diags))
Opts.OpenMP = Version;
+ else if (IsSimdSpecified || IsTargetSpecified)
+ Opts.OpenMP = 45;
// Provide diagnostic when a given target is not expected to be an OpenMP
// device or host.
if (!Opts.OpenMPIsDevice) {
@@ -2426,7 +2613,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// Add unsupported host targets here:
case llvm::Triple::nvptx:
case llvm::Triple::nvptx64:
- Diags.Report(clang::diag::err_drv_omp_host_target_not_supported)
+ Diags.Report(diag::err_drv_omp_host_target_not_supported)
<< TargetOpts.Triple;
break;
}
@@ -2435,7 +2622,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// Set the flag to prevent the implementation from emitting device exception
// handling code for those requiring so.
- if (Opts.OpenMPIsDevice && T.isNVPTX()) {
+ Opts.OpenMPHostCXXExceptions = Opts.Exceptions && Opts.CXXExceptions;
+ if ((Opts.OpenMPIsDevice && T.isNVPTX()) || Opts.OpenCLCPlusPlus) {
Opts.Exceptions = 0;
Opts.CXXExceptions = 0;
}
@@ -2454,7 +2642,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
TT.getArch() == llvm::Triple::nvptx64 ||
TT.getArch() == llvm::Triple::x86 ||
TT.getArch() == llvm::Triple::x86_64))
- Diags.Report(clang::diag::err_drv_invalid_omp_target) << A->getValue(i);
+ Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
else
Opts.OMPTargetTriples.push_back(TT);
}
@@ -2465,10 +2653,14 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {
Opts.OMPHostIRFile = A->getValue();
if (!llvm::sys::fs::exists(Opts.OMPHostIRFile))
- Diags.Report(clang::diag::err_drv_omp_host_ir_file_not_found)
+ Diags.Report(diag::err_drv_omp_host_ir_file_not_found)
<< Opts.OMPHostIRFile;
}
+ // set CUDA mode for OpenMP target NVPTX if specified in options
+ Opts.OpenMPCUDAMode = Opts.OpenMPIsDevice && T.isNVPTX() &&
+ Args.hasArg(options::OPT_fopenmp_cuda_mode);
+
// Record whether the __DEPRECATED define was requested.
Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro,
OPT_fno_deprecated_macro,
@@ -2543,14 +2735,55 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Args.hasFlag(OPT_fxray_always_emit_customevents,
OPT_fnoxray_always_emit_customevents, false);
+ // -fxray-always-emit-typedevents
+ Opts.XRayAlwaysEmitTypedEvents =
+ Args.hasFlag(OPT_fxray_always_emit_typedevents,
+ OPT_fnoxray_always_emit_customevents, false);
+
// -fxray-{always,never}-instrument= filenames.
Opts.XRayAlwaysInstrumentFiles =
Args.getAllArgValues(OPT_fxray_always_instrument);
Opts.XRayNeverInstrumentFiles =
Args.getAllArgValues(OPT_fxray_never_instrument);
+ Opts.XRayAttrListFiles = Args.getAllArgValues(OPT_fxray_attr_list);
+
+ // -fforce-emit-vtables
+ Opts.ForceEmitVTables = Args.hasArg(OPT_fforce_emit_vtables);
// -fallow-editor-placeholders
Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders);
+
+ if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
+ Opts.setClangABICompat(LangOptions::ClangABI::Latest);
+
+ StringRef Ver = A->getValue();
+ std::pair<StringRef, StringRef> VerParts = Ver.split('.');
+ unsigned Major, Minor = 0;
+
+ // Check the version number is valid: either 3.x (0 <= x <= 9) or
+ // y or y.0 (4 <= y <= current version).
+ if (!VerParts.first.startswith("0") &&
+ !VerParts.first.getAsInteger(10, Major) &&
+ 3 <= Major && Major <= CLANG_VERSION_MAJOR &&
+ (Major == 3 ? VerParts.second.size() == 1 &&
+ !VerParts.second.getAsInteger(10, Minor)
+ : VerParts.first.size() == Ver.size() ||
+ VerParts.second == "0")) {
+ // Got a valid version number.
+ if (Major == 3 && Minor <= 8)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
+ else if (Major <= 4)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver4);
+ else if (Major <= 6)
+ Opts.setClangABICompat(LangOptions::ClangABI::Ver6);
+ } else if (Ver != "latest") {
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ }
+
+ Opts.CompleteMemberPointers = Args.hasArg(OPT_fcomplete_member_pointers);
+ Opts.BuildingPCHWithObjectFile = Args.hasArg(OPT_building_pch_with_obj);
}
static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
@@ -2579,9 +2812,11 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
case frontend::RewriteObjC:
case frontend::RewriteTest:
case frontend::RunAnalysis:
+ case frontend::TemplightDump:
case frontend::MigrateSource:
return false;
+ case frontend::DumpCompilerOptions:
case frontend::DumpRawTokens:
case frontend::DumpTokens:
case frontend::InitOnly:
@@ -2595,12 +2830,11 @@ static bool isStrictlyPreprocessorAction(frontend::ActionKind Action) {
}
static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
- FileManager &FileMgr,
DiagnosticsEngine &Diags,
frontend::ActionKind Action) {
- using namespace options;
Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch);
Opts.ImplicitPTHInclude = Args.getLastArgValue(OPT_include_pth);
+ Opts.PCHThroughHeader = Args.getLastArgValue(OPT_pch_through_header_EQ);
if (const Arg *A = Args.getLastArg(OPT_token_cache))
Opts.TokenCache = A->getValue();
else
@@ -2611,7 +2845,7 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.AllowPCHWithCompilerErrors = Args.hasArg(OPT_fallow_pch_with_errors);
Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
- for (const Arg *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
+ for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
@@ -2630,8 +2864,19 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
}
}
+ // Add the __CET__ macro if a CFProtection option is set.
+ if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
+ StringRef Name = A->getValue();
+ if (Name == "branch")
+ Opts.addMacroDef("__CET__=1");
+ else if (Name == "return")
+ Opts.addMacroDef("__CET__=2");
+ else if (Name == "full")
+ Opts.addMacroDef("__CET__=3");
+ }
+
// Add macros from the command line.
- for (const Arg *A : Args.filtered(OPT_D, OPT_U)) {
+ for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
if (A->getOption().matches(OPT_D))
Opts.addMacroDef(A->getValue());
else
@@ -2641,13 +2886,13 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.MacroIncludes = Args.getAllArgValues(OPT_imacros);
// Add the ordered list of -includes.
- for (const Arg *A : Args.filtered(OPT_include))
+ for (const auto *A : Args.filtered(OPT_include))
Opts.Includes.emplace_back(A->getValue());
- for (const Arg *A : Args.filtered(OPT_chain_include))
+ for (const auto *A : Args.filtered(OPT_chain_include))
Opts.ChainedIncludes.emplace_back(A->getValue());
- for (const Arg *A : Args.filtered(OPT_remap_file)) {
+ for (const auto *A : Args.filtered(OPT_remap_file)) {
std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
if (Split.second.empty()) {
@@ -2681,8 +2926,6 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
ArgList &Args,
frontend::ActionKind Action) {
- using namespace options;
-
if (isStrictlyPreprocessorAction(Action))
Opts.ShowCPP = !Args.hasArg(OPT_dM);
else
@@ -2700,7 +2943,6 @@ static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
DiagnosticsEngine &Diags) {
- using namespace options;
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
if (Arg *A = Args.getLastArg(OPT_meabi)) {
StringRef Value = A->getValue();
@@ -2720,11 +2962,15 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
Opts.FPMath = Args.getLastArgValue(OPT_mfpmath);
Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature);
Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
- Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
+ Opts.Triple = Args.getLastArgValue(OPT_triple);
// Use the default target triple if unspecified.
if (Opts.Triple.empty())
Opts.Triple = llvm::sys::getDefaultTargetTriple();
+ Opts.Triple = llvm::Triple::normalize(Opts.Triple);
Opts.OpenCLExtensionsAsWritten = Args.getAllArgValues(OPT_cl_ext_EQ);
+ Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128);
+ Opts.NVPTXUseShortPointers = Args.hasFlag(
+ options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false);
}
bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
@@ -2750,8 +2996,14 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
}
// Issue errors on unknown arguments.
- for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
- Diags.Report(diag::err_drv_unknown_argument) << A->getAsString(Args);
+ for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
+ auto ArgString = A->getAsString(Args);
+ std::string Nearest;
+ if (Opts->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
+ Diags.Report(diag::err_drv_unknown_argument) << ArgString;
+ else
+ Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
+ << ArgString << Nearest;
Success = false;
}
@@ -2768,7 +3020,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
LangOpts.IsHeaderFile);
ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
- Res.getTargetOpts());
+ Res.getTargetOpts(), Res.getFrontendOpts());
ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
Res.getFileSystemOpts().WorkingDir);
if (DashX.getFormat() == InputKind::Precompiled ||
@@ -2793,6 +3045,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
LangOpts.ObjCExceptions = 1;
}
+ LangOpts.FunctionAlignment =
+ getLastArgIntValue(Args, OPT_function_alignment, 0, Diags);
+
if (LangOpts.CUDA) {
// During CUDA device-side compilation, the aux triple is the
// triple used for host compilation.
@@ -2811,12 +3066,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
!LangOpts.Sanitize.has(SanitizerKind::Address) &&
!LangOpts.Sanitize.has(SanitizerKind::Memory);
- // 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
- // parameters from the function and the "FileManager.h" #include.
- FileManager FileMgr(Res.getFileSystemOpts());
- ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, FileMgr, Diags,
+ ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
Res.getFrontendOpts().ProgramAction);
ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), Args,
Res.getFrontendOpts().ProgramAction);
@@ -2864,29 +3114,26 @@ std::string CompilerInvocation::getModuleHash() const {
// Extend the signature with the target options.
code = hash_combine(code, TargetOpts->Triple, TargetOpts->CPU,
TargetOpts->ABI);
- for (unsigned i = 0, n = TargetOpts->FeaturesAsWritten.size(); i != n; ++i)
- code = hash_combine(code, TargetOpts->FeaturesAsWritten[i]);
+ for (const auto &FeatureAsWritten : TargetOpts->FeaturesAsWritten)
+ code = hash_combine(code, FeatureAsWritten);
// Extend the signature with preprocessor options.
const PreprocessorOptions &ppOpts = getPreprocessorOpts();
const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
code = hash_combine(code, ppOpts.UsePredefines, ppOpts.DetailedRecord);
- for (std::vector<std::pair<std::string, bool/*isUndef*/>>::const_iterator
- I = getPreprocessorOpts().Macros.begin(),
- IEnd = getPreprocessorOpts().Macros.end();
- I != IEnd; ++I) {
+ for (const auto &I : getPreprocessorOpts().Macros) {
// If we're supposed to ignore this macro for the purposes of modules,
// don't put it into the hash.
if (!hsOpts.ModulesIgnoreMacros.empty()) {
// Check whether we're ignoring this macro.
- StringRef MacroDef = I->first;
+ StringRef MacroDef = I.first;
if (hsOpts.ModulesIgnoreMacros.count(
llvm::CachedHashString(MacroDef.split('=').first)))
continue;
}
- code = hash_combine(code, I->first, I->second);
+ code = hash_combine(code, I.first, I.second);
}
// Extend the signature with the sysroot and other header search options.
@@ -2919,8 +3166,6 @@ std::string CompilerInvocation::getModuleHash() const {
return llvm::APInt(64, code).toString(36, /*Signed=*/false);
}
-namespace clang {
-
template<typename IntTy>
static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
IntTy Default,
@@ -2936,6 +3181,7 @@ static IntTy getLastArgIntValueImpl(const ArgList &Args, OptSpecifier Id,
return Res;
}
+namespace clang {
// Declared in clang/Frontend/Utils.h.
int getLastArgIntValue(const ArgList &Args, OptSpecifier Id, int Default,
@@ -2980,22 +3226,22 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI,
IntrusiveRefCntPtr<vfs::OverlayFileSystem> Overlay(
new vfs::OverlayFileSystem(BaseFS));
// earlier vfs files are on the bottom
- for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
+ for (const auto &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
BaseFS->getBufferForFile(File);
if (!Buffer) {
Diags.Report(diag::err_missing_vfs_overlay_file) << File;
- return IntrusiveRefCntPtr<vfs::FileSystem>();
+ continue;
}
IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML(
std::move(Buffer.get()), /*DiagHandler*/ nullptr, File);
- if (!FS.get()) {
+ if (FS)
+ Overlay->pushOverlay(FS);
+ else
Diags.Report(diag::err_invalid_vfs_overlay) << File;
- return IntrusiveRefCntPtr<vfs::FileSystem>();
- }
- Overlay->pushOverlay(FS);
}
return Overlay;
}
-} // end namespace clang
+
+} // namespace clang
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 561eb9c4a316..f89722eeb9ed 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -63,7 +63,8 @@ struct DepCollectorPPCallbacks : public PPCallbacks {
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override {
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override {
if (!File)
DepCollector.maybeAddDependency(FileName, /*FromModule*/false,
/*IsSystem*/false, /*IsModuleFile*/false,
@@ -162,6 +163,7 @@ class DFGImpl : public PPCallbacks {
bool SeenMissingHeader;
bool IncludeModuleFiles;
DependencyOutputFormat OutputFormat;
+ unsigned InputFileIndex;
private:
bool FileMatchesDepCriteria(const char *Filename,
@@ -176,26 +178,33 @@ public:
AddMissingHeaderDeps(Opts.AddMissingHeaderDeps),
SeenMissingHeader(false),
IncludeModuleFiles(Opts.IncludeModuleFiles),
- OutputFormat(Opts.OutputFormat) {
+ OutputFormat(Opts.OutputFormat),
+ InputFileIndex(0) {
for (const auto &ExtraDep : Opts.ExtraDeps) {
- AddFilename(ExtraDep);
+ if (AddFilename(ExtraDep))
+ ++InputFileIndex;
}
}
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
FileID PrevFID) override;
+
+ void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) override;
+
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override;
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override;
void EndOfMainFile() override {
OutputDependencyFile();
}
- void AddFilename(StringRef Filename);
+ bool AddFilename(StringRef Filename);
bool includeSystemHeaders() const { return IncludeSystemHeaders; }
bool includeModuleFiles() const { return IncludeModuleFiles; }
};
@@ -291,6 +300,16 @@ void DFGImpl::FileChanged(SourceLocation Loc,
AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
}
+void DFGImpl::FileSkipped(const FileEntry &SkippedFile,
+ const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) {
+ StringRef Filename = SkippedFile.getName();
+ if (!FileMatchesDepCriteria(Filename.data(), FileType))
+ return;
+
+ AddFilename(llvm::sys::path::remove_leading_dotslash(Filename));
+}
+
void DFGImpl::InclusionDirective(SourceLocation HashLoc,
const Token &IncludeTok,
StringRef FileName,
@@ -299,7 +318,8 @@ void DFGImpl::InclusionDirective(SourceLocation HashLoc,
const FileEntry *File,
StringRef SearchPath,
StringRef RelativePath,
- const Module *Imported) {
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) {
if (!File) {
if (AddMissingHeaderDeps)
AddFilename(FileName);
@@ -308,9 +328,12 @@ void DFGImpl::InclusionDirective(SourceLocation HashLoc,
}
}
-void DFGImpl::AddFilename(StringRef Filename) {
- if (FilesSet.insert(Filename).second)
+bool DFGImpl::AddFilename(StringRef Filename) {
+ if (FilesSet.insert(Filename).second) {
Files.push_back(Filename);
+ return true;
+ }
+ return false;
}
/// Print the filename, with escaping or quoting that accommodates the three
@@ -446,8 +469,10 @@ void DFGImpl::OutputDependencyFile() {
// Create phony targets if requested.
if (PhonyTarget && !Files.empty()) {
- // Skip the first entry, this is always the input file itself.
- for (auto I = Files.begin() + 1, E = Files.end(); I != E; ++I) {
+ unsigned Index = 0;
+ for (auto I = Files.begin(), E = Files.end(); I != E; ++I) {
+ if (Index++ == InputFileIndex)
+ continue;
OS << '\n';
PrintFilename(OS, *I, OutputFormat);
OS << ":\n";
diff --git a/lib/Frontend/DependencyGraph.cpp b/lib/Frontend/DependencyGraph.cpp
index 67a977e38be2..660f664447ab 100644
--- a/lib/Frontend/DependencyGraph.cpp
+++ b/lib/Frontend/DependencyGraph.cpp
@@ -50,7 +50,8 @@ public:
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override;
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override;
void EndOfMainFile() override {
OutputGraphFile();
@@ -65,15 +66,17 @@ void clang::AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
SysRoot));
}
-void DependencyGraphCallback::InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) {
+void DependencyGraphCallback::InclusionDirective(
+ SourceLocation HashLoc,
+ const Token &IncludeTok,
+ StringRef FileName,
+ bool IsAngled,
+ CharSourceRange FilenameRange,
+ const FileEntry *File,
+ StringRef SearchPath,
+ StringRef RelativePath,
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) {
if (!File)
return;
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index e3263843e29b..fb0a92d1f8c6 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -1,4 +1,4 @@
-//===--- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing --------------===//
+//===- DiagnosticRenderer.cpp - Diagnostic Pretty-Printing ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,24 +8,34 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/DiagnosticRenderer.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Edit/Commit.h"
#include "clang/Edit/EditedSource.h"
#include "clang/Edit/EditsReceiver.h"
#include "clang/Lex/Lexer.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <utility>
+
using namespace clang;
DiagnosticRenderer::DiagnosticRenderer(const LangOptions &LangOpts,
DiagnosticOptions *DiagOpts)
- : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
+ : LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {}
-DiagnosticRenderer::~DiagnosticRenderer() {}
+DiagnosticRenderer::~DiagnosticRenderer() = default;
namespace {
@@ -34,24 +44,24 @@ class FixitReceiver : public edit::EditsReceiver {
public:
FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits)
- : MergedFixits(MergedFixits) { }
+ : MergedFixits(MergedFixits) {}
+
void insert(SourceLocation loc, StringRef text) override {
MergedFixits.push_back(FixItHint::CreateInsertion(loc, text));
}
+
void replace(CharSourceRange range, StringRef text) override {
MergedFixits.push_back(FixItHint::CreateReplacement(range, text));
}
};
-}
+} // namespace
static void mergeFixits(ArrayRef<FixItHint> FixItHints,
const SourceManager &SM, const LangOptions &LangOpts,
SmallVectorImpl<FixItHint> &MergedFixits) {
edit::Commit commit(SM, LangOpts);
- for (ArrayRef<FixItHint>::const_iterator
- I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) {
- const FixItHint &Hint = *I;
+ for (const auto &Hint : FixItHints)
if (Hint.CodeToInsert.empty()) {
if (Hint.InsertFromRange.isValid())
commit.insertFromRange(Hint.RemoveRange.getBegin(),
@@ -67,7 +77,6 @@ static void mergeFixits(ArrayRef<FixItHint> FixItHints,
commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
/*afterToken=*/false, Hint.BeforePreviousInsertions);
}
- }
edit::EditedSource Editor(SM, LangOpts);
if (Editor.commit(commit)) {
@@ -100,11 +109,9 @@ void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc,
FixItHints = MergedFixits;
}
- for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(),
- E = FixItHints.end();
- I != E; ++I)
- if (I->RemoveRange.isValid())
- MutableRanges.push_back(I->RemoveRange);
+ for (const auto &Hint : FixItHints)
+ if (Hint.RemoveRange.isValid())
+ MutableRanges.push_back(Hint.RemoveRange);
FullSourceLoc UnexpandedLoc = Loc;
@@ -134,7 +141,6 @@ void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc,
endDiagnostic(D, Level);
}
-
void DiagnosticRenderer::emitStoredDiagnostic(StoredDiagnostic &Diag) {
emitDiagnostic(Diag.getLocation(), Diag.getLevel(), Diag.getMessage(),
Diag.getRanges(), Diag.getFixIts(),
@@ -146,7 +152,7 @@ void DiagnosticRenderer::emitBasicNote(StringRef Message) {
Message, None, DiagOrStoredDiag());
}
-/// \brief Prints an include stack when appropriate for a particular
+/// Prints an include stack when appropriate for a particular
/// diagnostic level and location.
///
/// This routine handles all the logic of suppressing particular include
@@ -180,7 +186,7 @@ void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
}
}
-/// \brief Helper to recursivly walk up the include stack and print each layer
+/// Helper to recursively walk up the include stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) {
if (Loc.isInvalid()) {
@@ -210,7 +216,7 @@ void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) {
emitIncludeLocation(Loc, PLoc);
}
-/// \brief Emit the module import stack associated with the current location.
+/// Emit the module import stack associated with the current location.
void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) {
if (Loc.isInvalid()) {
emitModuleBuildStack(Loc.getManager());
@@ -221,7 +227,7 @@ void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) {
emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second);
}
-/// \brief Helper to recursivly walk up the import stack and print each layer
+/// Helper to recursively walk up the import stack and print each layer
/// on the way back down.
void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
StringRef ModuleName) {
@@ -239,14 +245,14 @@ void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
emitImportLocation(Loc, PLoc, ModuleName);
}
-/// \brief Emit the module build stack, for cases where a module is (re-)built
+/// Emit the module build stack, for cases where a module is (re-)built
/// on demand.
void DiagnosticRenderer::emitModuleBuildStack(const SourceManager &SM) {
ModuleBuildStack Stack = SM.getModuleBuildStack();
- for (unsigned I = 0, N = Stack.size(); I != N; ++I) {
- emitBuildingModuleLocation(Stack[I].second, Stack[I].second.getPresumedLoc(
- DiagOpts->ShowPresumedLoc),
- Stack[I].first);
+ for (const auto &I : Stack) {
+ emitBuildingModuleLocation(I.second, I.second.getPresumedLoc(
+ DiagOpts->ShowPresumedLoc),
+ I.first);
}
}
@@ -256,41 +262,54 @@ static SourceLocation
retrieveMacroLocation(SourceLocation Loc, FileID MacroFileID,
FileID CaretFileID,
const SmallVectorImpl<FileID> &CommonArgExpansions,
- bool IsBegin, const SourceManager *SM) {
+ bool IsBegin, const SourceManager *SM,
+ bool &IsTokenRange) {
assert(SM->getFileID(Loc) == MacroFileID);
if (MacroFileID == CaretFileID)
return Loc;
if (!Loc.isMacroID())
- return SourceLocation();
+ return {};
- SourceLocation MacroLocation, MacroArgLocation;
+ CharSourceRange MacroRange, MacroArgRange;
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;
+ MacroRange =
+ CharSourceRange(SM->getImmediateSpellingLoc(Loc), IsTokenRange);
+ MacroArgRange = SM->getImmediateExpansionRange(Loc);
} else {
- MacroLocation = IsBegin ? SM->getImmediateExpansionRange(Loc).first
- : SM->getImmediateExpansionRange(Loc).second;
- MacroArgLocation = SM->getImmediateSpellingLoc(Loc);
+ MacroRange = SM->getImmediateExpansionRange(Loc);
+ MacroArgRange =
+ CharSourceRange(SM->getImmediateSpellingLoc(Loc), IsTokenRange);
}
+ SourceLocation MacroLocation =
+ IsBegin ? MacroRange.getBegin() : MacroRange.getEnd();
if (MacroLocation.isValid()) {
MacroFileID = SM->getFileID(MacroLocation);
+ bool TokenRange = IsBegin ? IsTokenRange : MacroRange.isTokenRange();
MacroLocation =
retrieveMacroLocation(MacroLocation, MacroFileID, CaretFileID,
- CommonArgExpansions, IsBegin, SM);
- if (MacroLocation.isValid())
+ CommonArgExpansions, IsBegin, SM, TokenRange);
+ if (MacroLocation.isValid()) {
+ IsTokenRange = TokenRange;
return MacroLocation;
+ }
}
+ // If we moved the end of the range to an expansion location, we now have
+ // a range of the same kind as the expansion range.
+ if (!IsBegin)
+ IsTokenRange = MacroArgRange.isTokenRange();
+
+ SourceLocation MacroArgLocation =
+ IsBegin ? MacroArgRange.getBegin() : MacroArgRange.getEnd();
MacroFileID = SM->getFileID(MacroArgLocation);
return retrieveMacroLocation(MacroArgLocation, MacroFileID, CaretFileID,
- CommonArgExpansions, IsBegin, SM);
+ CommonArgExpansions, IsBegin, SM, IsTokenRange);
}
/// Walk up the chain of macro expansions and collect the FileIDs identifying the
@@ -304,7 +323,7 @@ static void getMacroArgExpansionFileIDs(SourceLocation Loc,
Loc = SM->getImmediateSpellingLoc(Loc);
} else {
auto ExpRange = SM->getImmediateExpansionRange(Loc);
- Loc = IsBegin ? ExpRange.first : ExpRange.second;
+ Loc = IsBegin ? ExpRange.getBegin() : ExpRange.getEnd();
}
}
}
@@ -318,8 +337,8 @@ static void computeCommonMacroArgExpansionFileIDs(
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());
+ llvm::sort(BeginArgExpansions.begin(), BeginArgExpansions.end());
+ llvm::sort(EndArgExpansions.begin(), EndArgExpansions.end());
std::set_intersection(BeginArgExpansions.begin(), BeginArgExpansions.end(),
EndArgExpansions.begin(), EndArgExpansions.end(),
std::back_inserter(CommonArgExpansions));
@@ -342,11 +361,12 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
const SourceManager *SM = &CaretLoc.getManager();
- for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
- if (I->isInvalid()) continue;
+ for (const auto &Range : Ranges) {
+ if (Range.isInvalid())
+ continue;
- SourceLocation Begin = I->getBegin(), End = I->getEnd();
- bool IsTokenRange = I->isTokenRange();
+ SourceLocation Begin = Range.getBegin(), End = Range.getEnd();
+ bool IsTokenRange = Range.isTokenRange();
FileID BeginFileID = SM->getFileID(Begin);
FileID EndFileID = SM->getFileID(End);
@@ -357,14 +377,16 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
llvm::SmallDenseMap<FileID, SourceLocation> BeginLocsMap;
while (Begin.isMacroID() && BeginFileID != EndFileID) {
BeginLocsMap[BeginFileID] = Begin;
- Begin = SM->getImmediateExpansionRange(Begin).first;
+ Begin = SM->getImmediateExpansionRange(Begin).getBegin();
BeginFileID = SM->getFileID(Begin);
}
// Then, crawl the expansion chain for the end of the range.
if (BeginFileID != EndFileID) {
while (End.isMacroID() && !BeginLocsMap.count(EndFileID)) {
- End = SM->getImmediateExpansionRange(End).second;
+ auto Exp = SM->getImmediateExpansionRange(End);
+ IsTokenRange = Exp.isTokenRange();
+ End = Exp.getEnd();
EndFileID = SM->getFileID(End);
}
if (End.isMacroID()) {
@@ -377,9 +399,11 @@ mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef<CharSourceRange> Ranges,
SmallVector<FileID, 4> CommonArgExpansions;
computeCommonMacroArgExpansionFileIDs(Begin, End, SM, CommonArgExpansions);
Begin = retrieveMacroLocation(Begin, BeginFileID, CaretLocFileID,
- CommonArgExpansions, /*IsBegin=*/true, SM);
+ CommonArgExpansions, /*IsBegin=*/true, SM,
+ IsTokenRange);
End = retrieveMacroLocation(End, BeginFileID, CaretLocFileID,
- CommonArgExpansions, /*IsBegin=*/false, SM);
+ CommonArgExpansions, /*IsBegin=*/false, SM,
+ IsTokenRange);
if (Begin.isInvalid() || End.isInvalid()) continue;
// Return the spelling location of the beginning and end of the range.
@@ -400,7 +424,7 @@ void DiagnosticRenderer::emitCaret(FullSourceLoc Loc,
emitCodeContext(Loc, Level, SpellingRanges, Hints);
}
-/// \brief A helper function for emitMacroExpansion to print the
+/// A helper function for emitMacroExpansion to print the
/// macro expansion message
void DiagnosticRenderer::emitSingleMacroExpansion(
FullSourceLoc Loc, DiagnosticsEngine::Level Level,
@@ -441,7 +465,7 @@ static bool checkLocForMacroArgExpansion(SourceLocation Loc,
}
/// Check if all the locations in the range have the same macro argument
-/// expansion, and that that expansion starts with ArgumentLoc.
+/// expansion, and that the expansion starts with ArgumentLoc.
static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
const SourceManager &SM,
SourceLocation ArgumentLoc) {
@@ -466,8 +490,9 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc,
/// Count all valid ranges.
unsigned ValidCount = 0;
- for (auto I : Ranges)
- if (I.isValid()) ValidCount++;
+ for (const auto &Range : Ranges)
+ if (Range.isValid())
+ ValidCount++;
if (ValidCount > SpellingRanges.size())
return false;
@@ -480,15 +505,14 @@ static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc,
if (!Loc.isMacroArgExpansion(&ArgumentLoc))
return false;
- for (auto I = SpellingRanges.begin(), E = SpellingRanges.end(); I != E; ++I) {
- if (!checkRangeForMacroArgExpansion(*I, Loc.getManager(), ArgumentLoc))
+ for (const auto &Range : SpellingRanges)
+ if (!checkRangeForMacroArgExpansion(Range, Loc.getManager(), ArgumentLoc))
return false;
- }
return true;
}
-/// \brief Recursively emit notes for each macro expansion and caret
+/// Recursively emit notes for each macro expansion and caret
/// diagnostics where appropriate.
///
/// Walks up the macro expansion stack printing expansion notes, the code
@@ -504,29 +528,31 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
ArrayRef<CharSourceRange> Ranges,
ArrayRef<FixItHint> Hints) {
assert(Loc.isValid() && "must have a valid source location here");
+ const SourceManager &SM = Loc.getManager();
+ SourceLocation L = Loc;
// Produce a stack of macro backtraces.
- SmallVector<FullSourceLoc, 8> LocationStack;
+ SmallVector<SourceLocation, 8> LocationStack;
unsigned IgnoredEnd = 0;
- while (Loc.isMacroID()) {
+ while (L.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 (Loc.isMacroArgExpansion())
- LocationStack.push_back(Loc.getImmediateExpansionRange().first);
+ if (SM.isMacroArgExpansion(L))
+ LocationStack.push_back(SM.getImmediateExpansionRange(L).getBegin());
else
- LocationStack.push_back(Loc);
+ LocationStack.push_back(L);
- if (checkRangesForMacroArgExpansion(Loc, Ranges))
+ if (checkRangesForMacroArgExpansion(FullSourceLoc(L, SM), Ranges))
IgnoredEnd = LocationStack.size();
- Loc = Loc.getImmediateMacroCallerLoc();
+ L = SM.getImmediateMacroCallerLoc(L);
// 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 = LocationStack.back().getImmediateMacroCallerLoc();
- assert(Loc.isValid() && "must have a valid source location here");
+ if (L.isFileID())
+ L = SM.getImmediateMacroCallerLoc(LocationStack.back());
+ assert(L.isValid() && "must have a valid source location here");
}
LocationStack.erase(LocationStack.begin(),
@@ -537,7 +563,7 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
if (MacroDepth <= MacroLimit || MacroLimit == 0) {
for (auto I = LocationStack.rbegin(), E = LocationStack.rend();
I != E; ++I)
- emitSingleMacroExpansion(*I, Level, Ranges);
+ emitSingleMacroExpansion(FullSourceLoc(*I, SM), Level, Ranges);
return;
}
@@ -547,7 +573,7 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
for (auto I = LocationStack.rbegin(),
E = LocationStack.rbegin() + MacroStartMessages;
I != E; ++I)
- emitSingleMacroExpansion(*I, Level, Ranges);
+ emitSingleMacroExpansion(FullSourceLoc(*I, SM), Level, Ranges);
SmallString<200> MessageStorage;
llvm::raw_svector_ostream Message(MessageStorage);
@@ -559,10 +585,10 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
for (auto I = LocationStack.rend() - MacroEndMessages,
E = LocationStack.rend();
I != E; ++I)
- emitSingleMacroExpansion(*I, Level, Ranges);
+ emitSingleMacroExpansion(FullSourceLoc(*I, SM), Level, Ranges);
}
-DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
+DiagnosticNoteRenderer::~DiagnosticNoteRenderer() = default;
void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc,
PresumedLoc PLoc) {
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 12226b231417..a5929424e52a 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -79,7 +79,7 @@ public:
}
};
-/// \brief Dumps deserialized declarations.
+/// Dumps deserialized declarations.
class DeserializedDeclsDumper : public DelegatingDeserializationListener {
public:
explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
@@ -88,15 +88,17 @@ public:
void DeclRead(serialization::DeclID ID, const Decl *D) override {
llvm::outs() << "PCH DECL: " << D->getDeclKindName();
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
- llvm::outs() << " - " << *ND;
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+ llvm::outs() << " - ";
+ ND->printQualifiedName(llvm::outs());
+ }
llvm::outs() << "\n";
DelegatingDeserializationListener::DeclRead(ID, D);
}
};
-/// \brief Checks deserialized declarations and emits error if a name
+/// Checks deserialized declarations and emits error if a name
/// matches one given in command-line using -error-on-deserialized-decl.
class DeserializedDeclsChecker : public DelegatingDeserializationListener {
ASTContext &Ctx;
@@ -153,6 +155,10 @@ FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
return Consumer;
+ // If this is a code completion run, avoid invoking the plugin consumers
+ if (CI.hasCodeCompletionConsumer())
+ return Consumer;
+
// Collect the list of plugins that go before the main action (in Consumers)
// or after it (in AfterConsumers)
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
@@ -282,7 +288,7 @@ static void addHeaderInclude(StringRef HeaderName,
Includes += "}\n";
}
-/// \brief Collect the set of header includes needed to construct the given
+/// Collect the set of header includes needed to construct the given
/// module and update the TopHeaders file set of the module.
///
/// \param Module The module we're collecting includes from.
@@ -760,6 +766,22 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
if (!BeginSourceFileAction(CI))
goto failure;
+ // If we were asked to load any module map files, do so now.
+ for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
+ if (auto *File = CI.getFileManager().getFile(Filename))
+ CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
+ File, /*IsSystem*/false);
+ else
+ CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
+ }
+
+ // Add a module declaration scope so that modules from -fmodule-map-file
+ // arguments may shadow modules found implicitly in search paths.
+ CI.getPreprocessor()
+ .getHeaderSearchInfo()
+ .getModuleMap()
+ .finishModuleDeclarationScope();
+
// Create the AST context and consumer unless this is a preprocessor only
// action.
if (!usesPreprocessorOnly()) {
@@ -849,15 +871,6 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
"doesn't support modules");
}
- // If we were asked to load any module map files, do so now.
- for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
- if (auto *File = CI.getFileManager().getFile(Filename))
- CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
- File, /*IsSystem*/false);
- else
- CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
- }
-
// If we were asked to load any module files, do so now.
for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
if (!CI.loadModuleFile(ModuleFile))
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index ffa5b410d2d8..9344e673c7ac 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -18,17 +18,36 @@
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
+#include "clang/Sema/TemplateInstCallback.h"
#include "clang/Serialization/ASTReader.h"
#include "clang/Serialization/ASTWriter.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
#include <memory>
#include <system_error>
using namespace clang;
+namespace {
+CodeCompleteConsumer *GetCodeCompletionConsumer(CompilerInstance &CI) {
+ return CI.hasCodeCompletionConsumer() ? &CI.getCodeCompletionConsumer()
+ : nullptr;
+}
+
+void EnsureSemaIsCreated(CompilerInstance &CI, FrontendAction &Action) {
+ if (Action.hasCodeCompletionSupport() &&
+ !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
+ CI.createCodeCompletionConsumer();
+
+ if (!CI.hasSema())
+ CI.createSema(Action.getTranslationUnitKind(),
+ GetCodeCompletionConsumer(CI));
+}
+} // namespace
+
//===----------------------------------------------------------------------===//
// Custom Actions
//===----------------------------------------------------------------------===//
@@ -55,7 +74,8 @@ ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
std::unique_ptr<ASTConsumer>
ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
- return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter,
+ return CreateASTDumper(nullptr /*Dump to stdout.*/,
+ CI.getFrontendOpts().ASTDumpFilter,
CI.getFrontendOpts().ASTDumpDecls,
CI.getFrontendOpts().ASTDumpAll,
CI.getFrontendOpts().ASTDumpLookups);
@@ -92,14 +112,14 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
if (!CI.getFrontendOpts().RelocatablePCH)
Sysroot.clear();
+ const auto &FrontendOpts = CI.getFrontendOpts();
auto Buffer = std::make_shared<PCHBuffer>();
std::vector<std::unique_ptr<ASTConsumer>> Consumers;
Consumers.push_back(llvm::make_unique<PCHGenerator>(
CI.getPreprocessor(), OutputFile, Sysroot,
- Buffer, CI.getFrontendOpts().ModuleFileExtensions,
- /*AllowASTWithErrors*/CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
- /*IncludeTimestamps*/
- +CI.getFrontendOpts().IncludeTimestamps));
+ Buffer, FrontendOpts.ModuleFileExtensions,
+ CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
+ FrontendOpts.IncludeTimestamps));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, std::move(OS), Buffer));
@@ -262,7 +282,141 @@ void VerifyPCHAction::ExecuteAction() {
}
namespace {
- /// \brief AST reader listener that dumps module information for a module
+struct TemplightEntry {
+ std::string Name;
+ std::string Kind;
+ std::string Event;
+ std::string DefinitionLocation;
+ std::string PointOfInstantiation;
+};
+} // namespace
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<TemplightEntry> {
+ static void mapping(IO &io, TemplightEntry &fields) {
+ io.mapRequired("name", fields.Name);
+ io.mapRequired("kind", fields.Kind);
+ io.mapRequired("event", fields.Event);
+ io.mapRequired("orig", fields.DefinitionLocation);
+ io.mapRequired("poi", fields.PointOfInstantiation);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
+namespace {
+class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
+ using CodeSynthesisContext = Sema::CodeSynthesisContext;
+
+public:
+ void initialize(const Sema &) override {}
+
+ void finalize(const Sema &) override {}
+
+ void atTemplateBegin(const Sema &TheSema,
+ const CodeSynthesisContext &Inst) override {
+ displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
+ }
+
+ void atTemplateEnd(const Sema &TheSema,
+ const CodeSynthesisContext &Inst) override {
+ displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
+ }
+
+private:
+ static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
+ switch (Kind) {
+ case CodeSynthesisContext::TemplateInstantiation:
+ return "TemplateInstantiation";
+ case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
+ return "DefaultTemplateArgumentInstantiation";
+ case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
+ return "DefaultFunctionArgumentInstantiation";
+ case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
+ return "ExplicitTemplateArgumentSubstitution";
+ case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
+ return "DeducedTemplateArgumentSubstitution";
+ case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
+ return "PriorTemplateArgumentSubstitution";
+ case CodeSynthesisContext::DefaultTemplateArgumentChecking:
+ return "DefaultTemplateArgumentChecking";
+ case CodeSynthesisContext::ExceptionSpecInstantiation:
+ return "ExceptionSpecInstantiation";
+ case CodeSynthesisContext::DeclaringSpecialMember:
+ return "DeclaringSpecialMember";
+ case CodeSynthesisContext::DefiningSynthesizedFunction:
+ return "DefiningSynthesizedFunction";
+ case CodeSynthesisContext::Memoization:
+ return "Memoization";
+ }
+ return "";
+ }
+
+ template <bool BeginInstantiation>
+ static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
+ const CodeSynthesisContext &Inst) {
+ std::string YAML;
+ {
+ llvm::raw_string_ostream OS(YAML);
+ llvm::yaml::Output YO(OS);
+ TemplightEntry Entry =
+ getTemplightEntry<BeginInstantiation>(TheSema, Inst);
+ llvm::yaml::EmptyContext Context;
+ llvm::yaml::yamlize(YO, Entry, true, Context);
+ }
+ Out << "---" << YAML << "\n";
+ }
+
+ template <bool BeginInstantiation>
+ static TemplightEntry getTemplightEntry(const Sema &TheSema,
+ const CodeSynthesisContext &Inst) {
+ TemplightEntry Entry;
+ Entry.Kind = toString(Inst.Kind);
+ Entry.Event = BeginInstantiation ? "Begin" : "End";
+ if (auto *NamedTemplate = dyn_cast_or_null<NamedDecl>(Inst.Entity)) {
+ llvm::raw_string_ostream OS(Entry.Name);
+ NamedTemplate->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
+ const PresumedLoc DefLoc =
+ TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
+ if(!DefLoc.isInvalid())
+ Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
+ std::to_string(DefLoc.getLine()) + ":" +
+ std::to_string(DefLoc.getColumn());
+ }
+ const PresumedLoc PoiLoc =
+ TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
+ if (!PoiLoc.isInvalid()) {
+ Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
+ std::to_string(PoiLoc.getLine()) + ":" +
+ std::to_string(PoiLoc.getColumn());
+ }
+ return Entry;
+ }
+};
+} // namespace
+
+std::unique_ptr<ASTConsumer>
+TemplightDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+ return llvm::make_unique<ASTConsumer>();
+}
+
+void TemplightDumpAction::ExecuteAction() {
+ CompilerInstance &CI = getCompilerInstance();
+
+ // This part is normally done by ASTFrontEndAction, but needs to happen
+ // before Templight observers can be created
+ // FIXME: Move the truncation aspect of this into Sema, we delayed this till
+ // here so the source manager would be initialized.
+ EnsureSemaIsCreated(CI, *this);
+
+ CI.getSema().TemplateInstCallbacks.push_back(
+ llvm::make_unique<DefaultTemplateInstCallback>());
+ ASTFrontendAction::ExecuteAction();
+}
+
+namespace {
+ /// AST reader listener that dumps module information for a module
/// file.
class DumpModuleInfoListener : public ASTReaderListener {
llvm::raw_ostream &Out;
@@ -406,6 +560,45 @@ namespace {
Out << "\n";
}
+
+ /// Tells the \c ASTReaderListener that we want to receive the
+ /// input files of the AST file via \c visitInputFile.
+ bool needsInputFileVisitation() override { return true; }
+
+ /// Tells the \c ASTReaderListener that we want to receive the
+ /// input files of the AST file via \c visitInputFile.
+ bool needsSystemInputFileVisitation() override { return true; }
+
+ /// Indicates that the AST file contains particular input file.
+ ///
+ /// \returns true to continue receiving the next input file, false to stop.
+ bool visitInputFile(StringRef Filename, bool isSystem,
+ bool isOverridden, bool isExplicitModule) override {
+
+ Out.indent(2) << "Input file: " << Filename;
+
+ if (isSystem || isOverridden || isExplicitModule) {
+ Out << " [";
+ if (isSystem) {
+ Out << "System";
+ if (isOverridden || isExplicitModule)
+ Out << ", ";
+ }
+ if (isOverridden) {
+ Out << "Overridden";
+ if (isExplicitModule)
+ Out << ", ";
+ }
+ if (isExplicitModule)
+ Out << "ExplicitModule";
+
+ Out << "]";
+ }
+
+ Out << "\n";
+
+ return true;
+ }
#undef DUMP_BOOLEAN
};
}
@@ -579,6 +772,7 @@ void PrintPreambleAction::ExecuteAction() {
case InputKind::ObjCXX:
case InputKind::OpenCL:
case InputKind::CUDA:
+ case InputKind::HIP:
break;
case InputKind::Unknown:
@@ -601,3 +795,51 @@ void PrintPreambleAction::ExecuteAction() {
llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
}
}
+
+void DumpCompilerOptionsAction::ExecuteAction() {
+ CompilerInstance &CI = getCompilerInstance();
+ std::unique_ptr<raw_ostream> OSP =
+ CI.createDefaultOutputFile(false, getCurrentFile());
+ if (!OSP)
+ return;
+
+ raw_ostream &OS = *OSP;
+ const Preprocessor &PP = CI.getPreprocessor();
+ const LangOptions &LangOpts = PP.getLangOpts();
+
+ // FIXME: Rather than manually format the JSON (which is awkward due to
+ // needing to remove trailing commas), this should make use of a JSON library.
+ // FIXME: Instead of printing enums as an integral value and specifying the
+ // type as a separate field, use introspection to print the enumerator.
+
+ OS << "{\n";
+ OS << "\n\"features\" : [\n";
+ {
+ llvm::SmallString<128> Str;
+#define FEATURE(Name, Predicate) \
+ ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
+ .toVector(Str);
+#include "clang/Basic/Features.def"
+#undef FEATURE
+ // Remove the newline and comma from the last entry to ensure this remains
+ // valid JSON.
+ OS << Str.substr(0, Str.size() - 2);
+ }
+ OS << "\n],\n";
+
+ OS << "\n\"extensions\" : [\n";
+ {
+ llvm::SmallString<128> Str;
+#define EXTENSION(Name, Predicate) \
+ ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
+ .toVector(Str);
+#include "clang/Basic/Features.def"
+#undef EXTENSION
+ // Remove the newline and comma from the last entry to ensure this remains
+ // valid JSON.
+ OS << Str.substr(0, Str.size() - 2);
+ }
+ OS << "\n]\n";
+
+ OS << "}";
+}
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index dca434588fb1..0744d447e816 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -1,4 +1,4 @@
-//===--- FrontendOptions.cpp ----------------------------------------------===//
+//===- FrontendOptions.cpp ------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,6 +9,7 @@
#include "clang/Frontend/FrontendOptions.h"
#include "llvm/ADT/StringSwitch.h"
+
using namespace clang;
InputKind FrontendOptions::getInputKindForExtension(StringRef Extension) {
diff --git a/lib/Frontend/FrontendTiming.cpp b/lib/Frontend/FrontendTiming.cpp
new file mode 100644
index 000000000000..9ea7347e7797
--- /dev/null
+++ b/lib/Frontend/FrontendTiming.cpp
@@ -0,0 +1,20 @@
+//===- FronendTiming.cpp - Implements Frontend timing utils --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file keps implementation of frontend timing utils.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/Utils.h"
+
+namespace clang {
+
+bool FrontendTimesIsEnabled = false;
+
+}
diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp
index 5bff4ecd0b46..9dc107c9d546 100644
--- a/lib/Frontend/HeaderIncludeGen.cpp
+++ b/lib/Frontend/HeaderIncludeGen.cpp
@@ -80,9 +80,23 @@ void clang::AttachHeaderIncludeGen(Preprocessor &PP,
const DependencyOutputOptions &DepOpts,
bool ShowAllHeaders, StringRef OutputPath,
bool ShowDepth, bool MSStyle) {
- raw_ostream *OutputFile = MSStyle ? &llvm::outs() : &llvm::errs();
+ raw_ostream *OutputFile = &llvm::errs();
bool OwnsOutputFile = false;
+ // Choose output stream, when printing in cl.exe /showIncludes style.
+ if (MSStyle) {
+ switch (DepOpts.ShowIncludesDest) {
+ default:
+ llvm_unreachable("Invalid destination for /showIncludes output!");
+ case ShowIncludesDestination::Stderr:
+ OutputFile = &llvm::errs();
+ break;
+ case ShowIncludesDestination::Stdout:
+ OutputFile = &llvm::outs();
+ break;
+ }
+ }
+
// Open the output file, if used.
if (!OutputPath.empty()) {
std::error_code EC;
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 8c6faced76ac..8a70404629d3 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -14,6 +14,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Config/config.h" // C_INCLUDE_DIRS
+#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderMap.h"
#include "clang/Lex/HeaderSearch.h"
@@ -55,11 +56,13 @@ public:
/// AddPath - Add the specified path to the specified group list, prefixing
/// the sysroot if used.
- void AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework);
+ /// Returns true if the path exists, false if it was ignored.
+ bool AddPath(const Twine &Path, IncludeDirGroup Group, bool isFramework);
/// AddUnmappedPath - Add the specified path to the specified group list,
/// without performing any sysroot remapping.
- void AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
+ /// Returns true if the path exists, false if it was ignored.
+ bool AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
bool isFramework);
/// AddSystemHeaderPrefix - Add the specified prefix to the system header
@@ -70,10 +73,9 @@ public:
/// AddGnuCPlusPlusIncludePaths - Add the necessary paths to support a gnu
/// libstdc++.
- void AddGnuCPlusPlusIncludePaths(StringRef Base,
- StringRef ArchDir,
- StringRef Dir32,
- StringRef Dir64,
+ /// Returns true if the \p Base path was found, false if it does not exist.
+ bool AddGnuCPlusPlusIncludePaths(StringRef Base, StringRef ArchDir,
+ StringRef Dir32, StringRef Dir64,
const llvm::Triple &triple);
/// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to support a MinGW
@@ -88,7 +90,8 @@ public:
// AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
// compiling c++.
- void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple,
+ void AddDefaultCPlusPlusIncludePaths(const LangOptions &LangOpts,
+ const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts);
/// AddDefaultSystemIncludePaths - Adds the default system include paths so
@@ -105,14 +108,14 @@ public:
} // end anonymous namespace.
static bool CanPrefixSysroot(StringRef Path) {
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
return !Path.empty() && llvm::sys::path::is_separator(Path[0]);
#else
return llvm::sys::path::is_absolute(Path);
#endif
}
-void InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group,
+bool InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group,
bool isFramework) {
// Add the path with sysroot prepended, if desired and this is a system header
// group.
@@ -120,15 +123,14 @@ void InitHeaderSearch::AddPath(const Twine &Path, IncludeDirGroup Group,
SmallString<256> MappedPathStorage;
StringRef MappedPathStr = Path.toStringRef(MappedPathStorage);
if (CanPrefixSysroot(MappedPathStr)) {
- AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
- return;
+ return AddUnmappedPath(IncludeSysroot + Path, Group, isFramework);
}
}
- AddUnmappedPath(Path, Group, isFramework);
+ return AddUnmappedPath(Path, Group, isFramework);
}
-void InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
+bool InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
bool isFramework) {
assert(!Path.isTriviallyEmpty() && "can't handle empty path here");
@@ -150,7 +152,7 @@ void InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
if (const DirectoryEntry *DE = FM.getDirectory(MappedPathStr)) {
IncludePath.push_back(
std::make_pair(Group, DirectoryLookup(DE, Type, isFramework)));
- return;
+ return true;
}
// Check to see if this is an apple-style headermap (which are not allowed to
@@ -162,7 +164,7 @@ void InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
IncludePath.push_back(
std::make_pair(Group,
DirectoryLookup(HM, Type, Group == IndexHeaderMap)));
- return;
+ return true;
}
}
}
@@ -170,15 +172,16 @@ void InitHeaderSearch::AddUnmappedPath(const Twine &Path, IncludeDirGroup Group,
if (Verbose)
llvm::errs() << "ignoring nonexistent directory \""
<< MappedPathStr << "\"\n";
+ return false;
}
-void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
+bool InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
StringRef ArchDir,
StringRef Dir32,
StringRef Dir64,
const llvm::Triple &triple) {
// Add the base dir
- AddPath(Base, CXXSystem, false);
+ bool IsBaseFound = AddPath(Base, CXXSystem, false);
// Add the multilib dirs
llvm::Triple::ArchType arch = triple.getArch();
@@ -190,6 +193,7 @@ void InitHeaderSearch::AddGnuCPlusPlusIncludePaths(StringRef Base,
// Add the backward dir
AddPath(Base + "/backward", CXXSystem, false);
+ return IsBaseFound;
}
void InitHeaderSearch::AddMinGWCPlusPlusIncludePaths(StringRef Base,
@@ -216,6 +220,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::NaCl:
case llvm::Triple::PS4:
case llvm::Triple::ELFIAMCU:
+ case llvm::Triple::Fuchsia:
break;
case llvm::Triple::Win32:
if (triple.getEnvironment() != llvm::Triple::Cygnus)
@@ -255,6 +260,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
switch (os) {
case llvm::Triple::Linux:
+ case llvm::Triple::Solaris:
llvm_unreachable("Include management is handled in the driver.");
case llvm::Triple::CloudABI: {
@@ -321,6 +327,7 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
case llvm::Triple::RTEMS:
case llvm::Triple::NaCl:
case llvm::Triple::ELFIAMCU:
+ case llvm::Triple::Fuchsia:
break;
case llvm::Triple::PS4: {
// <isysroot> gets prepended later in AddPath().
@@ -351,51 +358,61 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
}
}
-void InitHeaderSearch::
-AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOptions &HSOpts) {
+void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(
+ const LangOptions &LangOpts, const llvm::Triple &triple,
+ const HeaderSearchOptions &HSOpts) {
llvm::Triple::OSType os = triple.getOS();
// FIXME: temporary hack: hard-coded paths.
if (triple.isOSDarwin()) {
+ bool IsBaseFound = true;
switch (triple.getArch()) {
default: break;
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
- "powerpc-apple-darwin10", "", "ppc64",
- triple);
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
- "powerpc-apple-darwin10", "", "ppc64",
- triple);
+ IsBaseFound = AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+ "powerpc-apple-darwin10", "",
+ "ppc64", triple);
+ IsBaseFound |= AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
+ "powerpc-apple-darwin10", "",
+ "ppc64", triple);
break;
case llvm::Triple::x86:
case llvm::Triple::x86_64:
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
- "i686-apple-darwin10", "", "x86_64", triple);
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.0.0",
- "i686-apple-darwin8", "", "", triple);
+ IsBaseFound = AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
+ "i686-apple-darwin10", "",
+ "x86_64", triple);
+ IsBaseFound |= AddGnuCPlusPlusIncludePaths(
+ "/usr/include/c++/4.0.0", "i686-apple-darwin8", "", "", triple);
break;
case llvm::Triple::arm:
case llvm::Triple::thumb:
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
- "arm-apple-darwin10", "v7", "", triple);
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
- "arm-apple-darwin10", "v6", "", triple);
+ IsBaseFound = AddGnuCPlusPlusIncludePaths(
+ "/usr/include/c++/4.2.1", "arm-apple-darwin10", "v7", "", triple);
+ IsBaseFound |= AddGnuCPlusPlusIncludePaths(
+ "/usr/include/c++/4.2.1", "arm-apple-darwin10", "v6", "", triple);
break;
case llvm::Triple::aarch64:
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
- "arm64-apple-darwin10", "", "", triple);
+ IsBaseFound = AddGnuCPlusPlusIncludePaths(
+ "/usr/include/c++/4.2.1", "arm64-apple-darwin10", "", "", triple);
break;
}
+ // Warn when compiling pure C++ / Objective-C++ only.
+ if (!IsBaseFound &&
+ !(LangOpts.CUDA || LangOpts.OpenCL || LangOpts.RenderScript)) {
+ Headers.getDiags().Report(SourceLocation(),
+ diag::warn_stdlibcxx_not_found);
+ }
return;
}
switch (os) {
case llvm::Triple::Linux:
+ case llvm::Triple::Solaris:
llvm_unreachable("Include management is handled in the driver.");
break;
case llvm::Triple::Win32:
@@ -443,6 +460,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
break; // Everything else continues to use this routine's logic.
case llvm::Triple::Linux:
+ case llvm::Triple::Solaris:
return;
case llvm::Triple::Win32:
@@ -452,8 +470,8 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
break;
}
- if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes &&
- HSOpts.UseStandardSystemIncludes) {
+ if (Lang.CPlusPlus && !Lang.AsmPreprocessor &&
+ HSOpts.UseStandardCXXIncludes && HSOpts.UseStandardSystemIncludes) {
if (HSOpts.UseLibcxx) {
if (triple.isOSDarwin()) {
// On Darwin, libc++ may be installed alongside the compiler in
@@ -473,7 +491,7 @@ void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
}
AddPath("/usr/include/c++/v1", CXXSystem, false);
} else {
- AddDefaultCPlusPlusIncludePaths(triple, HSOpts);
+ AddDefaultCPlusPlusIncludePaths(Lang, triple, HSOpts);
}
}
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index d39890494323..e3f4f92b9d1e 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -93,7 +93,7 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP,
AddImplicitInclude(Builder, OriginalFile);
}
-/// \brief Add an implicit \#include using the original file used to generate
+/// Add an implicit \#include using the original file used to generate
/// a PCH file.
static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP,
const PCHContainerReader &PCHContainerRdr,
@@ -301,7 +301,7 @@ static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign,
return "1"; // "sometimes lock free"
}
-/// \brief Add definitions required for a smooth interaction between
+/// Add definitions required for a smooth interaction between
/// Objective-C++ automated reference counting and libstdc++ (4.2).
static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts,
MacroBuilder &Builder) {
@@ -426,45 +426,59 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros.
if (LangOpts.OpenCL) {
- // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the
- // language standard with which the program is compiled. __OPENCL_VERSION__
- // is for the OpenCL version supported by the OpenCL device, which is not
- // necessarily the language standard with which the program is compiled.
- // A shared OpenCL header file requires a macro to indicate the language
- // standard. As a workaround, __OPENCL_C_VERSION__ is defined for
- // OpenCL v1.0 and v1.1.
- switch (LangOpts.OpenCLVersion) {
- case 100:
- Builder.defineMacro("__OPENCL_C_VERSION__", "100");
- break;
- case 110:
- Builder.defineMacro("__OPENCL_C_VERSION__", "110");
- break;
- case 120:
- Builder.defineMacro("__OPENCL_C_VERSION__", "120");
- break;
- case 200:
- Builder.defineMacro("__OPENCL_C_VERSION__", "200");
- break;
- default:
- llvm_unreachable("Unsupported OpenCL version");
- }
- Builder.defineMacro("CL_VERSION_1_0", "100");
- Builder.defineMacro("CL_VERSION_1_1", "110");
- Builder.defineMacro("CL_VERSION_1_2", "120");
- Builder.defineMacro("CL_VERSION_2_0", "200");
+ if (LangOpts.CPlusPlus) {
+ if (LangOpts.OpenCLCPlusPlusVersion == 100)
+ Builder.defineMacro("__OPENCL_CPP_VERSION__", "100");
+ else
+ llvm_unreachable("Unsupported OpenCL C++ version");
+ Builder.defineMacro("__CL_CPP_VERSION_1_0__", "100");
+ } else {
+ // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the
+ // language standard with which the program is compiled. __OPENCL_VERSION__
+ // is for the OpenCL version supported by the OpenCL device, which is not
+ // necessarily the language standard with which the program is compiled.
+ // A shared OpenCL header file requires a macro to indicate the language
+ // standard. As a workaround, __OPENCL_C_VERSION__ is defined for
+ // OpenCL v1.0 and v1.1.
+ switch (LangOpts.OpenCLVersion) {
+ case 100:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "100");
+ break;
+ case 110:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "110");
+ break;
+ case 120:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "120");
+ break;
+ case 200:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "200");
+ break;
+ default:
+ llvm_unreachable("Unsupported OpenCL version");
+ }
+ Builder.defineMacro("CL_VERSION_1_0", "100");
+ Builder.defineMacro("CL_VERSION_1_1", "110");
+ Builder.defineMacro("CL_VERSION_1_2", "120");
+ Builder.defineMacro("CL_VERSION_2_0", "200");
- if (TI.isLittleEndian())
- Builder.defineMacro("__ENDIAN_LITTLE__");
+ if (TI.isLittleEndian())
+ Builder.defineMacro("__ENDIAN_LITTLE__");
- if (LangOpts.FastRelaxedMath)
- Builder.defineMacro("__FAST_RELAXED_MATH__");
+ if (LangOpts.FastRelaxedMath)
+ Builder.defineMacro("__FAST_RELAXED_MATH__");
+ }
}
// Not "standard" per se, but available even with the -undef flag.
if (LangOpts.AsmPreprocessor)
Builder.defineMacro("__ASSEMBLER__");
- if (LangOpts.CUDA)
+ if (LangOpts.CUDA && !LangOpts.HIP)
Builder.defineMacro("__CUDA__");
+ if (LangOpts.HIP) {
+ Builder.defineMacro("__HIP__");
+ Builder.defineMacro("__HIPCC__");
+ if (LangOpts.CUDAIsDevice)
+ Builder.defineMacro("__HIP_DEVICE_COMPILE__");
+ }
}
/// Initialize the predefined C++ language feature test macros defined in
@@ -473,78 +487,86 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
MacroBuilder &Builder) {
// C++98 features.
if (LangOpts.RTTI)
- Builder.defineMacro("__cpp_rtti", "199711");
+ Builder.defineMacro("__cpp_rtti", "199711L");
if (LangOpts.CXXExceptions)
- Builder.defineMacro("__cpp_exceptions", "199711");
+ Builder.defineMacro("__cpp_exceptions", "199711L");
// C++11 features.
if (LangOpts.CPlusPlus11) {
- Builder.defineMacro("__cpp_unicode_characters", "200704");
- Builder.defineMacro("__cpp_raw_strings", "200710");
- Builder.defineMacro("__cpp_unicode_literals", "200710");
- Builder.defineMacro("__cpp_user_defined_literals", "200809");
- Builder.defineMacro("__cpp_lambdas", "200907");
+ Builder.defineMacro("__cpp_unicode_characters", "200704L");
+ Builder.defineMacro("__cpp_raw_strings", "200710L");
+ Builder.defineMacro("__cpp_unicode_literals", "200710L");
+ Builder.defineMacro("__cpp_user_defined_literals", "200809L");
+ Builder.defineMacro("__cpp_lambdas", "200907L");
Builder.defineMacro("__cpp_constexpr",
- LangOpts.CPlusPlus17 ? "201603" :
- LangOpts.CPlusPlus14 ? "201304" : "200704");
+ LangOpts.CPlusPlus17 ? "201603L" :
+ LangOpts.CPlusPlus14 ? "201304L" : "200704");
Builder.defineMacro("__cpp_range_based_for",
- LangOpts.CPlusPlus17 ? "201603" : "200907");
+ LangOpts.CPlusPlus17 ? "201603L" : "200907");
Builder.defineMacro("__cpp_static_assert",
- LangOpts.CPlusPlus17 ? "201411" : "200410");
- Builder.defineMacro("__cpp_decltype", "200707");
- Builder.defineMacro("__cpp_attributes", "200809");
- Builder.defineMacro("__cpp_rvalue_references", "200610");
- Builder.defineMacro("__cpp_variadic_templates", "200704");
- Builder.defineMacro("__cpp_initializer_lists", "200806");
- Builder.defineMacro("__cpp_delegating_constructors", "200604");
- Builder.defineMacro("__cpp_nsdmi", "200809");
- Builder.defineMacro("__cpp_inheriting_constructors", "201511");
- Builder.defineMacro("__cpp_ref_qualifiers", "200710");
- Builder.defineMacro("__cpp_alias_templates", "200704");
+ LangOpts.CPlusPlus17 ? "201411L" : "200410");
+ Builder.defineMacro("__cpp_decltype", "200707L");
+ Builder.defineMacro("__cpp_attributes", "200809L");
+ Builder.defineMacro("__cpp_rvalue_references", "200610L");
+ Builder.defineMacro("__cpp_variadic_templates", "200704L");
+ Builder.defineMacro("__cpp_initializer_lists", "200806L");
+ Builder.defineMacro("__cpp_delegating_constructors", "200604L");
+ Builder.defineMacro("__cpp_nsdmi", "200809L");
+ Builder.defineMacro("__cpp_inheriting_constructors", "201511L");
+ Builder.defineMacro("__cpp_ref_qualifiers", "200710L");
+ Builder.defineMacro("__cpp_alias_templates", "200704L");
}
if (LangOpts.ThreadsafeStatics)
- Builder.defineMacro("__cpp_threadsafe_static_init", "200806");
+ Builder.defineMacro("__cpp_threadsafe_static_init", "200806L");
// C++14 features.
if (LangOpts.CPlusPlus14) {
- Builder.defineMacro("__cpp_binary_literals", "201304");
- Builder.defineMacro("__cpp_digit_separators", "201309");
- Builder.defineMacro("__cpp_init_captures", "201304");
- Builder.defineMacro("__cpp_generic_lambdas", "201304");
- Builder.defineMacro("__cpp_decltype_auto", "201304");
- Builder.defineMacro("__cpp_return_type_deduction", "201304");
- Builder.defineMacro("__cpp_aggregate_nsdmi", "201304");
- Builder.defineMacro("__cpp_variable_templates", "201304");
+ Builder.defineMacro("__cpp_binary_literals", "201304L");
+ Builder.defineMacro("__cpp_digit_separators", "201309L");
+ Builder.defineMacro("__cpp_init_captures", "201304L");
+ Builder.defineMacro("__cpp_generic_lambdas", "201304L");
+ Builder.defineMacro("__cpp_decltype_auto", "201304L");
+ Builder.defineMacro("__cpp_return_type_deduction", "201304L");
+ Builder.defineMacro("__cpp_aggregate_nsdmi", "201304L");
+ Builder.defineMacro("__cpp_variable_templates", "201304L");
}
if (LangOpts.SizedDeallocation)
- Builder.defineMacro("__cpp_sized_deallocation", "201309");
+ Builder.defineMacro("__cpp_sized_deallocation", "201309L");
// C++17 features.
if (LangOpts.CPlusPlus17) {
- Builder.defineMacro("__cpp_hex_float", "201603");
- Builder.defineMacro("__cpp_inline_variables", "201606");
- Builder.defineMacro("__cpp_noexcept_function_type", "201510");
- Builder.defineMacro("__cpp_capture_star_this", "201603");
- Builder.defineMacro("__cpp_if_constexpr", "201606");
- Builder.defineMacro("__cpp_deduction_guides", "201611");
- Builder.defineMacro("__cpp_template_auto", "201606");
- Builder.defineMacro("__cpp_namespace_attributes", "201411");
- Builder.defineMacro("__cpp_enumerator_attributes", "201411");
- Builder.defineMacro("__cpp_nested_namespace_definitions", "201411");
- Builder.defineMacro("__cpp_variadic_using", "201611");
- Builder.defineMacro("__cpp_aggregate_bases", "201603");
- Builder.defineMacro("__cpp_structured_bindings", "201606");
- Builder.defineMacro("__cpp_nontype_template_args", "201411");
- Builder.defineMacro("__cpp_fold_expressions", "201603");
+ Builder.defineMacro("__cpp_hex_float", "201603L");
+ Builder.defineMacro("__cpp_inline_variables", "201606L");
+ Builder.defineMacro("__cpp_noexcept_function_type", "201510L");
+ Builder.defineMacro("__cpp_capture_star_this", "201603L");
+ Builder.defineMacro("__cpp_if_constexpr", "201606L");
+ Builder.defineMacro("__cpp_deduction_guides", "201703L");
+ Builder.defineMacro("__cpp_template_auto", "201606L"); // (old name)
+ Builder.defineMacro("__cpp_namespace_attributes", "201411L");
+ Builder.defineMacro("__cpp_enumerator_attributes", "201411L");
+ Builder.defineMacro("__cpp_nested_namespace_definitions", "201411L");
+ Builder.defineMacro("__cpp_variadic_using", "201611L");
+ Builder.defineMacro("__cpp_aggregate_bases", "201603L");
+ Builder.defineMacro("__cpp_structured_bindings", "201606L");
+ Builder.defineMacro("__cpp_nontype_template_args", "201411L");
+ Builder.defineMacro("__cpp_fold_expressions", "201603L");
+ Builder.defineMacro("__cpp_guaranteed_copy_elision", "201606L");
+ Builder.defineMacro("__cpp_nontype_template_parameter_auto", "201606L");
}
if (LangOpts.AlignedAllocation)
- Builder.defineMacro("__cpp_aligned_new", "201606");
+ Builder.defineMacro("__cpp_aligned_new", "201606L");
+ if (LangOpts.RelaxedTemplateTemplateArgs)
+ Builder.defineMacro("__cpp_template_template_args", "201611L");
// TS features.
if (LangOpts.ConceptsTS)
- Builder.defineMacro("__cpp_experimental_concepts", "1");
+ Builder.defineMacro("__cpp_experimental_concepts", "1L");
if (LangOpts.CoroutinesTS)
Builder.defineMacro("__cpp_coroutines", "201703L");
+
+ // Potential future breaking changes.
+ if (LangOpts.Char8)
+ Builder.defineMacro("__cpp_char8_t", "201803L");
}
static void InitializePredefinedMacros(const TargetInfo &TI,
@@ -627,6 +649,19 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.ObjCRuntime.isNeXTFamily())
Builder.defineMacro("__NEXT_RUNTIME__");
+ if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::GNUstep) {
+ auto version = LangOpts.ObjCRuntime.getVersion();
+ std::string versionString = "1";
+ // Don't rely on the tuple argument, because we can be asked to target
+ // later ABIs than we actually support, so clamp these values to those
+ // currently supported
+ if (version >= VersionTuple(2, 0))
+ Builder.defineMacro("__OBJC_GNUSTEP_RUNTIME_ABI__", "20");
+ else
+ Builder.defineMacro("__OBJC_GNUSTEP_RUNTIME_ABI__",
+ "1" + Twine(std::min(8U, version.getMinor().getValueOr(0))));
+ }
+
if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) {
VersionTuple tuple = LangOpts.ObjCRuntime.getVersion();
@@ -817,10 +852,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");
- if (TI.hasFloat128Type())
- // FIXME: Switch away from the non-standard "Q" when we can
- DefineFloatMacros(Builder, "FLT128", &TI.getFloat128Format(), "Q");
-
// Define a __POINTER_WIDTH__ macro for stdint.h.
Builder.defineMacro("__POINTER_WIDTH__",
@@ -929,6 +960,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
InlineWidthBits));
DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
DEFINE_LOCK_FREE_MACRO(CHAR, Char);
+ if (LangOpts.Char8)
+ DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
@@ -1011,23 +1044,25 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// macro name is defined to have the decimal value yyyymm where
// yyyy and mm are the year and the month designations of the
// version of the OpenMP API that the implementation support.
- switch (LangOpts.OpenMP) {
- case 0:
- break;
- case 40:
- Builder.defineMacro("_OPENMP", "201307");
- break;
- case 45:
- Builder.defineMacro("_OPENMP", "201511");
- break;
- default:
- // Default version is OpenMP 3.1
- Builder.defineMacro("_OPENMP", "201107");
- break;
+ if (!LangOpts.OpenMPSimd) {
+ switch (LangOpts.OpenMP) {
+ case 0:
+ break;
+ case 40:
+ Builder.defineMacro("_OPENMP", "201307");
+ break;
+ case 45:
+ Builder.defineMacro("_OPENMP", "201511");
+ break;
+ default:
+ // Default version is OpenMP 3.1
+ Builder.defineMacro("_OPENMP", "201107");
+ break;
+ }
}
// CUDA device path compilaton
- if (LangOpts.CUDAIsDevice) {
+ if (LangOpts.CUDAIsDevice && !LangOpts.HIP) {
// The CUDA_ARCH value is set for the GPU target specified in the NVPTX
// backend's target defines.
Builder.defineMacro("__CUDA_ARCH__");
diff --git a/lib/Frontend/LayoutOverrideSource.cpp b/lib/Frontend/LayoutOverrideSource.cpp
index 06e9a7dc50b4..93e07eb81f72 100644
--- a/lib/Frontend/LayoutOverrideSource.cpp
+++ b/lib/Frontend/LayoutOverrideSource.cpp
@@ -15,7 +15,7 @@
using namespace clang;
-/// \brief Parse a simple identifier.
+/// Parse a simple identifier.
static std::string parseName(StringRef S) {
if (S.empty() || !isIdentifierHead(S[0]))
return "";
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
index ede12aab6e69..25cad8be6d00 100644
--- a/lib/Frontend/ModuleDependencyCollector.cpp
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -16,6 +16,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Serialization/ASTReader.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@@ -49,7 +50,8 @@ struct ModuleDependencyPPCallbacks : public PPCallbacks {
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override {
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override {
if (!File)
return;
Collector.addFile(File->getName());
@@ -135,7 +137,7 @@ static bool isCaseSensitivePath(StringRef Path) {
// Change path to all upper case and ask for its real path, if the latter
// exists and is equal to Path, it's not case sensitive. Default to case
- // sensitive in the absense of realpath, since this is what the VFSWriter
+ // sensitive in the absence of realpath, since this is what the VFSWriter
// already expects when sensitivity isn't setup.
for (auto &C : Path)
UpperDest.push_back(toUppercase(C));
diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp
index 04a8f6c1cdfb..df36c88ec38e 100644
--- a/lib/Frontend/MultiplexConsumer.cpp
+++ b/lib/Frontend/MultiplexConsumer.cpp
@@ -16,35 +16,11 @@
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclGroup.h"
-#include "clang/Serialization/ASTDeserializationListener.h"
using namespace clang;
namespace clang {
-// This ASTDeserializationListener forwards its notifications to a set of
-// child listeners.
-class MultiplexASTDeserializationListener
- : public ASTDeserializationListener {
-public:
- // Does NOT take ownership of the elements in L.
- MultiplexASTDeserializationListener(
- const std::vector<ASTDeserializationListener*>& L);
- void ReaderInitialized(ASTReader *Reader) override;
- void IdentifierRead(serialization::IdentID ID,
- IdentifierInfo *II) override;
- void MacroRead(serialization::MacroID ID, MacroInfo *MI) override;
- void TypeRead(serialization::TypeIdx Idx, QualType T) override;
- void DeclRead(serialization::DeclID ID, const Decl *D) override;
- void SelectorRead(serialization::SelectorID iD, Selector Sel) override;
- void MacroDefinitionRead(serialization::PreprocessedEntityID,
- MacroDefinitionRecord *MD) override;
- void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override;
-
-private:
- std::vector<ASTDeserializationListener *> Listeners;
-};
-
MultiplexASTDeserializationListener::MultiplexASTDeserializationListener(
const std::vector<ASTDeserializationListener*>& L)
: Listeners(L) {
diff --git a/lib/Frontend/PCHContainerOperations.cpp b/lib/Frontend/PCHContainerOperations.cpp
index eebebf327a19..340e8ce63ff4 100644
--- a/lib/Frontend/PCHContainerOperations.cpp
+++ b/lib/Frontend/PCHContainerOperations.cpp
@@ -25,7 +25,7 @@ PCHContainerReader::~PCHContainerReader() {}
namespace {
-/// \brief A PCHContainerGenerator that writes out the PCH to a flat file.
+/// A PCHContainerGenerator that writes out the PCH to a flat file.
class RawPCHContainerGenerator : public ASTConsumer {
std::shared_ptr<PCHBuffer> Buffer;
std::unique_ptr<raw_pwrite_stream> OS;
diff --git a/lib/Frontend/PrecompiledPreamble.cpp b/lib/Frontend/PrecompiledPreamble.cpp
index 7e1323fd83bb..30ae2db26d86 100644
--- a/lib/Frontend/PrecompiledPreamble.cpp
+++ b/lib/Frontend/PrecompiledPreamble.cpp
@@ -40,7 +40,7 @@ namespace {
StringRef getInMemoryPreamblePath() {
#if defined(LLVM_ON_UNIX)
return "/__clang_tmp/___clang_inmemory_preamble___";
-#elif defined(LLVM_ON_WIN32)
+#elif defined(_WIN32)
return "C:\\__clang_tmp\\___clang_inmemory_preamble___";
#else
#warning "Unknown platform. Defaulting to UNIX-style paths for in-memory PCHs"
@@ -63,6 +63,16 @@ createVFSOverlayForPreamblePCH(StringRef PCHFilename,
return Overlay;
}
+class PreambleDependencyCollector : public DependencyCollector {
+public:
+ // We want to collect all dependencies for correctness. Avoiding the real
+ // system dependencies (e.g. stl from /usr/lib) would probably be a good idea,
+ // but there is no way to distinguish between those and the ones that can be
+ // spuriously added by '-isystem' (e.g. to suppress warnings from those
+ // headers).
+ bool needSystemDependencies() override { return true; }
+};
+
/// Keeps a track of files to be deleted in destructor.
class TemporaryFiles {
public:
@@ -303,8 +313,6 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
VFS =
createVFSFromCompilerInvocation(Clang->getInvocation(), Diagnostics, VFS);
- if (!VFS)
- return BuildPreambleError::CouldntCreateVFSOverlay;
// Create a file manager object to provide access to and cache the filesystem.
Clang->setFileManager(new FileManager(Clang->getFileSystemOpts(), VFS));
@@ -313,7 +321,7 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
Clang->setSourceManager(
new SourceManager(Diagnostics, Clang->getFileManager()));
- auto PreambleDepCollector = std::make_shared<DependencyCollector>();
+ auto PreambleDepCollector = std::make_shared<PreambleDependencyCollector>();
Clang->addDependencyCollector(PreambleDepCollector);
// Remap the main source file to the preamble buffer.
@@ -485,20 +493,15 @@ bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation,
void PrecompiledPreamble::AddImplicitPreamble(
CompilerInvocation &CI, IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
llvm::MemoryBuffer *MainFileBuffer) const {
- assert(VFS && "VFS must not be null");
-
- auto &PreprocessorOpts = CI.getPreprocessorOpts();
-
- // Remap main file to point to MainFileBuffer.
- auto MainFilePath = CI.getFrontendOpts().Inputs[0].getFile();
- PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer);
-
- // Configure ImpicitPCHInclude.
- PreprocessorOpts.PrecompiledPreambleBytes.first = PreambleBytes.size();
- PreprocessorOpts.PrecompiledPreambleBytes.second = PreambleEndsAtStartOfLine;
- PreprocessorOpts.DisablePCHValidation = true;
+ PreambleBounds Bounds(PreambleBytes.size(), PreambleEndsAtStartOfLine);
+ configurePreamble(Bounds, CI, VFS, MainFileBuffer);
+}
- setupPreambleStorage(Storage, PreprocessorOpts, VFS);
+void PrecompiledPreamble::OverridePreamble(
+ CompilerInvocation &CI, IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ llvm::MemoryBuffer *MainFileBuffer) const {
+ auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), MainFileBuffer, 0);
+ configurePreamble(Bounds, CI, VFS, MainFileBuffer);
}
PrecompiledPreamble::PrecompiledPreamble(
@@ -681,6 +684,27 @@ PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer(
return Result;
}
+void PrecompiledPreamble::configurePreamble(
+ PreambleBounds Bounds, CompilerInvocation &CI,
+ IntrusiveRefCntPtr<vfs::FileSystem> &VFS,
+ llvm::MemoryBuffer *MainFileBuffer) const {
+ assert(VFS);
+
+ auto &PreprocessorOpts = CI.getPreprocessorOpts();
+
+ // Remap main file to point to MainFileBuffer.
+ auto MainFilePath = CI.getFrontendOpts().Inputs[0].getFile();
+ PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer);
+
+ // Configure ImpicitPCHInclude.
+ PreprocessorOpts.PrecompiledPreambleBytes.first = Bounds.Size;
+ PreprocessorOpts.PrecompiledPreambleBytes.second =
+ Bounds.PreambleEndsAtStartOfLine;
+ PreprocessorOpts.DisablePCHValidation = true;
+
+ setupPreambleStorage(Storage, PreprocessorOpts, VFS);
+}
+
void PrecompiledPreamble::setupPreambleStorage(
const PCHStorage &Storage, PreprocessorOptions &PreprocessorOpts,
IntrusiveRefCntPtr<vfs::FileSystem> &VFS) {
@@ -740,8 +764,6 @@ std::string BuildPreambleErrorCategory::message(int condition) const {
return "Could not create temporary file for PCH";
case BuildPreambleError::CouldntCreateTargetInfo:
return "CreateTargetInfo() return null";
- case BuildPreambleError::CouldntCreateVFSOverlay:
- return "Could not create VFS Overlay";
case BuildPreambleError::BeginSourceFileFailed:
return "BeginSourceFile() return an error";
case BuildPreambleError::CouldntEmitPCH:
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 2e023294f1e8..1b35b32656e7 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -130,7 +130,8 @@ public:
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override;
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override;
void Ident(SourceLocation Loc, StringRef str) override;
void PragmaMessage(SourceLocation Loc, StringRef Namespace,
PragmaMessageKind Kind, StringRef Str) override;
@@ -320,15 +321,17 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
}
}
-void PrintPPOutputPPCallbacks::InclusionDirective(SourceLocation HashLoc,
- const Token &IncludeTok,
- StringRef FileName,
- bool IsAngled,
- CharSourceRange FilenameRange,
- const FileEntry *File,
- StringRef SearchPath,
- StringRef RelativePath,
- const Module *Imported) {
+void PrintPPOutputPPCallbacks::InclusionDirective(
+ SourceLocation HashLoc,
+ const Token &IncludeTok,
+ StringRef FileName,
+ bool IsAngled,
+ CharSourceRange FilenameRange,
+ const FileEntry *File,
+ StringRef SearchPath,
+ StringRef RelativePath,
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) {
// In -dI mode, dump #include directives prior to dumping their content or
// interpretation.
if (DumpIncludeDirectives) {
@@ -752,7 +755,7 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
} else if (Tok.isLiteral() && !Tok.needsCleaning() &&
Tok.getLiteralData()) {
OS.write(Tok.getLiteralData(), Tok.getLength());
- } else if (Tok.getLength() < 256) {
+ } else if (Tok.getLength() < llvm::array_lengthof(Buffer)) {
const char *TokPtr = Buffer;
unsigned Len = PP.getSpelling(Tok, TokPtr);
OS.write(TokPtr, Len);
diff --git a/lib/Frontend/Rewrite/FixItRewriter.cpp b/lib/Frontend/Rewrite/FixItRewriter.cpp
index dc787ac9557c..64785e301236 100644
--- a/lib/Frontend/Rewrite/FixItRewriter.cpp
+++ b/lib/Frontend/Rewrite/FixItRewriter.cpp
@@ -1,4 +1,4 @@
-//===--- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --*- C++ -*-===//
+//===- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,28 +14,32 @@
//===----------------------------------------------------------------------===//
#include "clang/Rewrite/Frontend/FixItRewriter.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Edit/Commit.h"
#include "clang/Edit/EditsReceiver.h"
#include "clang/Frontend/FrontendDiagnostic.h"
-#include "llvm/Support/Path.h"
+#include "clang/Rewrite/Core/RewriteBuffer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
using namespace clang;
FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
const LangOptions &LangOpts,
FixItOptions *FixItOpts)
- : Diags(Diags),
- Editor(SourceMgr, LangOpts),
- Rewrite(SourceMgr, LangOpts),
- FixItOpts(FixItOpts),
- NumFailures(0),
- PrevDiagSilenced(false) {
+ : Diags(Diags), Editor(SourceMgr, LangOpts), Rewrite(SourceMgr, LangOpts),
+ FixItOpts(FixItOpts) {
Owner = Diags.takeClient();
Client = Diags.getClient();
Diags.setClient(this, false);
@@ -59,20 +63,21 @@ class RewritesReceiver : public edit::EditsReceiver {
Rewriter &Rewrite;
public:
- RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
+ RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) {}
void insert(SourceLocation loc, StringRef text) override {
Rewrite.InsertText(loc, text);
}
+
void replace(CharSourceRange range, StringRef text) override {
Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
}
};
-}
+} // namespace
bool FixItRewriter::WriteFixedFiles(
- std::vector<std::pair<std::string, std::string> > *RewrittenFiles) {
+ std::vector<std::pair<std::string, std::string>> *RewrittenFiles) {
if (NumFailures > 0 && !FixItOpts->FixWhatYouCan) {
Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
return true;
@@ -189,7 +194,7 @@ void FixItRewriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
Diag(Info.getLocation(), diag::note_fixit_applied);
}
-/// \brief Emit a diagnostic via the adapted diagnostic client.
+/// Emit a diagnostic via the adapted diagnostic client.
void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) {
// When producing this diagnostic, we temporarily bypass ourselves,
// clear out any current diagnostic, and let the downstream client
@@ -200,4 +205,4 @@ void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) {
Diags.setClient(this, false);
}
-FixItOptions::~FixItOptions() {}
+FixItOptions::~FixItOptions() = default;
diff --git a/lib/Frontend/Rewrite/HTMLPrint.cpp b/lib/Frontend/Rewrite/HTMLPrint.cpp
index 11e431de0a31..34ee9673cc54 100644
--- a/lib/Frontend/Rewrite/HTMLPrint.cpp
+++ b/lib/Frontend/Rewrite/HTMLPrint.cpp
@@ -86,8 +86,7 @@ void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
// Emit the HTML.
const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
- char *Buffer = (char*)malloc(RewriteBuf.size());
- std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
- Out->write(Buffer, RewriteBuf.size());
- free(Buffer);
+ std::unique_ptr<char[]> Buffer(new char[RewriteBuf.size()]);
+ std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer.get());
+ Out->write(Buffer.get(), RewriteBuf.size());
}
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
index e0477069b340..1631eccd7013 100644
--- a/lib/Frontend/Rewrite/InclusionRewriter.cpp
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -32,8 +32,10 @@ class InclusionRewriter : public PPCallbacks {
struct IncludedFile {
FileID Id;
SrcMgr::CharacteristicKind FileType;
- IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType)
- : Id(Id), FileType(FileType) {}
+ const DirectoryLookup *DirLookup;
+ IncludedFile(FileID Id, SrcMgr::CharacteristicKind FileType,
+ const DirectoryLookup *DirLookup)
+ : Id(Id), FileType(FileType), DirLookup(DirLookup) {}
};
Preprocessor &PP; ///< Used to find inclusion directives.
SourceManager &SM; ///< Used to read and manage source files.
@@ -54,7 +56,8 @@ class InclusionRewriter : public PPCallbacks {
public:
InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers,
bool UseLineDirectives);
- void Process(FileID FileId, SrcMgr::CharacteristicKind FileType);
+ void Process(FileID FileId, SrcMgr::CharacteristicKind FileType,
+ const DirectoryLookup *DirLookup);
void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) {
PredefinesBuffer = Buf;
}
@@ -74,7 +77,8 @@ private:
StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath,
- const Module *Imported) override;
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType) override;
void WriteLineInfo(StringRef Filename, int Line,
SrcMgr::CharacteristicKind FileType,
StringRef Extra = StringRef());
@@ -156,8 +160,9 @@ void InclusionRewriter::FileChanged(SourceLocation Loc,
// we didn't reach this file (eg: the main file) via an inclusion directive
return;
FileID Id = FullSourceLoc(Loc, SM).getFileID();
- auto P = FileIncludes.insert(std::make_pair(
- LastInclusionLocation.getRawEncoding(), IncludedFile(Id, NewFileType)));
+ auto P = FileIncludes.insert(
+ std::make_pair(LastInclusionLocation.getRawEncoding(),
+ IncludedFile(Id, NewFileType, PP.GetCurDirLookup())));
(void)P;
assert(P.second && "Unexpected revisitation of the same include directive");
LastInclusionLocation = SourceLocation();
@@ -188,7 +193,8 @@ void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
const FileEntry * /*File*/,
StringRef /*SearchPath*/,
StringRef /*RelativePath*/,
- const Module *Imported) {
+ const Module *Imported,
+ SrcMgr::CharacteristicKind FileType){
if (Imported) {
auto P = ModuleIncludes.insert(
std::make_pair(HashLoc.getRawEncoding(), Imported));
@@ -408,7 +414,7 @@ bool InclusionRewriter::HandleHasInclude(
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,
+ Filename, SourceLocation(), isAngled, Lookup, CurDir, Includers, nullptr,
nullptr, nullptr, nullptr, nullptr);
FileExists = File != nullptr;
@@ -418,7 +424,8 @@ bool InclusionRewriter::HandleHasInclude(
/// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
/// and including content of included files recursively.
void InclusionRewriter::Process(FileID FileId,
- SrcMgr::CharacteristicKind FileType) {
+ SrcMgr::CharacteristicKind FileType,
+ const DirectoryLookup *DirLookup) {
bool Invalid;
const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid);
assert(!Invalid && "Attempting to process invalid inclusion");
@@ -475,7 +482,7 @@ void InclusionRewriter::Process(FileID FileId,
<< Mod->getFullModuleName(true) << "\n";
// Include and recursively process the file.
- Process(Inc->Id, Inc->FileType);
+ Process(Inc->Id, Inc->FileType, Inc->DirLookup);
if (Mod)
OS << "#pragma clang module end /*"
@@ -532,11 +539,10 @@ void InclusionRewriter::Process(FileID FileId,
// Rewrite __has_include_next(x)
} else if (RawToken.getIdentifierInfo()->isStr(
"__has_include_next")) {
- const DirectoryLookup *Lookup = PP.GetCurDirLookup();
- if (Lookup)
- ++Lookup;
+ if (DirLookup)
+ ++DirLookup;
- if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken,
+ if (!HandleHasInclude(FileId, RawLex, DirLookup, RawToken,
HasFile))
continue;
} else {
@@ -621,7 +627,7 @@ void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
Rewrite->handleModuleBegin(Tok);
} while (Tok.isNot(tok::eof));
Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID()));
- Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User);
- Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);
+ Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User, nullptr);
+ Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User, nullptr);
OS->flush();
}
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 1954b24aedad..52b979c85f15 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -1714,7 +1714,7 @@ Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
else {
DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
elementName = DR->getDecl()->getName();
- ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+ ValueDecl *VD = DR->getDecl();
if (VD->getType()->isObjCQualifiedIdType() ||
VD->getType()->isObjCQualifiedInterfaceType())
// Simply use 'id' for all qualified types.
@@ -2590,7 +2590,7 @@ Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
// cast to NSConstantString *
CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
CK_CPointerToObjCPointerCast, Unop);
@@ -3295,7 +3295,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -3313,7 +3313,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
}
MsgExprs.push_back(SuperRep);
break;
@@ -3389,7 +3389,7 @@ Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -4720,7 +4720,7 @@ Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
return DRE;
Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
VK_LValue, OK_Ordinary,
- DRE->getLocation());
+ DRE->getLocation(), false);
// Need parens to enforce precedence.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
Exp);
@@ -5314,7 +5314,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
UO_AddrOf,
Context->getPointerType(Context->VoidPtrTy),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
InitExprs.push_back(DescRefExpr);
// Add initializers for any closure decl refs.
@@ -5332,7 +5332,8 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation());
+ OK_Ordinary, SourceLocation(),
+ false);
}
} else if (isTopLevelBlockPointerType((*I)->getType())) {
FD = SynthBlockInitFunctionDecl((*I)->getName());
@@ -5348,7 +5349,8 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation());
+ OK_Ordinary, SourceLocation(),
+ false);
}
}
@@ -5388,7 +5390,8 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
if (!isNestedCapturedVar)
Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
Context->getPointerType(Exp->getType()),
- VK_RValue, OK_Ordinary, SourceLocation());
+ VK_RValue, OK_Ordinary, SourceLocation(),
+ false);
Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
InitExprs.push_back(Exp);
}
@@ -5414,7 +5417,7 @@ Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
Context->getPointerType(NewRep->getType()),
- VK_RValue, OK_Ordinary, SourceLocation());
+ VK_RValue, OK_Ordinary, SourceLocation(), false);
NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
NewRep);
// Put Paren around the call.
@@ -6744,9 +6747,9 @@ static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
Ivar->getAccessControl() == ObjCIvarDecl::Package ||
Class->getVisibility() == HiddenVisibility)
- Visibility shoud be: HiddenVisibility;
+ Visibility should be: HiddenVisibility;
else
- Visibility shoud be: DefaultVisibility;
+ Visibility should be: DefaultVisibility;
*/
Result += "\n";
@@ -7558,7 +7561,7 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT,
VK_LValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
PE = new (Context) ParenExpr(OldRange.getBegin(),
OldRange.getEnd(),
Exp);
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index 096b81bc3f08..9938f89eb869 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -1502,7 +1502,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
else {
DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
elementName = DR->getDecl()->getName();
- ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+ ValueDecl *VD = DR->getDecl();
if (VD->getType()->isObjCQualifiedIdType() ||
VD->getType()->isObjCQualifiedInterfaceType())
// Simply use 'id' for all qualified types.
@@ -2511,7 +2511,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
// cast to NSConstantString *
CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
CK_CPointerToObjCPointerCast, Unop);
@@ -2712,7 +2712,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -2730,7 +2730,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
}
MsgExprs.push_back(SuperRep);
break;
@@ -2806,7 +2806,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
Context->getPointerType(SuperRep->getType()),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
SuperRep = NoTypeInfoCStyleCastExpr(Context,
Context->getPointerType(superType),
CK_BitCast, SuperRep);
@@ -3045,7 +3045,7 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
VK_LValue, SourceLocation());
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
Context->getPointerType(DRE->getType()),
- VK_RValue, OK_Ordinary, SourceLocation());
+ VK_RValue, OK_Ordinary, SourceLocation(), false);
CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
CK_BitCast,
DerefExpr);
@@ -3875,7 +3875,7 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
return DRE;
Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
VK_LValue, OK_Ordinary,
- DRE->getLocation());
+ DRE->getLocation(), false);
// Need parens to enforce precedence.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
Exp);
@@ -4438,7 +4438,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
UO_AddrOf,
Context->getPointerType(Context->VoidPtrTy),
VK_RValue, OK_Ordinary,
- SourceLocation());
+ SourceLocation(), false);
InitExprs.push_back(DescRefExpr);
// Add initializers for any closure decl refs.
@@ -4456,7 +4456,8 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation());
+ OK_Ordinary, SourceLocation(),
+ false);
}
} else if (isTopLevelBlockPointerType((*I)->getType())) {
FD = SynthBlockInitFunctionDecl((*I)->getName());
@@ -4472,7 +4473,8 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
QualType QT = (*I)->getType();
QT = Context->getPointerType(QT);
Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
- OK_Ordinary, SourceLocation());
+ OK_Ordinary, SourceLocation(),
+ false);
}
}
InitExprs.push_back(Exp);
@@ -4509,9 +4511,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
// captured nested byref variable has its address passed. Do not take
// its address again.
if (!isNestedCapturedVar)
- Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
- Context->getPointerType(Exp->getType()),
- VK_RValue, OK_Ordinary, SourceLocation());
+ Exp = new (Context) UnaryOperator(
+ Exp, UO_AddrOf, Context->getPointerType(Exp->getType()), VK_RValue,
+ OK_Ordinary, SourceLocation(), false);
Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
InitExprs.push_back(Exp);
}
@@ -4529,7 +4531,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
FType, VK_LValue, SourceLocation());
NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
Context->getPointerType(NewRep->getType()),
- VK_RValue, OK_Ordinary, SourceLocation());
+ VK_RValue, OK_Ordinary, SourceLocation(), false);
NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
NewRep);
BlockDeclRefs.clear();
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index 7666fe10b381..ca60c4812f72 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -162,131 +162,131 @@ public:
void finish() override;
private:
- /// \brief Build a DiagnosticsEngine to emit diagnostics about the diagnostics
+ /// Build a DiagnosticsEngine to emit diagnostics about the diagnostics
DiagnosticsEngine *getMetaDiags();
- /// \brief Remove old copies of the serialized diagnostics. This is necessary
+ /// Remove old copies of the serialized diagnostics. This is necessary
/// so that we can detect when subprocesses write diagnostics that we should
/// merge into our own.
void RemoveOldDiagnostics();
- /// \brief Emit the preamble for the serialized diagnostics.
+ /// Emit the preamble for the serialized diagnostics.
void EmitPreamble();
- /// \brief Emit the BLOCKINFO block.
+ /// Emit the BLOCKINFO block.
void EmitBlockInfoBlock();
- /// \brief Emit the META data block.
+ /// Emit the META data block.
void EmitMetaBlock();
- /// \brief Start a DIAG block.
+ /// Start a DIAG block.
void EnterDiagBlock();
- /// \brief End a DIAG block.
+ /// End a DIAG block.
void ExitDiagBlock();
- /// \brief Emit a DIAG record.
+ /// Emit a DIAG record.
void EmitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
DiagOrStoredDiag D);
- /// \brief Emit FIXIT and SOURCE_RANGE records for a diagnostic.
+ /// Emit FIXIT and SOURCE_RANGE records for a diagnostic.
void EmitCodeContext(SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints,
const SourceManager &SM);
- /// \brief Emit a record for a CharSourceRange.
+ /// Emit a record for a CharSourceRange.
void EmitCharSourceRange(CharSourceRange R, const SourceManager &SM);
- /// \brief Emit the string information for the category.
+ /// Emit the string information for the category.
unsigned getEmitCategory(unsigned category = 0);
- /// \brief Emit the string information for diagnostic flags.
+ /// Emit the string information for diagnostic flags.
unsigned getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel,
unsigned DiagID = 0);
unsigned getEmitDiagnosticFlag(StringRef DiagName);
- /// \brief Emit (lazily) the file string and retrieved the file identifier.
+ /// Emit (lazily) the file string and retrieved the file identifier.
unsigned getEmitFile(const char *Filename);
- /// \brief Add SourceLocation information the specified record.
+ /// Add SourceLocation information the specified record.
void AddLocToRecord(FullSourceLoc Loc, PresumedLoc PLoc,
RecordDataImpl &Record, unsigned TokSize = 0);
- /// \brief Add SourceLocation information the specified record.
+ /// Add SourceLocation information the specified record.
void AddLocToRecord(FullSourceLoc Loc, RecordDataImpl &Record,
unsigned TokSize = 0) {
AddLocToRecord(Loc, Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc(),
Record, TokSize);
}
- /// \brief Add CharSourceRange information the specified record.
+ /// Add CharSourceRange information the specified record.
void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record,
const SourceManager &SM);
- /// \brief Language options, which can differ from one clone of this client
+ /// Language options, which can differ from one clone of this client
/// to another.
const LangOptions *LangOpts;
- /// \brief Whether this is the original instance (rather than one of its
+ /// Whether this is the original instance (rather than one of its
/// clones), responsible for writing the file at the end.
bool OriginalInstance;
- /// \brief Whether this instance should aggregate diagnostics that are
+ /// Whether this instance should aggregate diagnostics that are
/// generated from child processes.
bool MergeChildRecords;
- /// \brief State that is shared among the various clones of this diagnostic
+ /// State that is shared among the various clones of this diagnostic
/// consumer.
struct SharedState {
SharedState(StringRef File, DiagnosticOptions *Diags)
: DiagOpts(Diags), Stream(Buffer), OutputFile(File.str()),
EmittedAnyDiagBlocks(false) {}
- /// \brief Diagnostic options.
+ /// Diagnostic options.
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
- /// \brief The byte buffer for the serialized content.
+ /// The byte buffer for the serialized content.
SmallString<1024> Buffer;
- /// \brief The BitStreamWriter for the serialized diagnostics.
+ /// The BitStreamWriter for the serialized diagnostics.
llvm::BitstreamWriter Stream;
- /// \brief The name of the diagnostics file.
+ /// The name of the diagnostics file.
std::string OutputFile;
- /// \brief The set of constructed record abbreviations.
+ /// The set of constructed record abbreviations.
AbbreviationMap Abbrevs;
- /// \brief A utility buffer for constructing record content.
+ /// A utility buffer for constructing record content.
RecordData Record;
- /// \brief A text buffer for rendering diagnostic text.
+ /// A text buffer for rendering diagnostic text.
SmallString<256> diagBuf;
- /// \brief The collection of diagnostic categories used.
+ /// The collection of diagnostic categories used.
llvm::DenseSet<unsigned> Categories;
- /// \brief The collection of files used.
+ /// The collection of files used.
llvm::DenseMap<const char *, unsigned> Files;
typedef llvm::DenseMap<const void *, std::pair<unsigned, StringRef> >
DiagFlagsTy;
- /// \brief Map for uniquing strings.
+ /// Map for uniquing strings.
DiagFlagsTy DiagFlags;
- /// \brief Whether we have already started emission of any DIAG blocks. Once
+ /// Whether we have already started emission of any DIAG blocks. Once
/// this becomes \c true, we never close a DIAG block until we know that we're
/// starting another one or we're done.
bool EmittedAnyDiagBlocks;
- /// \brief Engine for emitting diagnostics about the diagnostics.
+ /// Engine for emitting diagnostics about the diagnostics.
std::unique_ptr<DiagnosticsEngine> MetaDiagnostics;
};
- /// \brief State shared among the various clones of this diagnostic consumer.
+ /// State shared among the various clones of this diagnostic consumer.
std::shared_ptr<SharedState> State;
};
} // end anonymous namespace
@@ -305,7 +305,7 @@ create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords) {
// Serialization methods.
//===----------------------------------------------------------------------===//
-/// \brief Emits a block ID in the BLOCKINFO block.
+/// Emits a block ID in the BLOCKINFO block.
static void EmitBlockID(unsigned ID, const char *Name,
llvm::BitstreamWriter &Stream,
RecordDataImpl &Record) {
@@ -325,7 +325,7 @@ static void EmitBlockID(unsigned ID, const char *Name,
Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
}
-/// \brief Emits a record ID in the BLOCKINFO block.
+/// Emits a record ID in the BLOCKINFO block.
static void EmitRecordID(unsigned ID, const char *Name,
llvm::BitstreamWriter &Stream,
RecordDataImpl &Record){
@@ -395,7 +395,7 @@ void SDiagsWriter::EmitCharSourceRange(CharSourceRange R,
State->Record);
}
-/// \brief Emits the preamble of the diagnostics file.
+/// Emits the preamble of the diagnostics file.
void SDiagsWriter::EmitPreamble() {
// Emit the file header.
State->Stream.Emit((unsigned)'D', 8);
@@ -462,7 +462,7 @@ void SDiagsWriter::EmitBlockInfoBlock() {
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Diagnostc text.
Abbrevs.set(RECORD_DIAG, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
- // Emit abbrevation for RECORD_CATEGORY.
+ // Emit abbreviation for RECORD_CATEGORY.
Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(RECORD_CATEGORY));
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Category ID.
@@ -470,7 +470,7 @@ void SDiagsWriter::EmitBlockInfoBlock() {
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Category text.
Abbrevs.set(RECORD_CATEGORY, Stream.EmitBlockInfoAbbrev(BLOCK_DIAG, Abbrev));
- // Emit abbrevation for RECORD_SOURCE_RANGE.
+ // Emit abbreviation for RECORD_SOURCE_RANGE.
Abbrev = std::make_shared<BitCodeAbbrev>();
Abbrev->Add(BitCodeAbbrevOp(RECORD_SOURCE_RANGE));
AddRangeLocationAbbrev(*Abbrev);
diff --git a/lib/Frontend/SerializedDiagnosticReader.cpp b/lib/Frontend/SerializedDiagnosticReader.cpp
index 08b7087fbad6..458717819c41 100644
--- a/lib/Frontend/SerializedDiagnosticReader.cpp
+++ b/lib/Frontend/SerializedDiagnosticReader.cpp
@@ -1,4 +1,4 @@
-//===--- SerializedDiagnosticReader.cpp - Reads diagnostics ---------------===//
+//===- SerializedDiagnosticReader.cpp - Reads diagnostics -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,11 +9,22 @@
#include "clang/Frontend/SerializedDiagnosticReader.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
#include "clang/Frontend/SerializedDiagnostics.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitCodes.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/ManagedStatic.h"
+#include <cstdint>
+#include <system_error>
using namespace clang;
-using namespace clang::serialized_diags;
+using namespace serialized_diags;
std::error_code SerializedDiagnosticReader::readDiagnostics(StringRef File) {
// Open the diagnostics file.
@@ -44,13 +55,12 @@ std::error_code SerializedDiagnosticReader::readDiagnostics(StringRef File) {
std::error_code EC;
switch (Stream.ReadSubBlockID()) {
- case llvm::bitc::BLOCKINFO_BLOCK_ID: {
+ case llvm::bitc::BLOCKINFO_BLOCK_ID:
BlockInfo = Stream.ReadBlockInfoBlock();
if (!BlockInfo)
return SDError::MalformedBlockInfoBlock;
Stream.setBlockInfo(&*BlockInfo);
continue;
- }
case BLOCK_META:
if ((EC = readMetaBlock(Stream)))
return EC;
@@ -65,7 +75,7 @@ std::error_code SerializedDiagnosticReader::readDiagnostics(StringRef File) {
continue;
}
}
- return std::error_code();
+ return {};
}
enum class SerializedDiagnosticReader::Cursor {
@@ -132,7 +142,7 @@ SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
case Cursor::BlockEnd:
if (!VersionChecked)
return SDError::MissingVersion;
- return std::error_code();
+ return {};
}
SmallVector<uint64_t, 1> Record;
@@ -176,7 +186,7 @@ SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
case Cursor::BlockEnd:
if ((EC = visitEndOfDiagnostic()))
return EC;
- return std::error_code();
+ return {};
case Cursor::Record:
break;
}
@@ -253,12 +263,14 @@ SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
}
namespace {
+
class SDErrorCategoryType final : public std::error_category {
const char *name() const noexcept override {
return "clang.serialized_diags";
}
+
std::string message(int IE) const override {
- SDError E = static_cast<SDError>(IE);
+ auto E = static_cast<SDError>(IE);
switch (E) {
case SDError::CouldNotLoad:
return "Failed to open diagnostics file";
@@ -290,7 +302,8 @@ class SDErrorCategoryType final : public std::error_category {
llvm_unreachable("Unknown error type!");
}
};
-}
+
+} // namespace
static llvm::ManagedStatic<SDErrorCategoryType> ErrorCategory;
const std::error_category &clang::serialized_diags::SDErrorCategory() {
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index 6a72b00c602b..85cd019005da 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -42,7 +42,7 @@ static const enum raw_ostream::Colors fatalColor = raw_ostream::RED;
static const enum raw_ostream::Colors savedColor =
raw_ostream::SAVEDCOLOR;
-/// \brief Add highlights to differences in template strings.
+/// Add highlights to differences in template strings.
static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str,
bool &Normal, bool Bold) {
while (1) {
@@ -63,7 +63,7 @@ static void applyTemplateHighlighting(raw_ostream &OS, StringRef Str,
}
}
-/// \brief Number of spaces to indent when word-wrapping.
+/// Number of spaces to indent when word-wrapping.
const unsigned WordWrapIndentation = 6;
static int bytesSincePreviousTabOrLineBegin(StringRef SourceLine, size_t i) {
@@ -76,7 +76,7 @@ static int bytesSincePreviousTabOrLineBegin(StringRef SourceLine, size_t i) {
return bytes;
}
-/// \brief returns a printable representation of first item from input range
+/// returns a printable representation of first item from input range
///
/// This function returns a printable representation of the next item in a line
/// of source. If the next byte begins a valid and printable character, that
@@ -269,14 +269,14 @@ struct SourceColumnMap {
int columns() const { return m_byteToColumn.back(); }
int bytes() const { return m_columnToByte.back(); }
- /// \brief Map a byte to the column which it is at the start of, or return -1
+ /// Map a byte to the column which it is at the start of, or return -1
/// if it is not at the start of a column (for a UTF-8 trailing byte).
int byteToColumn(int n) const {
assert(0<=n && n<static_cast<int>(m_byteToColumn.size()));
return m_byteToColumn[n];
}
- /// \brief Map a byte to the first column which contains it.
+ /// Map a byte to the first column which contains it.
int byteToContainingColumn(int N) const {
assert(0 <= N && N < static_cast<int>(m_byteToColumn.size()));
while (m_byteToColumn[N] == -1)
@@ -284,7 +284,7 @@ struct SourceColumnMap {
return m_byteToColumn[N];
}
- /// \brief Map a column to the byte which starts the column, or return -1 if
+ /// Map a column to the byte which starts the column, or return -1 if
/// the column the second or subsequent column of an expanded tab or similar
/// multi-column entity.
int columnToByte(int n) const {
@@ -292,14 +292,14 @@ struct SourceColumnMap {
return m_columnToByte[n];
}
- /// \brief Map from a byte index to the next byte which starts a column.
+ /// Map from a byte index to the next byte which starts a column.
int startOfNextColumn(int N) const {
assert(0 <= N && N < static_cast<int>(m_byteToColumn.size() - 1));
while (byteToColumn(++N) == -1) {}
return N;
}
- /// \brief Map from a byte index to the previous byte which starts a column.
+ /// Map from a byte index to the previous byte which starts a column.
int startOfPreviousColumn(int N) const {
assert(0 < N && N < static_cast<int>(m_byteToColumn.size()));
while (byteToColumn(--N) == -1) {}
@@ -317,7 +317,7 @@ private:
};
} // end anonymous namespace
-/// \brief When the source code line we want to print is too long for
+/// When the source code line we want to print is too long for
/// the terminal, select the "interesting" region.
static void selectInterestingSourceRegion(std::string &SourceLine,
std::string &CaretLine,
@@ -507,7 +507,7 @@ static void selectInterestingSourceRegion(std::string &SourceLine,
}
}
-/// \brief Skip over whitespace in the string, starting at the given
+/// Skip over whitespace in the string, starting at the given
/// index.
///
/// \returns The index of the first non-whitespace character that is
@@ -519,7 +519,7 @@ static unsigned skipWhitespace(unsigned Idx, StringRef Str, unsigned Length) {
return Idx;
}
-/// \brief If the given character is the start of some kind of
+/// If the given character is the start of some kind of
/// balanced punctuation (e.g., quotes or parentheses), return the
/// character that will terminate the punctuation.
///
@@ -539,7 +539,7 @@ static inline char findMatchingPunctuation(char c) {
return 0;
}
-/// \brief Find the end of the word starting at the given offset
+/// Find the end of the word starting at the given offset
/// within a string.
///
/// \returns the index pointing one character past the end of the
@@ -596,7 +596,7 @@ static unsigned findEndOfWord(unsigned Start, StringRef Str,
return findEndOfWord(Start + 1, Str, Length, Column + 1, Columns);
}
-/// \brief Print the given string to a stream, word-wrapping it to
+/// Print the given string to a stream, word-wrapping it to
/// some number of columns in the process.
///
/// \param OS the stream to which the word-wrapping string will be
@@ -777,7 +777,7 @@ void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) {
OS << Filename;
}
-/// \brief Print out the file/line/column information and include trace.
+/// Print out the file/line/column information and include trace.
///
/// This method handlen the emission of the diagnostic location information.
/// This includes extracting as much location information as is present for
@@ -852,23 +852,14 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
// Ignore invalid ranges.
if (!RI->isValid()) continue;
- FullSourceLoc B =
- FullSourceLoc(RI->getBegin(), Loc.getManager()).getExpansionLoc();
- FullSourceLoc E =
- FullSourceLoc(RI->getEnd(), Loc.getManager()).getExpansionLoc();
+ auto &SM = Loc.getManager();
+ SourceLocation B = SM.getExpansionLoc(RI->getBegin());
+ CharSourceRange ERange = SM.getExpansionRange(RI->getEnd());
+ SourceLocation E = ERange.getEnd();
+ bool IsTokenRange = ERange.isTokenRange();
- // If the End location and the start location are the same and are a
- // macro location, then the range was something that came from a
- // macro expansion or _Pragma. If this is an object-like macro, the
- // best we can do is to highlight the range. If this is a
- // function-like macro, we'd also like to highlight the arguments.
- if (B == E && RI->getEnd().isMacroID())
- E = FullSourceLoc(RI->getEnd(), Loc.getManager())
- .getExpansionRange()
- .second;
-
- std::pair<FileID, unsigned> BInfo = B.getDecomposedLoc();
- std::pair<FileID, unsigned> EInfo = E.getDecomposedLoc();
+ std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(B);
+ std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(E);
// If the start or end of the range is in another file, just discard
// it.
@@ -878,11 +869,14 @@ void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
// Add in the length of the token, so that we cover multi-char
// tokens.
unsigned TokSize = 0;
- if (RI->isTokenRange())
- TokSize = Lexer::MeasureTokenLength(E, E.getManager(), LangOpts);
-
- OS << '{' << B.getLineNumber() << ':' << B.getColumnNumber() << '-'
- << E.getLineNumber() << ':' << (E.getColumnNumber() + TokSize) << '}';
+ if (IsTokenRange)
+ TokSize = Lexer::MeasureTokenLength(E, SM, LangOpts);
+
+ FullSourceLoc BF(B, SM), EF(E, SM);
+ OS << '{'
+ << BF.getLineNumber() << ':' << BF.getColumnNumber() << '-'
+ << EF.getLineNumber() << ':' << (EF.getColumnNumber() + TokSize)
+ << '}';
PrintedRange = true;
}
@@ -919,7 +913,7 @@ void TextDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc,
OS << "While building module '" << ModuleName << "':\n";
}
-/// \brief Find the suitable set of lines to show to include a set of ranges.
+/// Find the suitable set of lines to show to include a set of ranges.
static llvm::Optional<std::pair<unsigned, unsigned>>
findLinesForRange(const CharSourceRange &R, FileID FID,
const SourceManager &SM) {
@@ -969,7 +963,7 @@ maybeAddRange(std::pair<unsigned, unsigned> A, std::pair<unsigned, unsigned> B,
return A;
}
-/// \brief Highlight a SourceRange (with ~'s) for any characters on LineNo.
+/// Highlight a SourceRange (with ~'s) for any characters on LineNo.
static void highlightRange(const CharSourceRange &R,
unsigned LineNo, FileID FID,
const SourceColumnMap &map,
@@ -1116,7 +1110,7 @@ static std::string buildFixItInsertionLine(FileID FID,
return FixItInsertionLine;
}
-/// \brief Emit a code snippet and caret line.
+/// Emit a code snippet and caret line.
///
/// This routine emits a single line's code snippet and caret line..
///
diff --git a/lib/Frontend/TextDiagnosticBuffer.cpp b/lib/Frontend/TextDiagnosticBuffer.cpp
index 288507310baa..44bb2bc29bc0 100644
--- a/lib/Frontend/TextDiagnosticBuffer.cpp
+++ b/lib/Frontend/TextDiagnosticBuffer.cpp
@@ -1,4 +1,4 @@
-//===--- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics ---------------===//
+//===- TextDiagnosticBuffer.cpp - Buffer Text Diagnostics -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,13 +12,15 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
+
using namespace clang;
/// HandleDiagnostic - Store the errors, warnings, and notes that are
/// reported.
-///
void TextDiagnosticBuffer::HandleDiagnostic(DiagnosticsEngine::Level Level,
const Diagnostic &Info) {
// Default implementation (Warnings/errors count).
@@ -50,25 +52,24 @@ void TextDiagnosticBuffer::HandleDiagnostic(DiagnosticsEngine::Level Level,
}
void TextDiagnosticBuffer::FlushDiagnostics(DiagnosticsEngine &Diags) const {
- for (auto it = All.begin(), ie = All.end(); it != ie; ++it) {
- auto Diag = Diags.Report(Diags.getCustomDiagID(it->first, "%0"));
- switch (it->first) {
+ for (const auto &I : All) {
+ auto Diag = Diags.Report(Diags.getCustomDiagID(I.first, "%0"));
+ switch (I.first) {
default: llvm_unreachable(
"Diagnostic not handled during diagnostic flushing!");
case DiagnosticsEngine::Note:
- Diag << Notes[it->second].second;
+ Diag << Notes[I.second].second;
break;
case DiagnosticsEngine::Warning:
- Diag << Warnings[it->second].second;
+ Diag << Warnings[I.second].second;
break;
case DiagnosticsEngine::Remark:
- Diag << Remarks[it->second].second;
+ Diag << Remarks[I.second].second;
break;
case DiagnosticsEngine::Error:
case DiagnosticsEngine::Fatal:
- Diag << Errors[it->second].second;
+ Diag << Errors[I.second].second;
break;
}
}
}
-
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 5dd3252d5b1e..a37382c116ae 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -44,7 +44,7 @@ void TextDiagnosticPrinter::EndSourceFile() {
TextDiag.reset();
}
-/// \brief Print any diagnostic option information to a raw_ostream.
+/// Print any diagnostic option information to a raw_ostream.
///
/// This implements all of the logic for adding diagnostic options to a message
/// (via OS). Each relevant option is comma separated and all are enclosed in
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 0df5393a309b..21933f474ff5 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -1,4 +1,4 @@
-//===---- VerifyDiagnosticConsumer.cpp - Verifying Diagnostic Client ------===//
+//===- VerifyDiagnosticConsumer.cpp - Verifying Diagnostic Client ---------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,27 +13,48 @@
#include "clang/Frontend/VerifyDiagnosticConsumer.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
using namespace clang;
-typedef VerifyDiagnosticConsumer::Directive Directive;
-typedef VerifyDiagnosticConsumer::DirectiveList DirectiveList;
-typedef VerifyDiagnosticConsumer::ExpectedData ExpectedData;
+
+using Directive = VerifyDiagnosticConsumer::Directive;
+using DirectiveList = VerifyDiagnosticConsumer::DirectiveList;
+using ExpectedData = VerifyDiagnosticConsumer::ExpectedData;
VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_)
- : Diags(Diags_),
- PrimaryClient(Diags.getClient()), PrimaryClientOwner(Diags.takeClient()),
- Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(nullptr),
- LangOpts(nullptr), SrcManager(nullptr), ActiveSourceFiles(0),
- Status(HasNoDirectives)
-{
+ : Diags(Diags_), PrimaryClient(Diags.getClient()),
+ PrimaryClientOwner(Diags.takeClient()),
+ Buffer(new TextDiagnosticBuffer()), Status(HasNoDirectives) {
if (Diags.hasSourceManager())
setSourceManager(Diags.getSourceManager());
}
@@ -48,16 +69,18 @@ VerifyDiagnosticConsumer::~VerifyDiagnosticConsumer() {
}
#ifndef NDEBUG
+
namespace {
+
class VerifyFileTracker : public PPCallbacks {
VerifyDiagnosticConsumer &Verify;
SourceManager &SM;
public:
VerifyFileTracker(VerifyDiagnosticConsumer &Verify, SourceManager &SM)
- : Verify(Verify), SM(SM) { }
+ : Verify(Verify), SM(SM) {}
- /// \brief Hook into the preprocessor and update the list of parsed
+ /// Hook into the preprocessor and update the list of parsed
/// files when the preprocessor indicates a new file is entered.
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
SrcMgr::CharacteristicKind FileType,
@@ -66,7 +89,9 @@ public:
VerifyDiagnosticConsumer::IsParsed);
}
};
-} // End anonymous namespace.
+
+} // namespace
+
#endif
// DiagnosticConsumer interface.
@@ -79,10 +104,10 @@ void VerifyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts,
CurrentPreprocessor = PP;
this->LangOpts = &LangOpts;
setSourceManager(PP->getSourceManager());
- const_cast<Preprocessor*>(PP)->addCommentHandler(this);
+ const_cast<Preprocessor *>(PP)->addCommentHandler(this);
#ifndef NDEBUG
// Debug build tracks parsed files.
- const_cast<Preprocessor*>(PP)->addPPCallbacks(
+ const_cast<Preprocessor *>(PP)->addPPCallbacks(
llvm::make_unique<VerifyFileTracker>(*this, *SrcManager));
#endif
}
@@ -99,7 +124,8 @@ void VerifyDiagnosticConsumer::EndSourceFile() {
// Detach comment handler once last active source file completed.
if (--ActiveSourceFiles == 0) {
if (CurrentPreprocessor)
- const_cast<Preprocessor*>(CurrentPreprocessor)->removeCommentHandler(this);
+ const_cast<Preprocessor *>(CurrentPreprocessor)->
+ removeCommentHandler(this);
// Check diagnostics once last file completed.
CheckDiagnostics();
@@ -152,19 +178,18 @@ void VerifyDiagnosticConsumer::HandleDiagnostic(
// Checking diagnostics implementation.
//===----------------------------------------------------------------------===//
-typedef TextDiagnosticBuffer::DiagList DiagList;
-typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
+using DiagList = TextDiagnosticBuffer::DiagList;
+using const_diag_iterator = TextDiagnosticBuffer::const_iterator;
namespace {
/// StandardDirective - Directive with string matching.
-///
class StandardDirective : public Directive {
public:
StandardDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
bool MatchAnyLine, StringRef Text, unsigned Min,
unsigned Max)
- : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) { }
+ : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max) {}
bool isValid(std::string &Error) override {
// all strings are considered valid; even empty ones
@@ -177,14 +202,13 @@ public:
};
/// RegexDirective - Directive with regular-expression matching.
-///
class RegexDirective : public Directive {
public:
RegexDirective(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max,
StringRef RegexStr)
- : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
- Regex(RegexStr) { }
+ : Directive(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max),
+ Regex(RegexStr) {}
bool isValid(std::string &Error) override {
return Regex.isValid(Error);
@@ -202,7 +226,7 @@ class ParseHelper
{
public:
ParseHelper(StringRef S)
- : Begin(S.begin()), End(S.end()), C(Begin), P(Begin), PEnd(nullptr) {}
+ : Begin(S.begin()), End(S.end()), C(Begin), P(Begin) {}
// Return true if string literal is next.
bool Next(StringRef S) {
@@ -210,7 +234,7 @@ public:
PEnd = C + S.size();
if (PEnd > End)
return false;
- return !memcmp(P, S.data(), S.size());
+ return memcmp(P, S.data(), S.size()) == 0;
}
// Return true if number is next.
@@ -321,16 +345,23 @@ public:
return !(C < End);
}
- const char * const Begin; // beginning of expected content
- const char * const End; // end of expected content (1-past)
- const char *C; // position of next char in content
+ // Beginning of expected content.
+ const char * const Begin;
+
+ // End of expected content (1-past).
+ const char * const End;
+
+ // Position of next char in content.
+ const char *C;
+
const char *P;
private:
- const char *PEnd; // previous next/search subject end (1-past)
+ // Previous next/search subject end (1-past).
+ const char *PEnd = nullptr;
};
-} // namespace anonymous
+} // anonymous
/// ParseDirective - Go through the comment and see if it indicates expected
/// diagnostics. If so, then put them in the appropriate directive list.
@@ -625,7 +656,7 @@ bool VerifyDiagnosticConsumer::HandleComment(Preprocessor &PP,
}
#ifndef NDEBUG
-/// \brief Lex the specified source file to determine whether it contains
+/// Lex the specified source file to determine whether it contains
/// any expected-* directives. As a Lexer is used rather than a full-blown
/// Preprocessor, directives inside skipped #if blocks will still be found.
///
@@ -663,7 +694,7 @@ static bool findDirectives(SourceManager &SM, FileID FID,
}
#endif // !NDEBUG
-/// \brief Takes a list of diagnostics that have been generated but not matched
+/// Takes a list of diagnostics that have been generated but not matched
/// by an expected-* directive and produces a diagnostic to the user from this.
static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceMgr,
const_diag_iterator diag_begin,
@@ -691,7 +722,7 @@ static unsigned PrintUnexpected(DiagnosticsEngine &Diags, SourceManager *SourceM
return std::distance(diag_begin, diag_end);
}
-/// \brief Takes a list of diagnostics that were expected to have been generated
+/// Takes a list of diagnostics that were expected to have been generated
/// but were not and produces a diagnostic to the user from this.
static unsigned PrintExpected(DiagnosticsEngine &Diags,
SourceManager &SourceMgr,
@@ -701,21 +732,20 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
SmallString<256> Fmt;
llvm::raw_svector_ostream OS(Fmt);
- for (auto *DirPtr : DL) {
- Directive &D = *DirPtr;
- if (D.DiagnosticLoc.isInvalid())
+ for (const auto *D : DL) {
+ if (D->DiagnosticLoc.isInvalid())
OS << "\n File *";
else
- OS << "\n File " << SourceMgr.getFilename(D.DiagnosticLoc);
- if (D.MatchAnyLine)
+ OS << "\n File " << SourceMgr.getFilename(D->DiagnosticLoc);
+ if (D->MatchAnyLine)
OS << " Line *";
else
- OS << " Line " << SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
- if (D.DirectiveLoc != D.DiagnosticLoc)
+ OS << " Line " << SourceMgr.getPresumedLineNumber(D->DiagnosticLoc);
+ if (D->DirectiveLoc != D->DiagnosticLoc)
OS << " (directive at "
- << SourceMgr.getFilename(D.DirectiveLoc) << ':'
- << SourceMgr.getPresumedLineNumber(D.DirectiveLoc) << ')';
- OS << ": " << D.Text;
+ << SourceMgr.getFilename(D->DirectiveLoc) << ':'
+ << SourceMgr.getPresumedLineNumber(D->DirectiveLoc) << ')';
+ OS << ": " << D->Text;
}
Diags.Report(diag::err_verify_inconsistent_diags).setForceEmit()
@@ -723,7 +753,7 @@ static unsigned PrintExpected(DiagnosticsEngine &Diags,
return DL.size();
}
-/// \brief Determine whether two source locations come from the same file.
+/// Determine whether two source locations come from the same file.
static bool IsFromSameFile(SourceManager &SM, SourceLocation DirectiveLoc,
SourceLocation DiagnosticLoc) {
while (DiagnosticLoc.isMacroID())
@@ -741,7 +771,6 @@ static bool IsFromSameFile(SourceManager &SM, SourceLocation DirectiveLoc,
/// CheckLists - Compare expected to seen diagnostic lists and return the
/// the difference between them.
-///
static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
const char *Label,
DirectiveList &Left,
@@ -792,7 +821,6 @@ static unsigned CheckLists(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
/// CheckResults - This compares the expected results to those that
/// were actually reported. It emits any discrepencies. Return "true" if there
/// were problems. Return "false" otherwise.
-///
static unsigned CheckResults(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
const TextDiagnosticBuffer &Buffer,
ExpectedData &ED) {
@@ -875,19 +903,16 @@ void VerifyDiagnosticConsumer::CheckDiagnostics() {
// this file is being parsed separately from the main file, in which
// case consider moving the directives to the correct place, if this
// is applicable.
- if (UnparsedFiles.size() > 0) {
+ if (!UnparsedFiles.empty()) {
// Generate a cache of parsed FileEntry pointers for alias lookups.
llvm::SmallPtrSet<const FileEntry *, 8> ParsedFileCache;
- for (ParsedFilesMap::iterator I = ParsedFiles.begin(),
- End = ParsedFiles.end(); I != End; ++I) {
- if (const FileEntry *FE = I->second)
+ for (const auto &I : ParsedFiles)
+ if (const FileEntry *FE = I.second)
ParsedFileCache.insert(FE);
- }
// Iterate through list of unparsed files.
- for (UnparsedFilesMap::iterator I = UnparsedFiles.begin(),
- End = UnparsedFiles.end(); I != End; ++I) {
- const UnparsedFileStatus &Status = I->second;
+ for (const auto &I : UnparsedFiles) {
+ const UnparsedFileStatus &Status = I.second;
const FileEntry *FE = Status.getFile();
// Skip files that have been parsed via an alias.