diff options
Diffstat (limited to 'include/clang/Lex/Preprocessor.h')
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 184 |
1 files changed, 121 insertions, 63 deletions
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index e9095fb..7a912ec 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -14,23 +14,22 @@ #ifndef LLVM_CLANG_LEX_PREPROCESSOR_H #define LLVM_CLANG_LEX_PREPROCESSOR_H -#include "clang/Lex/MacroInfo.h" -#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" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Lexer.h" +#include "clang/Lex/MacroInfo.h" +#include "clang/Lex/PPCallbacks.h" +#include "clang/Lex/PTHLexer.h" +#include "clang/Lex/PTHManager.h" +#include "clang/Lex/TokenLexer.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/ArrayRef.h" #include "llvm/Support/Allocator.h" #include <vector> @@ -84,7 +83,7 @@ public: /// like the \#include stack, token expansion, etc. /// class Preprocessor : public RefCountedBase<Preprocessor> { - llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts; + IntrusiveRefCntPtr<PreprocessorOptions> PPOpts; DiagnosticsEngine *Diags; LangOptions &LangOpts; const TargetInfo *Target; @@ -160,6 +159,12 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief True if pragmas are enabled. bool PragmasEnabled : 1; + /// \brief True if the current build action is a preprocessing action. + bool PreprocessedOutput : 1; + + /// \brief True if we are currently preprocessing a #if or #elif directive + bool ParsingIfOrElifDirective; + /// \brief True if we are pre-expanding macro arguments. bool InMacroArgPreExpansion; @@ -215,8 +220,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { SourceLocation ModuleImportLoc; /// \brief The module import path that we're currently processing. - llvm::SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> - ModuleImportPath; + SmallVector<std::pair<IdentifierInfo *, SourceLocation>, 2> ModuleImportPath; /// \brief Whether the module import expectes an identifier next. Otherwise, /// it expects a '.' or ';'. @@ -291,24 +295,19 @@ 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; + MacroDirective *MD; SourceRange Range; - MacroExpandsInfo(Token Tok, MacroInfo *MI, SourceRange Range) - : Tok(Tok), MI(MI), Range(Range) { } + MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range) + : Tok(Tok), MD(MD), Range(Range) { } }; SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks; /// 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; + llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros; friend class ASTReader; /// \brief Macros that we want to warn because they are not used at the end @@ -343,6 +342,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// should use from the command line etc. std::string Predefines; + /// \brief The file ID for the preprocessor predefines. + FileID PredefinesFileID; + /// TokenLexerCache - Cache macro expanders to reduce malloc traffic. enum { TokenLexerCacheSize = 8 }; unsigned NumCachedTokenLexers; @@ -396,7 +398,7 @@ private: // Cached tokens state. MacroInfoChain *MICache; public: - Preprocessor(llvm::IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, + Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, DiagnosticsEngine &diags, LangOptions &opts, const TargetInfo *target, SourceManager &SM, HeaderSearch &Headers, @@ -447,6 +449,11 @@ public: /// \brief Retrieve the module loader associated with this preprocessor. ModuleLoader &getModuleLoader() const { return TheModuleLoader; } + /// \brief True if we are currently preprocessing a #if or #elif directive + bool isParsingIfOrElifDirective() const { + return ParsingIfOrElifDirective; + } + /// SetCommentRetentionState - Control whether or not the preprocessor retains /// comments in output. void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) { @@ -467,6 +474,16 @@ public: return SuppressIncludeNotFoundError; } + /// Sets whether the preprocessor is responsible for producing output or if + /// it is producing tokens to be consumed by Parse and Sema. + void setPreprocessedOutput(bool IsPreprocessedOutput) { + PreprocessedOutput = IsPreprocessedOutput; + } + + /// Returns true if the preprocessor is responsible for generating output, + /// false if it is producing tokens to be consumed by Parse and Sema. + bool isPreprocessedOutput() const { return PreprocessedOutput; } + /// isCurrentLexer - Return true if we are lexing directly from the specified /// lexer. bool isCurrentLexer(const PreprocessorLexer *L) const { @@ -483,6 +500,9 @@ public: /// expansions going on at the time. PreprocessorLexer *getCurrentFileLexer() const; + /// \brief Returns the file ID for the preprocessor predefines. + FileID getPredefinesFileID() const { return PredefinesFileID; } + /// getPPCallbacks/addPPCallbacks - Accessors for preprocessor callbacks. /// Note that this class takes ownership of any PPCallbacks object given to /// it. @@ -493,53 +513,54 @@ 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 { + /// \brief Given an identifier, return its latest MacroDirective if it is + // \#defined or null if it isn't \#define'd. + MacroDirective *getMacroDirective(IdentifierInfo *II) const { if (!II->hasMacroDefinition()) return 0; - MacroInfo *MI = getMacroInfoHistory(II); - assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!"); - return MI; + MacroDirective *MD = getMacroDirectiveHistory(II); + assert(MD->isDefined() && "Macro is undefined!"); + return MD; + } + + const MacroInfo *getMacroInfo(IdentifierInfo *II) const { + return const_cast<Preprocessor*>(this)->getMacroInfo(II); + } + + MacroInfo *getMacroInfo(IdentifierInfo *II) { + if (MacroDirective *MD = getMacroDirective(II)) + return MD->getMacroInfo(); + return 0; } /// \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; - - /// \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); + MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const; + + /// \brief Add a directive to the macro directive history for this identifier. + void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD); + DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, + SourceLocation Loc, + bool isImported) { + DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc, isImported); + appendMacroDirective(II, MD); + return MD; + } + DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){ + return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), false); + } + /// \brief Set a MacroDirective that was loaded from a PCH file. + void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD); /// 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; + typedef llvm::DenseMap<const IdentifierInfo *, + MacroDirective*>::const_iterator macro_iterator; macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; @@ -611,7 +632,7 @@ public: /// \brief Create a new preprocessing record, which will keep track of /// all macro expansions, macro definitions, etc. - void createPreprocessingRecord(bool RecordConditionalDirectives); + void createPreprocessingRecord(); /// EnterMainSourceFile - Enter the specified FileID as the main source file, /// which implicitly adds the builtin defines etc. @@ -696,6 +717,25 @@ public: void LexAfterModuleImport(Token &Result); + /// \brief Lex a string literal, which may be the concatenation of multiple + /// string literals and may even come from macro expansion. + /// \returns true on success, false if a error diagnostic has been generated. + bool LexStringLiteral(Token &Result, std::string &String, + const char *DiagnosticTag, bool AllowMacroExpansion) { + if (AllowMacroExpansion) + Lex(Result); + else + LexUnexpandedToken(Result); + return FinishLexStringLiteral(Result, String, DiagnosticTag, + AllowMacroExpansion); + } + + /// \brief Complete the lexing of a string literal where the first token has + /// already been lexed (see LexStringLiteral). + bool FinishLexStringLiteral(Token &Result, std::string &String, + const char *DiagnosticTag, + bool AllowMacroExpansion); + /// LexNonComment - Lex a token. If it's a comment, keep lexing until we get /// something not a comment. This is useful in -E -C mode where comments /// would foul up preprocessor directive handling. @@ -901,8 +941,8 @@ public: /// "cleaning", e.g. if it contains trigraphs or escaped newlines /// \param invalid If non-null, will be set \c true if an error occurs. StringRef getSpelling(SourceLocation loc, - SmallVectorImpl<char> &buffer, - bool *invalid = 0) const { + SmallVectorImpl<char> &buffer, + bool *invalid = 0) const { return Lexer::getSpelling(loc, buffer, SourceMgr, LangOpts, invalid); } @@ -939,6 +979,12 @@ public: SmallVectorImpl<char> &Buffer, bool *Invalid = 0) const; + /// \brief Relex the token at the specified location. + /// \returns true if there was a failure, false on success. + bool getRawToken(SourceLocation Loc, Token &Result) { + return Lexer::getRawToken(Loc, Result, SourceMgr, LangOpts); + } + /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant /// with length 1, return the character. char getSpellingOfSingleCharacterNumericConstant(const Token &Tok, @@ -1143,8 +1189,9 @@ public: /// \brief Allocate a new MacroInfo object with the provided SourceLocation. MacroInfo *AllocateMacroInfo(SourceLocation L); - /// \brief Allocate a new MacroInfo object which is clone of \p MI. - MacroInfo *CloneMacroInfo(const MacroInfo &MI); + /// \brief Allocate a new MacroInfo object loaded from an AST file. + MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L, + unsigned SubModuleID); /// \brief Turn the specified lexer token into a fully checked and spelled /// filename, e.g. as an operand of \#include. @@ -1221,6 +1268,13 @@ private: /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); + DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI, + SourceLocation Loc, + bool isImported); + UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc); + VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc, + bool isPublic); + /// \brief Release the specified MacroInfo for re-use. /// /// This memory will be reused for allocating new MacroInfo objects. @@ -1268,7 +1322,7 @@ private: /// HandleMacroExpandedIdentifier - If an identifier token is read that is to /// be expanded as a macro, handle it and return the next token as 'Tok'. If /// the macro should not be expanded return true, otherwise return false. - bool HandleMacroExpandedIdentifier(Token &Tok, MacroInfo *MI); + bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD); /// \brief Cache macro expanded tokens for TokenLexers. // @@ -1312,6 +1366,12 @@ private: /// start getting tokens from it using the PTH cache. void EnterSourceFileWithPTH(PTHLexer *PL, const DirectoryLookup *Dir); + /// \brief Set the file ID for the preprocessor predefines. + void setPredefinesFileID(FileID FID) { + assert(PredefinesFileID.isInvalid() && "PredefinesFileID already set!"); + PredefinesFileID = FID; + } + /// IsFileLexer - Returns true if we are lexing from a file and not a /// pragma or a macro. static bool IsFileLexer(const Lexer* L, const PreprocessorLexer* P) { @@ -1367,8 +1427,6 @@ 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, |