[Frontend] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 328171
This commit is contained in:
Eugene Zelenko 2018-03-22 00:53:26 +00:00
parent 598f3a499d
commit 4f23318118
9 changed files with 417 additions and 299 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}
}
}

View File

@ -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.