diff options
Diffstat (limited to 'include/clang/Lex')
-rw-r--r-- | include/clang/Lex/CodeCompletionHandler.h | 67 | ||||
-rw-r--r-- | include/clang/Lex/ExternalPreprocessorSource.h | 2 | ||||
-rw-r--r-- | include/clang/Lex/HeaderSearch.h | 2 | ||||
-rw-r--r-- | include/clang/Lex/Lexer.h | 29 | ||||
-rw-r--r-- | include/clang/Lex/MacroInfo.h | 37 | ||||
-rw-r--r-- | include/clang/Lex/PPCallbacks.h | 10 | ||||
-rw-r--r-- | include/clang/Lex/PTHLexer.h | 2 | ||||
-rw-r--r-- | include/clang/Lex/PreprocessingRecord.h | 3 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 73 | ||||
-rw-r--r-- | include/clang/Lex/Token.h | 1 |
10 files changed, 209 insertions, 17 deletions
diff --git a/include/clang/Lex/CodeCompletionHandler.h b/include/clang/Lex/CodeCompletionHandler.h new file mode 100644 index 0000000..d28a3aa --- /dev/null +++ b/include/clang/Lex/CodeCompletionHandler.h @@ -0,0 +1,67 @@ +//===--- CodeCompletionHandler.h - Preprocessor code completion -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the CodeCompletionHandler interface, which provides +// code-completion callbacks for the preprocessor. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H +#define LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H + +namespace clang { + +class IdentifierInfo; +class MacroInfo; + +/// \brief Callback handler that receives notifications when performing code +/// completion within the preprocessor. +class CodeCompletionHandler { +public: + virtual ~CodeCompletionHandler(); + + /// \brief Callback invoked when performing code completion for a preprocessor + /// directive. + /// + /// This callback will be invoked when the preprocessor processes a '#' at the + /// start of a line, followed by the code-completion token. + /// + /// \param InConditional Whether we're inside a preprocessor conditional + /// already. + virtual void CodeCompleteDirective(bool InConditional) { } + + /// \brief Callback invoked when performing code completion within a block of + /// code that was excluded due to preprocessor conditionals. + virtual void CodeCompleteInConditionalExclusion() { } + + /// \brief Callback invoked when performing code completion in a context + /// where the name of a macro is expected. + /// + /// \param IsDefinition Whether this is the definition of a macro, e.g., + /// in a #define. + virtual void CodeCompleteMacroName(bool IsDefinition) { } + + /// \brief Callback invoked when performing code completion in a preprocessor + /// expression, such as the condition of an #if or #elif directive. + virtual void CodeCompletePreprocessorExpression() { } + + /// \brief Callback invoked when performing code completion inside a + /// function-like macro argument. + virtual void CodeCompleteMacroArgument(IdentifierInfo *Macro, + MacroInfo *MacroInfo, + unsigned ArgumentIndex) { } + + /// \brief Callback invoked when performing code completion in a part of the + /// file where we expect natural language, e.g., a comment, string, or + /// #error directive. + virtual void CodeCompleteNaturalLanguage() { } +}; + +} + +#endif // LLVM_CLANG_LEX_CODECOMPLETIONHANDLER_H diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h index af5c389..791d3fe 100644 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -19,7 +19,7 @@ namespace clang { /// \brief Abstract interface for external sources of preprocessor /// information. /// -/// This abstract class allows an external sources (such as the \c PCHReader) +/// This abstract class allows an external sources (such as the \c ASTReader) /// to provide additional macro definitions. class ExternalPreprocessorSource { public: diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 978585c..80b38de 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -219,7 +219,7 @@ public: header_file_iterator header_file_end() const { return FileInfo.end(); } unsigned header_file_size() const { return FileInfo.size(); } - // Used by PCHReader. + // Used by ASTReader. void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID); void PrintStats(); diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 6a6e319..9e0fb7e 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -219,6 +219,33 @@ public: const SourceManager &SM, const LangOptions &LangOpts); + /// \brief Given a location any where in a source buffer, find the location + /// that corresponds to the beginning of the token in which the original + /// source location lands. + /// + /// \param Loc + static SourceLocation GetBeginningOfToken(SourceLocation Loc, + const SourceManager &SM, + const LangOptions &LangOpts); + + /// \brief Compute the preamble of the given file. + /// + /// The preamble of a file contains the initial comments, include directives, + /// and other preprocessor directives that occur before the code in this + /// particular file actually begins. The preamble of the main source file is + /// a potential prefix header. + /// + /// \param Buffer The memory buffer containing the file's contents. + /// + /// \param MaxLines If non-zero, restrict the length of the preamble + /// to fewer than this number of lines. + /// + /// \returns The offset into the file where the preamble ends and the rest + /// of the file begins along with a boolean value indicating whether + /// the preamble ends at the beginning of a new line. + static std::pair<unsigned, bool> + ComputePreamble(const llvm::MemoryBuffer *Buffer, unsigned MaxLines = 0); + //===--------------------------------------------------------------------===// // Internal implementation interfaces. private: @@ -361,6 +388,8 @@ private: //===--------------------------------------------------------------------===// // Other lexer functions. + void SkipBytes(unsigned Bytes, bool StartOfLine); + // Helper functions to lex the remainder of a token of the specific type. void LexIdentifier (Token &Result, const char *CurPtr); void LexNumericConstant (Token &Result, const char *CurPtr); diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index 5887041..90f95b7 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -62,6 +62,9 @@ class MacroInfo { /// it has not yet been redefined or undefined. bool IsBuiltinMacro : 1; + /// IsFromAST - True if this macro was loaded from an AST file. + bool IsFromAST : 1; + private: //===--------------------------------------------------------------------===// // State that changes as the macro is used. @@ -76,24 +79,28 @@ private: /// emit -Wunused-macros diagnostics. bool IsUsed : 1; - ~MacroInfo() { + /// AllowRedefinitionsWithoutWarning - True if this macro can be redefined + /// without emitting a warning. + bool IsAllowRedefinitionsWithoutWarning : 1; + + ~MacroInfo() { assert(ArgumentList == 0 && "Didn't call destroy before dtor!"); } public: MacroInfo(SourceLocation DefLoc); - + MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator); + /// FreeArgumentList - Free the argument list of the macro, restoring it to a /// state where it can be reused for other devious purposes. - void FreeArgumentList(llvm::BumpPtrAllocator &PPAllocator) { - PPAllocator.Deallocate(ArgumentList); + void FreeArgumentList() { ArgumentList = 0; NumArguments = 0; } /// Destroy - destroy this MacroInfo object. - void Destroy(llvm::BumpPtrAllocator &PPAllocator) { - FreeArgumentList(PPAllocator); + void Destroy() { + FreeArgumentList(); this->~MacroInfo(); } @@ -125,6 +132,12 @@ public: IsUsed = Val; } + /// setIsAllowRedefinitionsWithoutWarning - Set the value of the + /// IsAllowRedefinitionsWithoutWarning flag. + void setIsAllowRedefinitionsWithoutWarning(bool Val) { + IsAllowRedefinitionsWithoutWarning = Val; + } + /// setArgumentList - Set the specified list of identifiers as the argument /// list for this macro. void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs, @@ -172,10 +185,22 @@ public: /// __LINE__, which requires processing before expansion. bool isBuiltinMacro() const { return IsBuiltinMacro; } + /// isFromAST - Return true if this macro was loaded from an AST file. + bool isFromAST() const { return IsFromAST; } + + /// setIsFromAST - Set whether this macro was loaded from an AST file. + void setIsFromAST(bool FromAST = true) { IsFromAST = FromAST; } + /// isUsed - Return false if this macro is defined in the main file and has /// not yet been used. bool isUsed() const { return IsUsed; } + /// isAllowRedefinitionsWithoutWarning - Return true if this macro can be + /// redefined without warning. + bool isAllowRedefinitionsWithoutWarning() const { + return IsAllowRedefinitionsWithoutWarning; + } + /// getNumTokens - Return the number of tokens that this macro expands to. /// unsigned getNumTokens() const { diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 99fe29b..782f2d5 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -89,7 +89,8 @@ public: /// MacroUndefined - This hook is called whenever a macro #undef is seen. /// MI is released immediately following this callback. - virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) { + virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II, + const MacroInfo *MI) { } }; @@ -149,9 +150,10 @@ public: Second->MacroDefined(II, MI); } - virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI) { - First->MacroUndefined(II, MI); - Second->MacroUndefined(II, MI); + virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II, + const MacroInfo *MI) { + First->MacroUndefined(Loc, II, MI); + Second->MacroUndefined(Loc, II, MI); } }; diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h index e96a8c5..0b5a76c 100644 --- a/include/clang/Lex/PTHLexer.h +++ b/include/clang/Lex/PTHLexer.h @@ -50,6 +50,8 @@ class PTHLexer : public PreprocessorLexer { /// ReadToken - Used by PTHLexer to read tokens TokBuf. void ReadToken(Token& T); + + bool LexEndOfFile(Token &Result); /// PTHMgr - The PTHManager object that created this PTHLexer. PTHManager& PTHMgr; diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index ef28af9..730f04f 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -257,7 +257,8 @@ namespace clang { virtual void MacroExpands(const Token &Id, const MacroInfo* MI); virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI); - virtual void MacroUndefined(const IdentifierInfo *II, const MacroInfo *MI); + virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II, + const MacroInfo *MI); }; } // end namespace clang diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 1ee4bb6..6b9b89e 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -42,6 +42,7 @@ class CommentHandler; class ScratchBuffer; class TargetInfo; class PPCallbacks; +class CodeCompletionHandler; class DirectoryLookup; class PreprocessingRecord; @@ -77,7 +78,8 @@ class Preprocessor { IdentifierInfo *Ident__BASE_FILE__; // __BASE_FILE__ IdentifierInfo *Ident__TIMESTAMP__; // __TIMESTAMP__ IdentifierInfo *Ident__COUNTER__; // __COUNTER__ - IdentifierInfo *Ident_Pragma, *Ident__VA_ARGS__; // _Pragma, __VA_ARGS__ + IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma + IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__ IdentifierInfo *Ident__has_feature; // __has_feature IdentifierInfo *Ident__has_builtin; // __has_builtin IdentifierInfo *Ident__has_include; // __has_include @@ -117,7 +119,7 @@ class Preprocessor { /// conceptually similar the IdentifierTable. In addition, the current control /// flow (in clang::ParseAST()), make it convenient to put here. /// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to - /// the lifetime fo the preprocessor. + /// the lifetime of the preprocessor. SelectorTable Selectors; /// BuiltinInfo - Information about builtins. @@ -131,9 +133,18 @@ class Preprocessor { /// with this preprocessor. std::vector<CommentHandler *> CommentHandlers; + /// \brief The code-completion handler. + CodeCompletionHandler *CodeComplete; + /// \brief The file that we're performing code-completion for, if any. const FileEntry *CodeCompletionFile; + /// \brief The number of bytes that we will initially skip when entering the + /// main file, which is used when loading a precompiled preamble, along + /// with a flag that indicates whether skipping this number of bytes will + /// place the lexer at the start of a line. + std::pair<unsigned, bool> SkipMainFilePreamble; + /// CurLexer - This is the current top of the stack that we're lexing from if /// not expanding a macro and we are lexing directly from source code. /// Only one of CurLexer, CurPTHLexer, or CurTokenLexer will be non-null. @@ -192,6 +203,11 @@ class Preprocessor { /// reused for quick allocation. MacroArgs *MacroArgCache; friend class MacroArgs; + + /// PragmaPushMacroInfo - For each IdentifierInfo used in a #pragma + /// push_macro directive, we keep a MacroInfo stack used to restore + /// previous macro value. + llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo; // Various statistics we track for performance analysis. unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma; @@ -362,6 +378,25 @@ public: /// It is an error to remove a handler that has not been registered. void RemoveCommentHandler(CommentHandler *Handler); + /// \brief Set the code completion handler to the given object. + void setCodeCompletionHandler(CodeCompletionHandler &Handler) { + CodeComplete = &Handler; + } + + /// \brief Retrieve the current code-completion handler. + CodeCompletionHandler *getCodeCompletionHandler() const { + return CodeComplete; + } + + /// \brief Clear out the code completion handler. + void clearCodeCompletionHandler() { + CodeComplete = 0; + } + + /// \brief Hook used by the lexer to invoke the "natural language" code + /// completion point. + void CodeCompleteNaturalLanguage(); + /// \brief Retrieve the preprocessing record, or NULL if there is no /// preprocessing record. PreprocessingRecord *getPreprocessingRecord() const { return Record; } @@ -556,6 +591,18 @@ public: /// for which we are performing code completion. bool isCodeCompletionFile(SourceLocation FileLoc) const; + /// \brief Instruct the preprocessor to skip part of the main + /// the main source file. + /// + /// \brief Bytes The number of bytes in the preamble to skip. + /// + /// \brief StartOfLine Whether skipping these bytes puts the lexer at the + /// start of a line. + void setSkipMainFilePreamble(unsigned Bytes, bool StartOfLine) { + SkipMainFilePreamble.first = Bytes; + SkipMainFilePreamble.second = StartOfLine; + } + /// Diag - Forwarding function for diagnostics. This emits a diagnostic at /// the specified Token's location, translating the token's start /// position in the current buffer into a SourcePosition object for rendering. @@ -726,7 +773,10 @@ public: /// AllocateMacroInfo - Allocate a new MacroInfo object with the provide /// SourceLocation. - MacroInfo* AllocateMacroInfo(SourceLocation L); + MacroInfo *AllocateMacroInfo(SourceLocation L); + + /// CloneMacroInfo - Allocate a new MacroInfo object which is clone of MI. + MacroInfo *CloneMacroInfo(const MacroInfo &MI); /// GetIncludeFilenameSpelling - Turn the specified lexer token into a fully /// checked and spelled filename, e.g. as an operand of #include. This returns @@ -784,6 +834,9 @@ private: IncludeMacroStack.pop_back(); } + /// AllocateMacroInfo - Allocate a new MacroInfo object. + MacroInfo *AllocateMacroInfo(); + /// ReleaseMacroInfo - Release the specified MacroInfo. This memory will /// be reused for allocating new MacroInfo objects. void ReleaseMacroInfo(MacroInfo* MI); @@ -852,6 +905,13 @@ private: /// been read into 'Tok'. void Handle_Pragma(Token &Tok); + /// HandleMicrosoft__pragma - Like Handle_Pragma except the pragma text + /// is not enclosed within a string literal. + void HandleMicrosoft__pragma(Token &Tok); + + void Handle_Pragma(const std::string &StrVal, SourceLocation PragmaLoc, + SourceLocation RParenLoc); + /// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and /// start lexing tokens from it instead of the current buffer. void EnterSourceFileWithLexer(Lexer *TheLexer, const DirectoryLookup *Dir); @@ -880,7 +940,8 @@ private: 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 == 0 && CurTokenLexer == 0 && !IncludeMacroStack.empty(); + return CurPPLexer == 0 && CurTokenLexer == 0 && CurPTHLexer == 0 && + !IncludeMacroStack.empty(); } void EnterCachingLexMode(); void ExitCachingLexMode() { @@ -929,6 +990,10 @@ public: void HandlePragmaDependency(Token &DependencyTok); void HandlePragmaComment(Token &CommentTok); void HandlePragmaMessage(Token &MessageTok); + void HandlePragmaPushMacro(Token &Tok); + void HandlePragmaPopMacro(Token &Tok); + IdentifierInfo *ParsePragmaPushOrPopMacro(Token &Tok); + // Return true and store the first token only if any CommentHandler // has inserted some tokens and getCommentRetentionState() is false. bool HandleComment(Token &Token, SourceRange Comment); diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index bd9b468..954b36e 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -231,6 +231,7 @@ public: /// newlines in it. /// bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; } + }; /// PPConditionalInfo - Information about the conditional stack (#if directives) |