-//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===//
+//===- MacroInfo.h - Information about #defined identifiers -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::MacroInfo and clang::MacroDirective classes.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_MACROINFO_H
#define LLVM_CLANG_LEX_MACROINFO_H
#include "clang/Lex/Token.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
+#include <algorithm>
#include <cassert>
namespace clang {
+
+class DefMacroDirective;
+class IdentifierInfo;
class Module;
-class ModuleMacro;
class Preprocessor;
+class SourceManager;
/// \brief Encapsulates the data about a macro definition (e.g. its tokens).
///
/// \brief The location the macro is defined.
SourceLocation Location;
+
/// \brief The location of the last token in the macro.
SourceLocation EndLocation;
///
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
- IdentifierInfo **ParameterList;
+ IdentifierInfo **ParameterList = nullptr;
/// \see ParameterList
- unsigned NumParameters;
+ unsigned NumParameters = 0;
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
/// Parameters - The list of parameters for a function-like macro. This can
/// be empty, for, e.g. "#define X()".
- typedef IdentifierInfo *const *param_iterator;
+ using param_iterator = IdentifierInfo *const *;
bool param_empty() const { return NumParameters == 0; }
param_iterator param_begin() const { return ParameterList; }
param_iterator param_end() const { return ParameterList + NumParameters; }
bool isWarnIfUnused() const { return IsWarnIfUnused; }
/// \brief Return the number of tokens that this macro expands to.
- ///
unsigned getNumTokens() const { return ReplacementTokens.size(); }
const Token &getReplacementToken(unsigned Tok) const {
return ReplacementTokens[Tok];
}
- typedef SmallVectorImpl<Token>::const_iterator tokens_iterator;
+ using tokens_iterator = SmallVectorImpl<Token>::const_iterator;
+
tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); }
tokens_iterator tokens_end() const { return ReplacementTokens.end(); }
bool tokens_empty() const { return ReplacementTokens.empty(); }
void dump() const;
private:
- unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
-
friend class Preprocessor;
-};
-class DefMacroDirective;
+ unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
+};
/// \brief Encapsulates changes to the "macros namespace" (the location where
/// the macro name became active, the location where it was undefined, etc.).
/// create additional DefMacroDirectives for the same MacroInfo.
class MacroDirective {
public:
- enum Kind { MD_Define, MD_Undefine, MD_Visibility };
+ enum Kind {
+ MD_Define,
+ MD_Undefine,
+ MD_Visibility
+ };
protected:
- /// \brief Previous macro directive for the same identifier, or NULL.
- MacroDirective *Previous;
+ /// \brief Previous macro directive for the same identifier, or nullptr.
+ MacroDirective *Previous = nullptr;
SourceLocation Loc;
unsigned IsPublic : 1;
MacroDirective(Kind K, SourceLocation Loc)
- : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false),
- IsPublic(true) {}
+ : Loc(Loc), MDKind(K), IsFromPCH(false), IsPublic(true) {}
public:
Kind getKind() const { return Kind(MDKind); }
void setIsFromPCH() { IsFromPCH = true; }
class DefInfo {
- DefMacroDirective *DefDirective;
+ DefMacroDirective *DefDirective = nullptr;
SourceLocation UndefLoc;
- bool IsPublic;
+ bool IsPublic = true;
public:
- DefInfo() : DefDirective(nullptr), IsPublic(true) {}
-
+ DefInfo() = default;
DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc,
bool isPublic)
: DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {}
inline SourceLocation getLocation() const;
inline MacroInfo *getMacroInfo();
+
const MacroInfo *getMacroInfo() const {
return const_cast<DefInfo *>(this)->getMacroInfo();
}
explicit operator bool() const { return isValid(); }
inline DefInfo getPreviousDefinition();
+
const DefInfo getPreviousDefinition() const {
return const_cast<DefInfo *>(this)->getPreviousDefinition();
}
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Define;
}
+
static bool classof(const DefMacroDirective *) { return true; }
};
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Undefine;
}
+
static bool classof(const UndefMacroDirective *) { return true; }
};
static bool classof(const MacroDirective *MD) {
return MD->getKind() == MD_Visibility;
}
+
static bool classof(const VisibilityMacroDirective *) { return true; }
};
inline SourceLocation MacroDirective::DefInfo::getLocation() const {
if (isInvalid())
- return SourceLocation();
+ return {};
return DefDirective->getLocation();
}
inline MacroDirective::DefInfo
MacroDirective::DefInfo::getPreviousDefinition() {
if (isInvalid() || DefDirective->getPrevious() == nullptr)
- return DefInfo();
+ return {};
return DefDirective->getPrevious()->getDefinition();
}
///
/// These are stored in a FoldingSet in the preprocessor.
class ModuleMacro : public llvm::FoldingSetNode {
+ friend class Preprocessor;
+
/// The name defined by the macro.
IdentifierInfo *II;
+
/// The body of the #define, or nullptr if this is a #undef.
MacroInfo *Macro;
+
/// The module that exports this macro.
Module *OwningModule;
+
/// The number of module macros that override this one.
- unsigned NumOverriddenBy;
+ unsigned NumOverriddenBy = 0;
+
/// The number of modules whose macros are directly overridden by this one.
unsigned NumOverrides;
- // ModuleMacro *OverriddenMacros[NumOverrides];
-
- friend class Preprocessor;
ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro,
ArrayRef<ModuleMacro *> Overrides)
- : II(II), Macro(Macro), OwningModule(OwningModule), NumOverriddenBy(0),
+ : II(II), Macro(Macro), OwningModule(OwningModule),
NumOverrides(Overrides.size()) {
std::copy(Overrides.begin(), Overrides.end(),
reinterpret_cast<ModuleMacro **>(this + 1));
void Profile(llvm::FoldingSetNodeID &ID) const {
return Profile(ID, OwningModule, II);
}
+
static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule,
IdentifierInfo *II) {
ID.AddPointer(OwningModule);
/// Iterators over the overridden module IDs.
/// \{
- typedef ModuleMacro *const *overrides_iterator;
+ using overrides_iterator = ModuleMacro *const *;
+
overrides_iterator overrides_begin() const {
return reinterpret_cast<overrides_iterator>(this + 1);
}
+
overrides_iterator overrides_end() const {
return overrides_begin() + NumOverrides;
}
+
ArrayRef<ModuleMacro *> overrides() const {
return llvm::makeArrayRef(overrides_begin(), overrides_end());
}
ArrayRef<ModuleMacro *> ModuleMacros;
public:
- MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {}
+ MacroDefinition() = default;
MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs,
bool IsAmbiguous)
: LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {}
}
};
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_MACROINFO_H
-//===--- Preprocessor.h - C Language Family Preprocessor --------*- C++ -*-===//
+//===- Preprocessor.h - C Language Family Preprocessor ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Defines the clang::Preprocessor interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/ModuleLoader.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Token.h"
#include "clang/Lex/TokenLexer.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Registry.h"
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <memory>
+#include <map>
+#include <string>
+#include <utility>
#include <vector>
namespace llvm {
- template<unsigned InternalLen> class SmallString;
-}
+
+template<unsigned InternalLen> class SmallString;
+
+} // namespace llvm
namespace clang {
-class SourceManager;
+class CodeCompletionHandler;
+class CommentHandler;
+class DirectoryEntry;
+class DirectoryLookup;
class ExternalPreprocessorSource;
-class FileManager;
class FileEntry;
+class FileManager;
class HeaderSearch;
+class MacroArgs;
class MemoryBufferCache;
-class PragmaNamespace;
class PragmaHandler;
-class CommentHandler;
-class ScratchBuffer;
-class TargetInfo;
-class PPCallbacks;
-class CodeCompletionHandler;
-class DirectoryLookup;
+class PragmaNamespace;
class PreprocessingRecord;
-class ModuleLoader;
-class PTHManager;
+class PreprocessorLexer;
class PreprocessorOptions;
+class PTHManager;
+class ScratchBuffer;
+class TargetInfo;
/// \brief Stores token information for comparing actual tokens with
/// predefined values. Only handles simple tokens and identifiers.
assert(!tok::isLiteral(Kind) && "Literals are not supported.");
assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
}
+
TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
+
bool operator==(const Token &Tok) const {
return Tok.getKind() == Kind &&
(!II || II == Tok.getIdentifierInfo());
/// \brief Context in which macro name is used.
enum MacroUse {
- MU_Other = 0, // other than #define or #undef
- MU_Define = 1, // macro name specified in #define
- MU_Undef = 2 // macro name specified in #undef
+ // other than #define or #undef
+ MU_Other = 0,
+
+ // macro name specified in #define
+ MU_Define = 1,
+
+ // macro name specified in #undef
+ MU_Undef = 2
};
/// \brief Engages in a tight little dance with the lexer to efficiently
/// know anything about preprocessor-level issues like the \#include stack,
/// token expansion, etc.
class Preprocessor {
- friend class VariadicMacroScopeGuard;
friend class VAOptDefinitionContext;
+ friend class VariadicMacroScopeGuard;
+
std::shared_ptr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
- const TargetInfo *Target;
- const TargetInfo *AuxTarget;
+ const TargetInfo *Target = nullptr;
+ const TargetInfo *AuxTarget = nullptr;
FileManager &FileMgr;
SourceManager &SourceMgr;
MemoryBufferCache &PCMCache;
/// \brief External source of macros.
ExternalPreprocessorSource *ExternalSource;
-
/// An optional PTHManager object used for getting tokens from
/// a token cache rather than lexing the original source file.
std::unique_ptr<PTHManager> PTH;
IdentifierInfo *Ident__has_declspec; // __has_declspec_attribute
SourceLocation DATELoc, TIMELoc;
- unsigned CounterValue; // Next __COUNTER__ value.
+
+ // Next __COUNTER__ value, starts at 0.
+ unsigned CounterValue = 0;
enum {
/// \brief Maximum depth of \#includes.
/// \brief True if we want to ignore EOF token and continue later on (thus
/// avoid tearing the Lexer and etc. down).
- bool IncrementalProcessing;
+ bool IncrementalProcessing = false;
/// The kind of translation unit we are processing.
TranslationUnitKind TUKind;
/// \brief The code-completion handler.
- CodeCompletionHandler *CodeComplete;
+ CodeCompletionHandler *CodeComplete = nullptr;
/// \brief The file that we're performing code-completion for, if any.
- const FileEntry *CodeCompletionFile;
+ const FileEntry *CodeCompletionFile = nullptr;
/// \brief The offset in file for the code-completion point.
- unsigned CodeCompletionOffset;
+ unsigned CodeCompletionOffset = 0;
/// \brief The location for the code-completion point. This gets instantiated
/// when the CodeCompletionFile gets \#include'ed for preprocessing.
SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath;
/// \brief Whether the last token we lexed was an '@'.
- bool LastTokenWasAt;
+ bool LastTokenWasAt = false;
/// \brief Whether the module import expects an identifier next. Otherwise,
/// it expects a '.' or ';'.
- bool ModuleImportExpectsIdentifier;
+ bool ModuleImportExpectsIdentifier = false;
/// \brief The source location of the currently-active
/// \#pragma clang arc_cf_code_audited begin.
SourceLocation PragmaAssumeNonNullLoc;
/// \brief True if we hit the code-completion point.
- bool CodeCompletionReached;
+ bool CodeCompletionReached = false;
/// \brief The code completion token containing the information
/// on the stem that is to be code completed.
- IdentifierInfo *CodeCompletionII;
+ IdentifierInfo *CodeCompletionII = nullptr;
/// \brief The directory that the main file should be considered to occupy,
/// if it does not correspond to a real file (as happens when building a
/// module).
- const DirectoryEntry *MainFileDir;
+ const DirectoryEntry *MainFileDir = nullptr;
/// \brief The number of bytes that we will initially skip when entering the
/// main file, along with a flag that indicates whether skipping this number
public:
struct PreambleSkipInfo {
+ SourceLocation HashTokenLoc;
+ SourceLocation IfTokenLoc;
+ bool FoundNonSkipPortion;
+ bool FoundElse;
+ SourceLocation ElseLoc;
+
PreambleSkipInfo(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc,
bool FoundNonSkipPortion, bool FoundElse,
SourceLocation ElseLoc)
: HashTokenLoc(HashTokenLoc), IfTokenLoc(IfTokenLoc),
FoundNonSkipPortion(FoundNonSkipPortion), FoundElse(FoundElse),
ElseLoc(ElseLoc) {}
-
- SourceLocation HashTokenLoc;
- SourceLocation IfTokenLoc;
- bool FoundNonSkipPortion;
- bool FoundElse;
- SourceLocation ElseLoc;
};
private:
+ friend class ASTReader;
+ friend class MacroArgs;
+
class PreambleConditionalStackStore {
enum State {
Off = 0,
};
public:
- PreambleConditionalStackStore() : ConditionalStackState(Off) {}
+ PreambleConditionalStackStore() = default;
void startRecording() { ConditionalStackState = Recording; }
void startReplaying() { ConditionalStackState = Replaying; }
private:
SmallVector<PPConditionalInfo, 4> ConditionalStack;
- State ConditionalStackState;
+ State ConditionalStackState = Off;
} PreambleConditionalStack;
/// \brief The current top of the stack that we're lexing from if
/// if not expanding a macro.
///
/// This is an alias for either CurLexer or CurPTHLexer.
- PreprocessorLexer *CurPPLexer;
+ PreprocessorLexer *CurPPLexer = nullptr;
/// \brief Used to find the current FileEntry, if CurLexer is non-null
/// and if applicable.
///
/// This allows us to implement \#include_next and find directory-specific
/// properties.
- const DirectoryLookup *CurDirLookup;
+ const DirectoryLookup *CurDirLookup = nullptr;
/// \brief The current macro we are expanding, if we are expanding a macro.
///
CLK_TokenLexer,
CLK_CachingLexer,
CLK_LexAfterModuleImport
- } CurLexerKind;
+ } CurLexerKind = CLK_Lexer;
/// \brief If the current lexer is for a submodule that is being built, this
/// is that submodule.
- Module *CurLexerSubmodule;
+ Module *CurLexerSubmodule = nullptr;
/// \brief Keeps track of the stack of files currently
/// \#included, and macros currently being expanded from, not counting
Token Tok;
MacroDefinition MD;
SourceRange Range;
+
MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range)
- : Tok(Tok), MD(MD), Range(Range) { }
+ : Tok(Tok), MD(MD), Range(Range) {}
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
/// Information about a name that has been used to define a module macro.
struct ModuleMacroInfo {
- ModuleMacroInfo(MacroDirective *MD)
- : MD(MD), ActiveModuleMacrosGeneration(0), IsAmbiguous(false) {}
-
/// The most recent macro directive for this identifier.
MacroDirective *MD;
+
/// The active module macros for this identifier.
- llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros;
+ llvm::TinyPtrVector<ModuleMacro *> ActiveModuleMacros;
+
/// The generation number at which we last updated ActiveModuleMacros.
/// \see Preprocessor::VisibleModules.
- unsigned ActiveModuleMacrosGeneration;
+ unsigned ActiveModuleMacrosGeneration = 0;
+
/// Whether this macro name is ambiguous.
- bool IsAmbiguous;
+ bool IsAmbiguous = false;
+
/// The module macros that are overridden by this macro.
- llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros;
+ llvm::TinyPtrVector<ModuleMacro *> OverriddenMacros;
+
+ ModuleMacroInfo(MacroDirective *MD) : MD(MD) {}
};
/// The state of a macro for an identifier.
public:
MacroState() : MacroState(nullptr) {}
MacroState(MacroDirective *MD) : State(MD) {}
+
MacroState(MacroState &&O) noexcept : State(O.State) {
O.State = (MacroDirective *)nullptr;
}
+
MacroState &operator=(MacroState &&O) noexcept {
auto S = O.State;
O.State = (MacroDirective *)nullptr;
State = S;
return *this;
}
+
~MacroState() {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
Info->~ModuleMacroInfo();
return Info->MD;
return State.get<MacroDirective*>();
}
+
void setLatest(MacroDirective *MD) {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
Info->MD = MD;
auto *Info = getModuleInfo(PP, II);
return Info ? Info->IsAmbiguous : false;
}
+
ArrayRef<ModuleMacro *>
getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const {
if (auto *Info = getModuleInfo(PP, II))
// FIXME: Incorporate module macros into the result of this.
if (auto *Latest = getLatest())
return Latest->findDirectiveAtLoc(Loc, SourceMgr);
- return MacroDirective::DefInfo();
+ return {};
}
void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) {
Info->IsAmbiguous = false;
}
}
+
ArrayRef<ModuleMacro*> getOverriddenMacros() const {
if (auto *Info = State.dyn_cast<ModuleMacroInfo*>())
return Info->OverriddenMacros;
return None;
}
+
void setOverriddenMacros(Preprocessor &PP,
ArrayRef<ModuleMacro *> Overrides) {
auto *Info = State.dyn_cast<ModuleMacroInfo*>();
/// the reverse order (the latest one is in the head of the list).
///
/// This mapping lives within the \p CurSubmoduleState.
- typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap;
-
- friend class ASTReader;
+ using MacroMap = llvm::DenseMap<const IdentifierInfo *, MacroState>;
struct SubmoduleState;
/// \brief Information about a submodule that we're currently building.
struct BuildingSubmoduleInfo {
- BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
- SubmoduleState *OuterSubmoduleState,
- unsigned OuterPendingModuleMacroNames)
- : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
- OuterSubmoduleState(OuterSubmoduleState),
- OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
-
/// The module that we are building.
Module *M;
+
/// The location at which the module was included.
SourceLocation ImportLoc;
+
/// Whether we entered this submodule via a pragma.
bool IsPragma;
+
/// The previous SubmoduleState.
SubmoduleState *OuterSubmoduleState;
+
/// The number of pending module macro names when we started building this.
unsigned OuterPendingModuleMacroNames;
+
+ BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
+ SubmoduleState *OuterSubmoduleState,
+ unsigned OuterPendingModuleMacroNames)
+ : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
+ OuterSubmoduleState(OuterSubmoduleState),
+ OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
};
SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
struct SubmoduleState {
/// The macros for the submodule.
MacroMap Macros;
+
/// The set of modules that are visible within the submodule.
VisibleModuleSet VisibleModules;
+
// FIXME: CounterValue?
// FIXME: PragmaPushMacroInfo?
};
- std::map<Module*, SubmoduleState> Submodules;
+ std::map<Module *, SubmoduleState> Submodules;
/// The preprocessor state for preprocessing outside of any submodule.
SubmoduleState NullSubmoduleState;
llvm::FoldingSet<ModuleMacro> ModuleMacros;
/// The names of potential module macros that we've not yet processed.
- llvm::SmallVector<const IdentifierInfo*, 32> PendingModuleMacroNames;
+ llvm::SmallVector<const IdentifierInfo *, 32> PendingModuleMacroNames;
/// The list of module macros, for each identifier, that are not overridden by
/// any other module macro.
- llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>>
+ llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro *>>
LeafModuleMacros;
/// \brief Macros that we want to warn because they are not used at the end
/// just so that we can report that they are unused, we just warn using
/// the SourceLocations of this set (that will be filled by the ASTReader).
/// We are using SmallPtrSet instead of a vector for faster removal.
- typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
+ using WarnUnusedMacroLocsTy = llvm::SmallPtrSet<SourceLocation, 32>;
WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
/// \brief A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
- MacroArgs *MacroArgCache;
- friend class MacroArgs;
+ MacroArgs *MacroArgCache = nullptr;
/// For each IdentifierInfo used in a \#pragma push_macro directive,
/// we keep a MacroInfo stack used to restore the previous macro value.
- llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
+ llvm::DenseMap<IdentifierInfo *, std::vector<MacroInfo *>>
+ PragmaPushMacroInfo;
// Various statistics we track for performance analysis.
- unsigned NumDirectives, NumDefined, NumUndefined, NumPragma;
- unsigned NumIf, NumElse, NumEndif;
- unsigned NumEnteredSourceFiles, MaxIncludeStackDepth;
- unsigned NumMacroExpanded, NumFnMacroExpanded, NumBuiltinMacroExpanded;
- unsigned NumFastMacroExpanded, NumTokenPaste, NumFastTokenPaste;
- unsigned NumSkipped;
+ unsigned NumDirectives = 0;
+ unsigned NumDefined = 0;
+ unsigned NumUndefined = 0;
+ unsigned NumPragma = 0;
+ unsigned NumIf = 0;
+ unsigned NumElse = 0;
+ unsigned NumEndif = 0;
+ unsigned NumEnteredSourceFiles = 0;
+ unsigned MaxIncludeStackDepth = 0;
+ unsigned NumMacroExpanded = 0;
+ unsigned NumFnMacroExpanded = 0;
+ unsigned NumBuiltinMacroExpanded = 0;
+ unsigned NumFastMacroExpanded = 0;
+ unsigned NumTokenPaste = 0;
+ unsigned NumFastTokenPaste = 0;
+ unsigned NumSkipped = 0;
/// \brief The predefined macros that preprocessor should use from the
/// command line etc.
/// going to lex in the cache and when it finishes the tokens are removed
/// from the end of the cache.
SmallVector<Token, 16> MacroExpandedTokens;
- std::vector<std::pair<TokenLexer *, size_t> > MacroExpandingLexersStack;
+ std::vector<std::pair<TokenLexer *, size_t>> MacroExpandingLexersStack;
/// \brief A record of the macro definitions and expansions that
/// occurred during preprocessing.
///
/// This is an optional side structure that can be enabled with
/// \c createPreprocessingRecord() prior to preprocessing.
- PreprocessingRecord *Record;
+ PreprocessingRecord *Record = nullptr;
/// Cached tokens state.
- typedef SmallVector<Token, 1> CachedTokensTy;
+ using CachedTokensTy = SmallVector<Token, 1>;
/// \brief Cached tokens are stored here when we do backtracking or
/// lookahead. They are "lexed" by the CachingLex() method.
///
/// If it points beyond the CachedTokens vector, it means that a normal
/// Lex() should be invoked.
- CachedTokensTy::size_type CachedLexPos;
+ CachedTokensTy::size_type CachedLexPos = 0;
/// \brief Stack of backtrack positions, allowing nested backtracks.
///
/// MacroInfos are managed as a chain for easy disposal. This is the head
/// of that list.
- MacroInfoChain *MIChainHead;
+ MacroInfoChain *MIChainHead = nullptr;
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
MacroDefinition getMacroDefinition(const IdentifierInfo *II) {
if (!II->hasMacroDefinition())
- return MacroDefinition();
+ return {};
MacroState &S = CurSubmoduleState->Macros[II];
auto *MD = S.getLatest();
MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II,
SourceLocation Loc) {
if (!II->hadMacroDefinition())
- return MacroDefinition();
+ return {};
MacroState &S = CurSubmoduleState->Macros[II];
MacroDirective::DefInfo DI;
MacroInfo *MI) {
return appendDefMacroDirective(II, MI, MI->getDefinitionLoc());
}
+
/// \brief Set a MacroDirective that was loaded from a PCH file.
void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *ED,
MacroDirective *MD);
/// Iterators for the macro history table. Currently defined macros have
/// IdentifierInfo::hasMacroDefinition() set and an empty
/// MacroInfo::getUndefLoc() at the head of the list.
- typedef MacroMap::const_iterator macro_iterator;
+ using macro_iterator = MacroMap::const_iterator;
+
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
llvm::iterator_range<macro_iterator>
+
macros(bool IncludeExternalMacros = true) const {
return llvm::make_range(macro_begin(IncludeExternalMacros),
macro_end(IncludeExternalMacros));
ArrayRef<TokenValue> Tokens) const;
const std::string &getPredefines() const { return Predefines; }
+
/// \brief Set the predefines for this Preprocessor.
///
/// These predefines are automatically injected when parsing the main file.
bool DisableMacroExpansion) {
EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true);
}
+
void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion) {
EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false);
}
llvm::DenseMap<IdentifierInfo*,unsigned> PoisonReasons;
public:
-
/// \brief Specifies the reason for poisoning an identifier.
///
/// If that identifier is accessed while poisoned, then this reason will be
/// lex again.
bool HandleIdentifier(Token &Identifier);
-
/// \brief Callback invoked when the lexer hits the end of the current file.
///
/// This either returns the EOF token and returns true, or
Module *LeaveSubmodule(bool ForPragma);
private:
+ friend void TokenLexer::ExpandFunctionArguments();
+
void PushIncludeMacroStack() {
assert(CurLexerKind != CLK_CachingLexer && "cannot push a caching lexer");
IncludeMacroStack.emplace_back(CurLexerKind, CurLexerSubmodule,
///
/// Either returns a pointer to a MacroInfo object OR emits a diagnostic and
/// returns a nullptr if an invalid sequence of tokens is encountered.
-
MacroInfo *ReadOptionalMacroParameterListAndBody(
const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
struct DirectiveEvalResult {
/// Whether the expression was evaluated as true or not.
bool Conditional;
+
/// True if the expression contained identifiers that were undefined.
bool IncludedUndefinedIds;
};
/// from the end of the cache.
Token *cacheMacroExpandedTokens(TokenLexer *tokLexer,
ArrayRef<Token> tokens);
+
void removeCachedMacroExpandedTokensOfLastLexer();
- friend void TokenLexer::ExpandFunctionArguments();
/// Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
//===--------------------------------------------------------------------===//
// Caching stuff.
void CachingLex(Token &Result);
+
bool InCachingLexMode() const {
// If the Lexer pointers are 0 and IncludeMacroStack is empty, it means
// that we are past EOF, not that we are in CachingLex mode.
return !CurPPLexer && !CurTokenLexer && !CurPTHLexer &&
!IncludeMacroStack.empty();
}
+
void EnterCachingLexMode();
+
void ExitCachingLexMode() {
if (InCachingLexMode())
RemoveTopOfLexerStack();
}
+
const Token &PeekAhead(unsigned N);
void AnnotatePreviousCachedTokens(const Token &Tok);
// Pragmas.
void HandlePragmaDirective(SourceLocation IntroducerLoc,
PragmaIntroducerKind Introducer);
+
public:
void HandlePragmaOnce(Token &OnceTok);
void HandlePragmaMark();
};
/// \brief Registry of pragma handlers added by plugins
-typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry;
+using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>;
-} // end namespace clang
+} // namespace clang
-#endif
+#endif // LLVM_CLANG_LEX_PREPROCESSOR_H
-//===--- Preprocess.cpp - C Language Family Preprocessor Implementation ---===//
+//===- Preprocess.cpp - C Language Family Preprocessor Implementation -----===//
//
// The LLVM Compiler Infrastructure
//
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/FileSystemStatCache.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/Lexer.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/ModuleLoader.h"
+#include "clang/Lex/PTHLexer.h"
#include "clang/Lex/PTHManager.h"
#include "clang/Lex/Pragma.h"
#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Lex/PreprocessorLexer.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/ScratchBuffer.h"
+#include "clang/Lex/Token.h"
+#include "clang/Lex/TokenLexer.h"
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
LLVM_INSTANTIATE_REGISTRY(PragmaHandlerRegistry)
-//===----------------------------------------------------------------------===//
-ExternalPreprocessorSource::~ExternalPreprocessorSource() { }
+ExternalPreprocessorSource::~ExternalPreprocessorSource() = default;
Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
DiagnosticsEngine &diags, LangOptions &opts,
HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
IdentifierInfoLookup *IILookup, bool OwnsHeaders,
TranslationUnitKind TUKind)
- : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), Target(nullptr),
- AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM),
+ : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts),
+ FileMgr(Headers.getFileMgr()), SourceMgr(SM),
PCMCache(PCMCache), ScratchBuf(new ScratchBuffer(SourceMgr)),
HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
ExternalSource(nullptr), Identifiers(opts, IILookup),
- PragmaHandlers(new PragmaNamespace(StringRef())),
- IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr),
- CodeCompletionFile(nullptr), CodeCompletionOffset(0),
- LastTokenWasAt(false), ModuleImportExpectsIdentifier(false),
- CodeCompletionReached(false), CodeCompletionII(nullptr),
- MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr),
- CurDirLookup(nullptr), CurLexerKind(CLK_Lexer),
- CurLexerSubmodule(nullptr), Callbacks(nullptr),
- CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr),
- Record(nullptr), MIChainHead(nullptr) {
+ PragmaHandlers(new PragmaNamespace(StringRef())), TUKind(TUKind),
+ SkipMainFilePreamble(0, true),
+ CurSubmoduleState(&NullSubmoduleState) {
OwnsHeaderSearch = OwnsHeaders;
- CounterValue = 0; // __COUNTER__ starts at 0.
-
- // Clear stats.
- NumDirectives = NumDefined = NumUndefined = NumPragma = 0;
- NumIf = NumElse = NumEndif = 0;
- NumEnteredSourceFiles = 0;
- NumMacroExpanded = NumFnMacroExpanded = NumBuiltinMacroExpanded = 0;
- NumFastMacroExpanded = NumTokenPaste = NumFastTokenPaste = 0;
- MaxIncludeStackDepth = 0;
- NumSkipped = 0;
-
// Default to discarding comments.
KeepComments = false;
KeepMacroComments = false;
ParsingIfOrElifDirective = false;
PreprocessedOutput = false;
- CachedLexPos = 0;
-
// We haven't read anything from the external source.
ReadMacrosFromExternalSource = false;
Identifier.setIdentifierInfo(II);
if (getLangOpts().MSVCCompat && II->isCPlusPlusOperatorKeyword() &&
getSourceManager().isInSystemHeader(Identifier.getLocation()))
- Identifier.setKind(clang::tok::identifier);
+ Identifier.setKind(tok::identifier);
else
Identifier.setKind(II->getTokenID());
}
void Preprocessor::removeCommentHandler(CommentHandler *Handler) {
- std::vector<CommentHandler *>::iterator Pos
- = std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
+ std::vector<CommentHandler *>::iterator Pos =
+ std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
assert(Pos != CommentHandlers.end() && "Comment handler not registered");
CommentHandlers.erase(Pos);
}
return true;
}
-ModuleLoader::~ModuleLoader() { }
+ModuleLoader::~ModuleLoader() = default;
-CommentHandler::~CommentHandler() { }
+CommentHandler::~CommentHandler() = default;
-CodeCompletionHandler::~CodeCompletionHandler() { }
+CodeCompletionHandler::~CodeCompletionHandler() = default;
void Preprocessor::createPreprocessingRecord() {
if (Record)