aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/ASTUnit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend/ASTUnit.cpp')
-rw-r--r--lib/Frontend/ASTUnit.cpp524
1 files changed, 293 insertions, 231 deletions
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;
}