summaryrefslogtreecommitdiff
path: root/include/clang/Lex/Preprocessor.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex/Preprocessor.h')
-rw-r--r--include/clang/Lex/Preprocessor.h128
1 files changed, 104 insertions, 24 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 02e3f1e7e439..e9095fbf44a9 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -18,6 +18,7 @@
#include "clang/Lex/Lexer.h"
#include "clang/Lex/PTHLexer.h"
#include "clang/Lex/PPCallbacks.h"
+#include "clang/Lex/PPMutationListener.h"
#include "clang/Lex/TokenLexer.h"
#include "clang/Lex/PTHManager.h"
#include "clang/Basic/Builtins.h"
@@ -54,6 +55,28 @@ class CodeCompletionHandler;
class DirectoryLookup;
class PreprocessingRecord;
class ModuleLoader;
+class PreprocessorOptions;
+
+/// \brief Stores token information for comparing actual tokens with
+/// predefined values. Only handles simple tokens and identifiers.
+class TokenValue {
+ tok::TokenKind Kind;
+ IdentifierInfo *II;
+
+public:
+ TokenValue(tok::TokenKind Kind) : Kind(Kind), II(0) {
+ assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
+ assert(Kind != tok::identifier &&
+ "Identifiers should be created by TokenValue(IdentifierInfo *)");
+ 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());
+ }
+};
/// Preprocessor - This object engages in a tight little dance with the lexer to
/// efficiently preprocess tokens. Lexers know only about tokens within a
@@ -61,6 +84,7 @@ class ModuleLoader;
/// like the \#include stack, token expansion, etc.
///
class Preprocessor : public RefCountedBase<Preprocessor> {
+ llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
const TargetInfo *Target;
@@ -98,6 +122,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
IdentifierInfo *Ident__has_include; // __has_include
IdentifierInfo *Ident__has_include_next; // __has_include_next
IdentifierInfo *Ident__has_warning; // __has_warning
+ IdentifierInfo *Ident__building_module; // __building_module
+ IdentifierInfo *Ident__MODULE__; // __MODULE__
SourceLocation DATELoc, TIMELoc;
unsigned CounterValue; // Next __COUNTER__ value.
@@ -265,6 +291,11 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
/// encountered (e.g. a file is \#included, etc).
PPCallbacks *Callbacks;
+ /// \brief Listener whose actions are invoked when an entity in the
+ /// preprocessor (e.g., a macro) that was loaded from an AST file is
+ /// later mutated.
+ PPMutationListener *Listener;
+
struct MacroExpandsInfo {
Token Tok;
MacroInfo *MI;
@@ -274,10 +305,12 @@ class Preprocessor : public RefCountedBase<Preprocessor> {
};
SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks;
- /// Macros - For each IdentifierInfo with 'HasMacro' set, we keep a mapping
- /// to the actual definition of the macro.
+ /// Macros - For each IdentifierInfo that was associated with a macro, we
+ /// keep a mapping to the history of all macro definitions and #undefs in
+ /// the reverse order (the latest one is in the head of the list).
llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
-
+ friend class ASTReader;
+
/// \brief Macros that we want to warn because they are not used at the end
/// of the translation unit; we store just their SourceLocations instead
/// something like MacroInfo*. The benefit of this is that when we are
@@ -362,10 +395,9 @@ private: // Cached tokens state.
/// allocation.
MacroInfoChain *MICache;
- MacroInfo *getInfoForMacro(IdentifierInfo *II) const;
-
public:
- Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
+ Preprocessor(llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
+ DiagnosticsEngine &diags, LangOptions &opts,
const TargetInfo *target,
SourceManager &SM, HeaderSearch &Headers,
ModuleLoader &TheModuleLoader,
@@ -382,6 +414,10 @@ public:
/// \param Target Information about the target.
void Initialize(const TargetInfo &Target);
+ /// \brief Retrieve the preprocessor options used to initialize this
+ /// preprocessor.
+ PreprocessorOptions &getPreprocessorOpts() const { return *PPOpts; }
+
DiagnosticsEngine &getDiagnostics() const { return *Diags; }
void setDiagnostics(DiagnosticsEngine &D) { Diags = &D; }
@@ -457,37 +493,70 @@ public:
Callbacks = C;
}
+ /// \brief Attach an preprocessor mutation listener to the preprocessor.
+ ///
+ /// The preprocessor mutation listener provides the ability to track
+ /// modifications to the preprocessor entities committed after they were
+ /// initially created.
+ void setPPMutationListener(PPMutationListener *Listener) {
+ this->Listener = Listener;
+ }
+
+ /// \brief Retrieve a pointer to the preprocessor mutation listener
+ /// associated with this preprocessor, if any.
+ PPMutationListener *getPPMutationListener() const { return Listener; }
+
/// \brief Given an identifier, return the MacroInfo it is \#defined to
/// or null if it isn't \#define'd.
MacroInfo *getMacroInfo(IdentifierInfo *II) const {
if (!II->hasMacroDefinition())
return 0;
- return getInfoForMacro(II);
+ MacroInfo *MI = getMacroInfoHistory(II);
+ assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!");
+ return MI;
}
- /// \brief Specify a macro for this identifier.
- void setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
- bool LoadedFromAST = false);
+ /// \brief Given an identifier, return the (probably #undef'd) MacroInfo
+ /// representing the most recent macro definition. One can iterate over all
+ /// previous macro definitions from it. This method should only be called for
+ /// identifiers that hadMacroDefinition().
+ MacroInfo *getMacroInfoHistory(IdentifierInfo *II) const;
- /// macro_iterator/macro_begin/macro_end - This allows you to walk the current
- /// state of the macro table. This visits every currently-defined macro.
+ /// \brief Specify a macro for this identifier.
+ void setMacroInfo(IdentifierInfo *II, MacroInfo *MI);
+ /// \brief Add a MacroInfo that was loaded from an AST file.
+ void addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI,
+ MacroInfo *Hint = 0);
+ /// \brief Make the given MacroInfo, that was loaded from an AST file and
+ /// previously hidden, visible.
+ void makeLoadedMacroInfoVisible(IdentifierInfo *II, MacroInfo *MI);
+ /// \brief Undefine a macro for this identifier.
+ void clearMacroInfo(IdentifierInfo *II);
+
+ /// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
+ /// history table. Currently defined macros have
+ /// IdentifierInfo::hasMacroDefinition() set and an empty
+ /// MacroInfo::getUndefLoc() at the head of the list.
typedef llvm::DenseMap<IdentifierInfo*,
MacroInfo*>::const_iterator macro_iterator;
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
+ /// \brief Return the name of the macro defined before \p Loc that has
+ /// spelling \p Tokens. If there are multiple macros with same spelling,
+ /// return the last one defined.
+ StringRef getLastMacroWithSpelling(SourceLocation Loc,
+ ArrayRef<TokenValue> Tokens) const;
+
const std::string &getPredefines() const { return Predefines; }
/// setPredefines - Set the predefines for this Preprocessor. These
/// predefines are automatically injected when parsing the main file.
void setPredefines(const char *P) { Predefines = P; }
void setPredefines(const std::string &P) { Predefines = P; }
- /// getIdentifierInfo - Return information about the specified preprocessor
- /// identifier token. The version of this method that takes two character
- /// pointers is preferred unless the identifier is already available as a
- /// string (this avoids allocation and copying of memory to construct an
- /// std::string).
+ /// Return information about the specified preprocessor
+ /// identifier token.
IdentifierInfo *getIdentifierInfo(StringRef Name) const {
return &Identifiers.get(Name);
}
@@ -501,8 +570,8 @@ public:
}
/// RemovePragmaHandler - Remove the specific pragma handler from
- /// the preprocessor. If \arg Namespace is non-null, then it should
- /// be the namespace that \arg Handler was added to. It is an error
+ /// the preprocessor. If \p Namespace is non-null, then it should
+ /// be the namespace that \p Handler was added to. It is an error
/// to remove a handler that has not been registered.
void RemovePragmaHandler(StringRef Namespace, PragmaHandler *Handler);
void RemovePragmaHandler(PragmaHandler *Handler) {
@@ -564,7 +633,8 @@ public:
///
/// ILEnd specifies the location of the ')' for a function-like macro or the
/// identifier for an object-like macro.
- void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroArgs *Args);
+ void EnterMacro(Token &Identifier, SourceLocation ILEnd, MacroInfo *Macro,
+ MacroArgs *Args);
/// EnterTokenStream - Add a "macro" context to the top of the include stack,
/// which will cause the lexer to start returning the specified tokens.
@@ -724,6 +794,14 @@ public:
CachedTokens[CachedLexPos-1] = Tok;
}
+ /// TypoCorrectToken - Update the current token to represent the provided
+ /// identifier, in order to cache an action performed by typo correction.
+ void TypoCorrectToken(const Token &Tok) {
+ assert(Tok.getIdentifierInfo() && "Expected identifier token");
+ if (CachedLexPos != 0 && isBacktrackEnabled())
+ CachedTokens[CachedLexPos-1] = Tok;
+ }
+
/// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
/// CurTokenLexer pointers.
void recomputeCurLexerKind();
@@ -892,7 +970,7 @@ public:
/// CreateString - Plop the specified string into a scratch buffer and set the
/// specified token's location and length to it. If specified, the source
/// location provides a location of the expansion point of the token.
- void CreateString(const char *Buf, unsigned Len, Token &Tok,
+ void CreateString(StringRef Str, Token &Tok,
SourceLocation ExpansionLocStart = SourceLocation(),
SourceLocation ExpansionLocEnd = SourceLocation());
@@ -929,7 +1007,7 @@ public:
/// \brief Returns true if the given MacroID location points at the last
/// token of the macro expansion.
///
- /// \param MacroBegin If non-null and function returns true, it is set to
+ /// \param MacroEnd If non-null and function returns true, it is set to
/// end location of the macro.
bool isAtEndOfMacroExpansion(SourceLocation loc,
SourceLocation *MacroEnd = 0) const {
@@ -1103,10 +1181,10 @@ public:
/// from a macro as multiple tokens, which need to be glued together. This
/// occurs for code like:
/// \code
- /// \#define FOO <a/b.h>
+ /// \#define FOO <x/y.h>
/// \#include FOO
/// \endcode
- /// because in this case, "<a/b.h>" is returned as 7 tokens, not one.
+ /// because in this case, "<x/y.h>" is returned as 7 tokens, not one.
///
/// This code concatenates and consumes tokens up to the '>' token. It
/// returns false if the > was found, otherwise it returns true if it finds
@@ -1289,6 +1367,8 @@ private:
// Macro handling.
void HandleDefineDirective(Token &Tok);
void HandleUndefDirective(Token &Tok);
+ void UndefineMacro(IdentifierInfo *II, MacroInfo *MI,
+ SourceLocation UndefLoc);
// Conditional Inclusion.
void HandleIfdefDirective(Token &Tok, bool isIfndef,