mirror of https://github.com/microsoft/clang.git
[Frontend] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328171 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1f4e6039a0
commit
57091d2e94
|
@ -1,4 +1,4 @@
|
|||
//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===//
|
||||
//===- ASTUnit.h - ASTUnit utility ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -16,8 +16,11 @@
|
|||
|
||||
#include "clang-c/Index.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/FileSystemOptions.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/TargetOptions.h"
|
||||
#include "clang/Lex/HeaderSearchOptions.h"
|
||||
|
@ -26,48 +29,59 @@
|
|||
#include "clang/Sema/CodeCompleteConsumer.h"
|
||||
#include "clang/Serialization/ASTBitCodes.h"
|
||||
#include "clang/Frontend/PrecompiledPreamble.h"
|
||||
#include "llvm/ADT/ArrayRef.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/SmallVector.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <sys/types.h>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class MemoryBuffer;
|
||||
}
|
||||
|
||||
class MemoryBuffer;
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
namespace clang {
|
||||
class Sema;
|
||||
|
||||
class ASTContext;
|
||||
class ASTDeserializationListener;
|
||||
class ASTMutationListener;
|
||||
class ASTReader;
|
||||
class CompilerInvocation;
|
||||
class CompilerInstance;
|
||||
class CompilerInvocation;
|
||||
class Decl;
|
||||
class DiagnosticsEngine;
|
||||
class FileEntry;
|
||||
class FileManager;
|
||||
class FrontendAction;
|
||||
class HeaderSearch;
|
||||
class InputKind;
|
||||
class MemoryBufferCache;
|
||||
class Preprocessor;
|
||||
class PreprocessorOptions;
|
||||
class PCHContainerOperations;
|
||||
class PCHContainerReader;
|
||||
class Preprocessor;
|
||||
class PreprocessorOptions;
|
||||
class Sema;
|
||||
class TargetInfo;
|
||||
class FrontendAction;
|
||||
class ASTDeserializationListener;
|
||||
|
||||
namespace vfs {
|
||||
|
||||
class FileSystem;
|
||||
}
|
||||
|
||||
} // namespace vfs
|
||||
|
||||
/// \brief Utility class for loading a ASTContext from an AST file.
|
||||
///
|
||||
class ASTUnit {
|
||||
public:
|
||||
struct StandaloneFixIt {
|
||||
|
@ -83,7 +97,7 @@ public:
|
|||
std::string Message;
|
||||
std::string Filename;
|
||||
unsigned LocOffset;
|
||||
std::vector<std::pair<unsigned, unsigned> > Ranges;
|
||||
std::vector<std::pair<unsigned, unsigned>> Ranges;
|
||||
std::vector<StandaloneFixIt> FixIts;
|
||||
};
|
||||
|
||||
|
@ -101,7 +115,7 @@ private:
|
|||
std::shared_ptr<HeaderSearchOptions> HSOpts;
|
||||
std::shared_ptr<PreprocessorOptions> PPOpts;
|
||||
IntrusiveRefCntPtr<ASTReader> Reader;
|
||||
bool HadModuleLoaderFatalFailure;
|
||||
bool HadModuleLoaderFatalFailure = false;
|
||||
|
||||
struct ASTWriterData;
|
||||
std::unique_ptr<ASTWriterData> WriterData;
|
||||
|
@ -126,22 +140,22 @@ private:
|
|||
// OnlyLocalDecls - when true, walking this AST should only visit declarations
|
||||
// that come from the AST itself, not from included precompiled headers.
|
||||
// FIXME: This is temporary; eventually, CIndex will always do this.
|
||||
bool OnlyLocalDecls;
|
||||
bool OnlyLocalDecls = false;
|
||||
|
||||
/// \brief Whether to capture any diagnostics produced.
|
||||
bool CaptureDiagnostics;
|
||||
bool CaptureDiagnostics = false;
|
||||
|
||||
/// \brief Track whether the main file was loaded from an AST or not.
|
||||
bool MainFileIsAST;
|
||||
|
||||
/// \brief What kind of translation unit this AST represents.
|
||||
TranslationUnitKind TUKind;
|
||||
TranslationUnitKind TUKind = TU_Complete;
|
||||
|
||||
/// \brief Whether we should time each operation.
|
||||
bool WantTiming;
|
||||
|
||||
/// \brief Whether the ASTUnit should delete the remapped buffers.
|
||||
bool OwnsRemappedFileBuffers;
|
||||
bool OwnsRemappedFileBuffers = true;
|
||||
|
||||
/// Track the top-level decls which appeared in an ASTUnit which was loaded
|
||||
/// from a source file.
|
||||
|
@ -153,8 +167,8 @@ private:
|
|||
std::vector<Decl*> TopLevelDecls;
|
||||
|
||||
/// \brief Sorted (by file offset) vector of pairs of file offset/Decl.
|
||||
typedef SmallVector<std::pair<unsigned, Decl *>, 64> LocDeclsTy;
|
||||
typedef llvm::DenseMap<FileID, LocDeclsTy *> FileDeclsTy;
|
||||
using LocDeclsTy = SmallVector<std::pair<unsigned, Decl *>, 64>;
|
||||
using FileDeclsTy = llvm::DenseMap<FileID, LocDeclsTy *>;
|
||||
|
||||
/// \brief Map from FileID to the file-level declarations that it contains.
|
||||
/// The files and decls are only local (and non-preamble) ones.
|
||||
|
@ -179,7 +193,7 @@ private:
|
|||
///
|
||||
/// Diagnostics that come from the driver are retained from one parse to
|
||||
/// the next.
|
||||
unsigned NumStoredDiagnosticsFromDriver;
|
||||
unsigned NumStoredDiagnosticsFromDriver = 0;
|
||||
|
||||
/// \brief Counter that determines when we want to try building a
|
||||
/// precompiled preamble.
|
||||
|
@ -190,7 +204,7 @@ private:
|
|||
/// we'll attempt to rebuild the precompiled header. This way, if
|
||||
/// building the precompiled preamble fails, we won't try again for
|
||||
/// some number of calls.
|
||||
unsigned PreambleRebuildCounter;
|
||||
unsigned PreambleRebuildCounter = 0;
|
||||
|
||||
/// \brief Cache pairs "filename - source location"
|
||||
///
|
||||
|
@ -200,7 +214,6 @@ private:
|
|||
/// of that loading. It must be cleared when preamble is recreated.
|
||||
llvm::StringMap<SourceLocation> PreambleSrcLocCache;
|
||||
|
||||
private:
|
||||
/// The contents of the preamble.
|
||||
llvm::Optional<PrecompiledPreamble> Preamble;
|
||||
|
||||
|
@ -215,7 +228,7 @@ private:
|
|||
/// object when re-using the precompiled preamble. Note that only the
|
||||
/// number of warnings matters, since we will not save the preamble
|
||||
/// when any errors are present.
|
||||
unsigned NumWarningsInPreamble;
|
||||
unsigned NumWarningsInPreamble = 0;
|
||||
|
||||
/// \brief A list of the serialization ID numbers for each of the top-level
|
||||
/// declarations parsed within the precompiled preamble.
|
||||
|
@ -283,7 +296,7 @@ public:
|
|||
|
||||
/// \brief Retrieve the mapping from formatted type names to unique type
|
||||
/// identifiers.
|
||||
llvm::StringMap<unsigned> &getCachedCompletionTypes() {
|
||||
llvm::StringMap<unsigned> &getCachedCompletionTypes() {
|
||||
return CachedCompletionTypes;
|
||||
}
|
||||
|
||||
|
@ -318,18 +331,18 @@ private:
|
|||
///
|
||||
/// This hash value is used to determine when we need to refresh the
|
||||
/// global code-completion cache.
|
||||
unsigned CompletionCacheTopLevelHashValue;
|
||||
unsigned CompletionCacheTopLevelHashValue = 0;
|
||||
|
||||
/// \brief A string hash of the top-level declaration and macro definition
|
||||
/// names processed the last time that we reparsed the precompiled preamble.
|
||||
///
|
||||
/// This hash value is used to determine when we need to refresh the
|
||||
/// global code-completion cache after a rebuild of the precompiled preamble.
|
||||
unsigned PreambleTopLevelHashValue;
|
||||
unsigned PreambleTopLevelHashValue = 0;
|
||||
|
||||
/// \brief The current hash value for the top-level declaration and macro
|
||||
/// definition names
|
||||
unsigned CurrentTopLevelHashValue;
|
||||
unsigned CurrentTopLevelHashValue = 0;
|
||||
|
||||
/// \brief Bit used by CIndex to mark when a translation unit may be in an
|
||||
/// inconsistent state, and is not safe to free.
|
||||
|
@ -342,9 +355,6 @@ private:
|
|||
/// \brief Clear out and deallocate
|
||||
void ClearCachedCompletionResults();
|
||||
|
||||
ASTUnit(const ASTUnit &) = delete;
|
||||
void operator=(const ASTUnit &) = delete;
|
||||
|
||||
explicit ASTUnit(bool MainFileIsAST);
|
||||
|
||||
bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
|
@ -382,21 +392,23 @@ private:
|
|||
ConcurrencyState ConcurrencyCheckValue;
|
||||
|
||||
public:
|
||||
friend class ConcurrencyCheck;
|
||||
|
||||
class ConcurrencyCheck {
|
||||
ASTUnit &Self;
|
||||
|
||||
public:
|
||||
explicit ConcurrencyCheck(ASTUnit &Self)
|
||||
: Self(Self)
|
||||
{
|
||||
explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) {
|
||||
Self.ConcurrencyCheckValue.start();
|
||||
}
|
||||
|
||||
~ConcurrencyCheck() {
|
||||
Self.ConcurrencyCheckValue.finish();
|
||||
}
|
||||
};
|
||||
friend class ConcurrencyCheck;
|
||||
|
||||
ASTUnit(const ASTUnit &) = delete;
|
||||
ASTUnit &operator=(const ASTUnit &) = delete;
|
||||
~ASTUnit();
|
||||
|
||||
bool isMainFileAST() const { return MainFileIsAST; }
|
||||
|
@ -405,22 +417,23 @@ public:
|
|||
void setUnsafeToFree(bool Value) { UnsafeToFree = Value; }
|
||||
|
||||
const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; }
|
||||
DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
|
||||
DiagnosticsEngine &getDiagnostics() { return *Diagnostics; }
|
||||
|
||||
const SourceManager &getSourceManager() const { return *SourceMgr; }
|
||||
SourceManager &getSourceManager() { return *SourceMgr; }
|
||||
SourceManager &getSourceManager() { return *SourceMgr; }
|
||||
|
||||
const Preprocessor &getPreprocessor() const { return *PP; }
|
||||
Preprocessor &getPreprocessor() { return *PP; }
|
||||
Preprocessor &getPreprocessor() { return *PP; }
|
||||
std::shared_ptr<Preprocessor> getPreprocessorPtr() const { return PP; }
|
||||
|
||||
const ASTContext &getASTContext() const { return *Ctx; }
|
||||
ASTContext &getASTContext() { return *Ctx; }
|
||||
ASTContext &getASTContext() { return *Ctx; }
|
||||
|
||||
void setASTContext(ASTContext *ctx) { Ctx = ctx; }
|
||||
void setPreprocessor(std::shared_ptr<Preprocessor> pp);
|
||||
|
||||
bool hasSema() const { return (bool)TheSema; }
|
||||
|
||||
Sema &getSema() const {
|
||||
assert(TheSema && "ASTUnit does not have a Sema object!");
|
||||
return *TheSema;
|
||||
|
@ -442,7 +455,7 @@ public:
|
|||
}
|
||||
|
||||
const FileManager &getFileManager() const { return *FileMgr; }
|
||||
FileManager &getFileManager() { return *FileMgr; }
|
||||
FileManager &getFileManager() { return *FileMgr; }
|
||||
|
||||
const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
|
||||
|
||||
|
@ -465,7 +478,7 @@ public:
|
|||
/// \brief If this ASTUnit came from an AST file, returns the filename for it.
|
||||
StringRef getASTFileName() const;
|
||||
|
||||
typedef std::vector<Decl *>::iterator top_level_iterator;
|
||||
using top_level_iterator = std::vector<Decl *>::iterator;
|
||||
|
||||
top_level_iterator top_level_begin() {
|
||||
assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!");
|
||||
|
@ -549,20 +562,25 @@ public:
|
|||
}
|
||||
|
||||
// Retrieve the diagnostics associated with this AST
|
||||
typedef StoredDiagnostic *stored_diag_iterator;
|
||||
typedef const StoredDiagnostic *stored_diag_const_iterator;
|
||||
using stored_diag_iterator = StoredDiagnostic *;
|
||||
using stored_diag_const_iterator = const StoredDiagnostic *;
|
||||
|
||||
stored_diag_const_iterator stored_diag_begin() const {
|
||||
return StoredDiagnostics.begin();
|
||||
}
|
||||
|
||||
stored_diag_iterator stored_diag_begin() {
|
||||
return StoredDiagnostics.begin();
|
||||
}
|
||||
|
||||
stored_diag_const_iterator stored_diag_end() const {
|
||||
return StoredDiagnostics.end();
|
||||
}
|
||||
|
||||
stored_diag_iterator stored_diag_end() {
|
||||
return StoredDiagnostics.end();
|
||||
}
|
||||
|
||||
unsigned stored_diag_size() const { return StoredDiagnostics.size(); }
|
||||
|
||||
stored_diag_iterator stored_diag_afterDriver_begin() {
|
||||
|
@ -571,8 +589,8 @@ public:
|
|||
return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver;
|
||||
}
|
||||
|
||||
typedef std::vector<CachedCodeCompletionResult>::iterator
|
||||
cached_completion_iterator;
|
||||
using cached_completion_iterator =
|
||||
std::vector<CachedCodeCompletionResult>::iterator;
|
||||
|
||||
cached_completion_iterator cached_completion_begin() {
|
||||
return CachedCompletionResults.begin();
|
||||
|
@ -594,7 +612,7 @@ public:
|
|||
|
||||
/// \brief Type for a function iterating over a number of declarations.
|
||||
/// \returns true to continue iteration and false to abort.
|
||||
typedef bool (*DeclVisitorFn)(void *context, const Decl *D);
|
||||
using DeclVisitorFn = bool (*)(void *context, const Decl *D);
|
||||
|
||||
/// \brief Iterate over local declarations (locally parsed if this is a parsed
|
||||
/// source file or the loaded declarations of the primary module if this is an
|
||||
|
@ -620,7 +638,7 @@ public:
|
|||
|
||||
/// \brief A mapping from a file name to the memory buffer that stores the
|
||||
/// remapped contents of that file.
|
||||
typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile;
|
||||
using RemappedFile = std::pair<std::string, llvm::MemoryBuffer *>;
|
||||
|
||||
/// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation.
|
||||
static std::unique_ptr<ASTUnit>
|
||||
|
@ -631,8 +649,10 @@ public:
|
|||
enum WhatToLoad {
|
||||
/// Load options and the preprocessor state.
|
||||
LoadPreprocessorOnly,
|
||||
|
||||
/// Load the AST, but do not restore Sema state.
|
||||
LoadASTOnly,
|
||||
|
||||
/// Load everything, including Sema.
|
||||
LoadEverything
|
||||
};
|
||||
|
@ -676,7 +696,6 @@ private:
|
|||
IntrusiveRefCntPtr<vfs::FileSystem> VFS);
|
||||
|
||||
public:
|
||||
|
||||
/// \brief Create an ASTUnit from a source file, via a CompilerInvocation
|
||||
/// object, by invoking the optionally provided ASTFrontendAction.
|
||||
///
|
||||
|
@ -853,4 +872,4 @@ public:
|
|||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_FRONTEND_ASTUNIT_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===//
|
||||
//===- DiagnosticRenderer.h - Diagnostic Pretty-Printing --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -17,18 +17,21 @@
|
|||
#define LLVM_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 "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class DiagnosticOptions;
|
||||
class LangOptions;
|
||||
class SourceManager;
|
||||
|
||||
typedef llvm::PointerUnion<const Diagnostic *,
|
||||
const StoredDiagnostic *> DiagOrStoredDiag;
|
||||
using DiagOrStoredDiag =
|
||||
llvm::PointerUnion<const Diagnostic *, const StoredDiagnostic *>;
|
||||
|
||||
/// \brief Class to encapsulate the logic for formatting a diagnostic message.
|
||||
///
|
||||
|
@ -64,7 +67,7 @@ protected:
|
|||
///
|
||||
/// The level of the last diagnostic emitted. Used to detect level changes
|
||||
/// which change the amount of information displayed.
|
||||
DiagnosticsEngine::Level LastLevel;
|
||||
DiagnosticsEngine::Level LastLevel = DiagnosticsEngine::Ignored;
|
||||
|
||||
DiagnosticRenderer(const LangOptions &LangOpts,
|
||||
DiagnosticOptions *DiagOpts);
|
||||
|
@ -97,7 +100,6 @@ protected:
|
|||
virtual void endDiagnostic(DiagOrStoredDiag D,
|
||||
DiagnosticsEngine::Level Level) {}
|
||||
|
||||
|
||||
private:
|
||||
void emitBasicNote(StringRef Message);
|
||||
void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
|
||||
|
@ -142,7 +144,7 @@ class DiagnosticNoteRenderer : public DiagnosticRenderer {
|
|||
public:
|
||||
DiagnosticNoteRenderer(const LangOptions &LangOpts,
|
||||
DiagnosticOptions *DiagOpts)
|
||||
: DiagnosticRenderer(LangOpts, DiagOpts) {}
|
||||
: DiagnosticRenderer(LangOpts, DiagOpts) {}
|
||||
|
||||
~DiagnosticNoteRenderer() override;
|
||||
|
||||
|
@ -156,5 +158,7 @@ public:
|
|||
|
||||
virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0;
|
||||
};
|
||||
} // end clang namespace
|
||||
#endif
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===//
|
||||
//===- FrontendPluginRegistry.h ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -6,6 +6,10 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Pluggable Frontend Action Interface
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
|
||||
#define LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
|
||||
|
@ -16,8 +20,8 @@
|
|||
namespace clang {
|
||||
|
||||
/// The frontend plugin registry.
|
||||
typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry;
|
||||
using FrontendPluginRegistry = llvm::Registry<PluginASTAction>;
|
||||
|
||||
} // end namespace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===//
|
||||
//===- TextDiagnosticBuffer.h - Buffer Text Diagnostics ---------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -15,37 +15,41 @@
|
|||
#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Preprocessor;
|
||||
class SourceManager;
|
||||
|
||||
class TextDiagnosticBuffer : public DiagnosticConsumer {
|
||||
public:
|
||||
typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
|
||||
typedef DiagList::iterator iterator;
|
||||
typedef DiagList::const_iterator const_iterator;
|
||||
using DiagList = std::vector<std::pair<SourceLocation, std::string>>;
|
||||
using iterator = DiagList::iterator;
|
||||
using const_iterator = DiagList::const_iterator;
|
||||
|
||||
private:
|
||||
DiagList Errors, Warnings, Remarks, Notes;
|
||||
|
||||
/// All - All diagnostics in the order in which they were generated. That
|
||||
/// order likely doesn't correspond to user input order, but it at least
|
||||
/// keeps notes in the right places. Each pair in the vector is a diagnostic
|
||||
/// level and an index into the corresponding DiagList above.
|
||||
std::vector<std::pair<DiagnosticsEngine::Level, size_t>> All;
|
||||
|
||||
public:
|
||||
const_iterator err_begin() const { return Errors.begin(); }
|
||||
const_iterator err_end() const { return Errors.end(); }
|
||||
const_iterator err_begin() const { return Errors.begin(); }
|
||||
const_iterator err_end() const { return Errors.end(); }
|
||||
|
||||
const_iterator warn_begin() const { return Warnings.begin(); }
|
||||
const_iterator warn_end() const { return Warnings.end(); }
|
||||
const_iterator warn_end() const { return Warnings.end(); }
|
||||
|
||||
const_iterator remark_begin() const { return Remarks.begin(); }
|
||||
const_iterator remark_end() const { return Remarks.end(); }
|
||||
const_iterator remark_end() const { return Remarks.end(); }
|
||||
|
||||
const_iterator note_begin() const { return Notes.begin(); }
|
||||
const_iterator note_end() const { return Notes.end(); }
|
||||
const_iterator note_end() const { return Notes.end(); }
|
||||
|
||||
void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
|
||||
const Diagnostic &Info) override;
|
||||
|
@ -55,6 +59,6 @@ public:
|
|||
void FlushDiagnostics(DiagnosticsEngine &Diags) const;
|
||||
};
|
||||
|
||||
} // end namspace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H
|
||||
|
|
|
@ -11,18 +11,24 @@
|
|||
#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Lex/Preprocessor.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include <climits>
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class DiagnosticsEngine;
|
||||
class TextDiagnosticBuffer;
|
||||
class FileEntry;
|
||||
class LangOptions;
|
||||
class SourceManager;
|
||||
class TextDiagnosticBuffer;
|
||||
|
||||
/// VerifyDiagnosticConsumer - Create a diagnostic client which will use
|
||||
/// markers in the input source to check that all the emitted diagnostics match
|
||||
|
@ -153,7 +159,7 @@ public:
|
|||
|
||||
public:
|
||||
/// Constant representing n or more matches.
|
||||
static const unsigned MaxCount = UINT_MAX;
|
||||
static const unsigned MaxCount = std::numeric_limits<unsigned>::max();
|
||||
|
||||
SourceLocation DirectiveLoc;
|
||||
SourceLocation DiagnosticLoc;
|
||||
|
@ -161,7 +167,9 @@ public:
|
|||
unsigned Min, Max;
|
||||
bool MatchAnyLine;
|
||||
|
||||
virtual ~Directive() { }
|
||||
Directive(const Directive &) = delete;
|
||||
Directive &operator=(const Directive &) = delete;
|
||||
virtual ~Directive() = default;
|
||||
|
||||
// Returns true if directive text is valid.
|
||||
// Otherwise returns false and populates E.
|
||||
|
@ -173,22 +181,17 @@ public:
|
|||
protected:
|
||||
Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc,
|
||||
bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max)
|
||||
: DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
|
||||
Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
|
||||
assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
|
||||
assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
|
||||
"DiagnosticLoc is invalid!");
|
||||
: DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc),
|
||||
Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) {
|
||||
assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!");
|
||||
assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) &&
|
||||
"DiagnosticLoc is invalid!");
|
||||
}
|
||||
|
||||
private:
|
||||
Directive(const Directive &) = delete;
|
||||
void operator=(const Directive &) = delete;
|
||||
};
|
||||
|
||||
typedef std::vector<std::unique_ptr<Directive>> DirectiveList;
|
||||
using DirectiveList = std::vector<std::unique_ptr<Directive>>;
|
||||
|
||||
/// ExpectedData - owns directive objects and deletes on destructor.
|
||||
///
|
||||
struct ExpectedData {
|
||||
DirectiveList Errors;
|
||||
DirectiveList Warnings;
|
||||
|
@ -215,14 +218,15 @@ private:
|
|||
DiagnosticConsumer *PrimaryClient;
|
||||
std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner;
|
||||
std::unique_ptr<TextDiagnosticBuffer> Buffer;
|
||||
const Preprocessor *CurrentPreprocessor;
|
||||
const LangOptions *LangOpts;
|
||||
SourceManager *SrcManager;
|
||||
unsigned ActiveSourceFiles;
|
||||
const Preprocessor *CurrentPreprocessor = nullptr;
|
||||
const LangOptions *LangOpts = nullptr;
|
||||
SourceManager *SrcManager = nullptr;
|
||||
unsigned ActiveSourceFiles = 0;
|
||||
DirectiveStatus Status;
|
||||
ExpectedData ED;
|
||||
|
||||
void CheckDiagnostics();
|
||||
|
||||
void setSourceManager(SourceManager &SM) {
|
||||
assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
|
||||
SrcManager = &SM;
|
||||
|
@ -231,14 +235,18 @@ private:
|
|||
// These facilities are used for validation in debug builds.
|
||||
class UnparsedFileStatus {
|
||||
llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
|
||||
|
||||
public:
|
||||
UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
|
||||
: Data(File, FoundDirectives) {}
|
||||
: Data(File, FoundDirectives) {}
|
||||
|
||||
const FileEntry *getFile() const { return Data.getPointer(); }
|
||||
bool foundDirectives() const { return Data.getInt(); }
|
||||
};
|
||||
typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
|
||||
typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
|
||||
|
||||
using ParsedFilesMap = llvm::DenseMap<FileID, const FileEntry *>;
|
||||
using UnparsedFilesMap = llvm::DenseMap<FileID, UnparsedFileStatus>;
|
||||
|
||||
ParsedFilesMap ParsedFiles;
|
||||
UnparsedFilesMap UnparsedFiles;
|
||||
|
||||
|
@ -274,6 +282,6 @@ public:
|
|||
const Diagnostic &Info) override;
|
||||
};
|
||||
|
||||
} // end namspace clang
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
||||
#endif // LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H
|
||||
|
|
|
@ -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/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/DJB.h"
|
||||
#include "llvm/Support/Host.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,22 +127,29 @@ 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
|
||||
/// and file-to-buffer remappings inside \p Invocation.
|
||||
|
@ -156,7 +212,6 @@ getBufferForFileHandlingRemapping(const CompilerInvocation &Invocation,
|
|||
return nullptr;
|
||||
return llvm::MemoryBuffer::getMemBufferCopy(Buffer->getBuffer(), FilePath);
|
||||
}
|
||||
}
|
||||
|
||||
struct ASTUnit::ASTWriterData {
|
||||
SmallString<128> Buffer;
|
||||
|
@ -183,20 +238,10 @@ const unsigned DefaultPreambleRebuildInterval = 5;
|
|||
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);
|
||||
}
|
||||
|
@ -278,7 +323,7 @@ static unsigned getDeclShowContexts(const NamedDecl *ND,
|
|||
// 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
|
||||
|
@ -319,7 +364,7 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
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);
|
||||
|
@ -330,7 +375,7 @@ void ASTUnit::CacheCodeCompletionResults() {
|
|||
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;
|
||||
|
@ -470,8 +515,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,7 +525,7 @@ 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 {
|
||||
|
@ -494,16 +539,15 @@ public:
|
|||
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 +601,18 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/// \brief Diagnostic consumer that saves each diagnostic it is given.
|
||||
/// \brief 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.");
|
||||
}
|
||||
|
@ -590,15 +633,15 @@ public:
|
|||
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 +655,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace
|
||||
|
||||
static ASTUnit::StandaloneDiagnostic
|
||||
makeStandaloneDiagnostic(const LangOptions &LangOpts,
|
||||
|
@ -634,7 +677,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();
|
||||
|
@ -693,7 +736,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 +784,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 +837,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) {
|
||||
static void AddDefinedMacroToHash(const Token &MacroNameTok, unsigned &Hash) {
|
||||
Hash = llvm::djbHash(MacroNameTok.getIdentifierInfo()->getName(), Hash);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief 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,8 +858,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
/// \brief Add the given declaration to the hash of all top-level entities.
|
||||
void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
|
||||
static void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
|
||||
if (!D)
|
||||
return;
|
||||
|
||||
|
@ -827,8 +872,8 @@ void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
|
|||
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()) {
|
||||
|
@ -848,8 +893,8 @@ void AddTopLevelDeclarationToHash(Decl *D, unsigned &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::djbHash(ModName, Hash);
|
||||
}
|
||||
|
@ -857,13 +902,15 @@ void AddTopLevelDeclarationToHash(Decl *D, unsigned &Hash) {
|
|||
}
|
||||
}
|
||||
|
||||
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 +933,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 +949,7 @@ public:
|
|||
void HandleInterestingDecl(DeclGroupRef) override {}
|
||||
|
||||
void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
|
||||
for (Decl *TopLevelDecl : D)
|
||||
for (auto *TopLevelDecl : D)
|
||||
handleTopLevelDecl(TopLevelDecl);
|
||||
}
|
||||
|
||||
|
@ -932,6 +979,7 @@ public:
|
|||
TopLevelDeclTrackerAction(ASTUnit &_Unit) : Unit(_Unit) {}
|
||||
|
||||
bool hasCodeCompletionSupport() const override { return false; }
|
||||
|
||||
TranslationUnitKind getTranslationUnitKind() override {
|
||||
return Unit.getTranslationUnitKind();
|
||||
}
|
||||
|
@ -949,7 +997,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 +1006,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 +1029,7 @@ private:
|
|||
llvm::SmallVector<ASTUnit::StandaloneDiagnostic, 4> PreambleDiags;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
} // namespace
|
||||
|
||||
static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
|
||||
return StoredDiag.getLocation().isValid();
|
||||
|
@ -1004,7 +1052,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);
|
||||
|
@ -1192,9 +1240,9 @@ 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;
|
||||
|
@ -1226,7 +1274,6 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
|
|||
const CompilerInvocation &PreambleInvocationIn,
|
||||
IntrusiveRefCntPtr<vfs::FileSystem> VFS, bool AllowRebuild,
|
||||
unsigned MaxLines) {
|
||||
|
||||
auto MainFilePath =
|
||||
PreambleInvocationIn.getFrontendOpts().Inputs[0].getFile();
|
||||
std::unique_ptr<llvm::MemoryBuffer> MainFileBuffer =
|
||||
|
@ -1345,7 +1392,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))
|
||||
|
@ -1389,12 +1436,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();
|
||||
|
@ -1461,7 +1508,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.
|
||||
|
@ -1629,7 +1676,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
|
|||
llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
|
||||
ASTUnitCleanup(AST.get());
|
||||
llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
|
||||
llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
|
||||
DiagCleanup(Diags.get());
|
||||
|
||||
if (AST->LoadFromCompilerInvocation(std::move(PCHContainerOps),
|
||||
|
@ -1658,11 +1705,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;
|
||||
|
@ -1768,7 +1814,6 @@ bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
|||
OverrideMainBuffer =
|
||||
getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation, VFS);
|
||||
|
||||
|
||||
// Clear out the diagnostics state.
|
||||
FileMgr.reset();
|
||||
getDiagnostics().Reset();
|
||||
|
@ -1811,6 +1856,7 @@ void ASTUnit::ResetForParse() {
|
|||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace {
|
||||
|
||||
/// \brief 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
|
||||
|
@ -1822,9 +1868,8 @@ namespace {
|
|||
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
|
||||
|
@ -1866,7 +1911,8 @@ namespace {
|
|||
return Next.getCodeCompletionTUInfo();
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace
|
||||
|
||||
/// \brief Helper function that computes which global names are hidden by the
|
||||
/// local code-completion results.
|
||||
|
@ -1921,7 +1967,7 @@ static void CalculateHiddenNames(const CodeCompletionContext &Context,
|
|||
return;
|
||||
}
|
||||
|
||||
typedef CodeCompletionResult Result;
|
||||
using Result = CodeCompletionResult;
|
||||
for (unsigned I = 0; I != NumResults; ++I) {
|
||||
if (Results[I].Kind != Result::RK_Declaration)
|
||||
continue;
|
||||
|
@ -1963,7 +2009,7 @@ 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
|
||||
C = AST.cached_completion_begin(),
|
||||
|
@ -2259,7 +2305,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,
|
||||
|
@ -2273,7 +2319,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;
|
||||
|
@ -2305,7 +2351,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;
|
||||
|
@ -2488,7 +2534,7 @@ SourceLocation ASTUnit::getEndOfPreambleFileID() const {
|
|||
FID = SourceMgr->getPreambleFileID();
|
||||
|
||||
if (FID.isInvalid())
|
||||
return SourceLocation();
|
||||
return {};
|
||||
|
||||
return SourceMgr->getLocForEndOfFile(FID);
|
||||
}
|
||||
|
@ -2499,7 +2545,7 @@ SourceLocation ASTUnit::getStartOfMainFileID() const {
|
|||
FID = SourceMgr->getMainFileID();
|
||||
|
||||
if (FID.isInvalid())
|
||||
return SourceLocation();
|
||||
return {};
|
||||
|
||||
return SourceMgr->getLocForStartOfFile(FID);
|
||||
}
|
||||
|
@ -2523,7 +2569,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;
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
@ -243,10 +249,10 @@ void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc,
|
|||
/// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,7 +267,7 @@ retrieveMacroLocation(SourceLocation Loc, FileID MacroFileID,
|
|||
if (MacroFileID == CaretFileID)
|
||||
return Loc;
|
||||
if (!Loc.isMacroID())
|
||||
return SourceLocation();
|
||||
return {};
|
||||
|
||||
SourceLocation MacroLocation, MacroArgLocation;
|
||||
|
||||
|
@ -342,11 +348,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);
|
||||
|
@ -466,8 +473,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,10 +488,9 @@ 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;
|
||||
}
|
||||
|
@ -562,7 +569,7 @@ void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc,
|
|||
emitSingleMacroExpansion(*I, Level, Ranges);
|
||||
}
|
||||
|
||||
DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {}
|
||||
DiagnosticNoteRenderer::~DiagnosticNoteRenderer() = default;
|
||||
|
||||
void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc,
|
||||
PresumedLoc PLoc) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,14 +69,16 @@ 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
|
||||
/// files when the preprocessor indicates a new file is entered.
|
||||
|
@ -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.
|
||||
|
@ -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()
|
||||
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue