diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/ASTContext.h | 26 | ||||
-rw-r--r-- | include/clang/AST/ExternalASTSource.h | 3 | ||||
-rw-r--r-- | include/clang/Basic/SourceManager.h | 42 | ||||
-rw-r--r-- | include/clang/Comments/RawCommentList.h | 172 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 4 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 1 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 12 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 7 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 1 |
10 files changed, 252 insertions, 18 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 6ceed17eb8..172ac88edf 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -27,6 +27,7 @@ #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/AST/CanonicalType.h" +#include "clang/Comments/RawCommentList.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -51,7 +52,6 @@ namespace clang { class ASTMutationListener; class IdentifierTable; class SelectorTable; - class SourceManager; class TargetInfo; class CXXABI; // Decls @@ -418,6 +418,30 @@ public: return FullSourceLoc(Loc,SourceMgr); } + /// \brief All comments in this translation unit. + RawCommentList Comments; + + /// \brief True if comments are already loaded from ExternalASTSource. + mutable bool CommentsLoaded; + + /// \brief Mapping from declarations to their comments (stored within + /// Comments list), once we have already looked up the comment associated + /// with a given declaration. + mutable llvm::DenseMap<const Decl *, const RawComment *> DeclComments; + + /// \brief Return the Doxygen-style comment attached to a given declaration, + /// without looking into cache. + const RawComment *getRawCommentForDeclNoCache(const Decl *D) const; + +public: + void addComment(const RawComment &RC) { + Comments.addComment(RC, *this); + } + + /// \brief Return the Doxygen-style comment attached to a given declaration. + /// Returns NULL if no comment is attached. + const RawComment *getRawCommentForDecl(const Decl *D) const; + /// \brief Retrieve the attributes for the given declaration. AttrVec& getDeclAttrs(const Decl *D); diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index e2a60d5cf0..7aedfe2ef6 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -179,6 +179,9 @@ public: /// \c ObjCInterfaceDecl::setExternallyCompleted(). virtual void CompleteType(ObjCInterfaceDecl *Class) { } + /// \brief Loads comment ranges. + virtual void ReadComments() { } + /// \brief Notify ExternalASTSource that we started deserialization of /// a decl or type so until FinishedDeserializing is called there may be /// decls that are initializing. Must be paired with FinishedDeserializing. diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 603bfebfd3..19fa52ee1d 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -1244,19 +1244,6 @@ public: /// \returns true if LHS source location comes before RHS, false otherwise. bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const; - /// \brief Comparison function class. - class LocBeforeThanCompare : public std::binary_function<SourceLocation, - SourceLocation, bool> { - SourceManager &SM; - - public: - explicit LocBeforeThanCompare(SourceManager &SM) : SM(SM) { } - - bool operator()(SourceLocation LHS, SourceLocation RHS) const { - return SM.isBeforeInTranslationUnit(LHS, RHS); - } - }; - /// \brief Determines the order of 2 source locations in the "source location /// address space". bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const { @@ -1500,6 +1487,35 @@ private: friend class ASTWriter; }; +/// \brief Comparison function object. +template<typename T> +class BeforeThanCompare; + +/// \brief Compare two source locations. +template<> +class BeforeThanCompare<SourceLocation> { + SourceManager &SM; + +public: + explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { } + + bool operator()(SourceLocation LHS, SourceLocation RHS) const { + return SM.isBeforeInTranslationUnit(LHS, RHS); + } +}; + +/// \brief Compare two non-overlapping source ranges. +template<> +class BeforeThanCompare<SourceRange> { + SourceManager &SM; + +public: + explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { } + + bool operator()(SourceRange LHS, SourceRange RHS) { + return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin()); + } +}; } // end namespace clang diff --git a/include/clang/Comments/RawCommentList.h b/include/clang/Comments/RawCommentList.h new file mode 100644 index 0000000000..bf0b616383 --- /dev/null +++ b/include/clang/Comments/RawCommentList.h @@ -0,0 +1,172 @@ +//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_COMMENTS_RAW_COMMENT_LIST_H +#define LLVM_CLANG_COMMENTS_RAW_COMMENT_LIST_H + +#include "clang/Basic/SourceManager.h" +#include "llvm/ADT/ArrayRef.h" + +namespace clang { + +class ASTContext; +class ASTReader; + +class RawComment { +public: + enum CommentKind { + CK_Invalid, ///< Invalid comment + CK_OrdinaryBCPL, ///< Any normal BCPL comments + CK_OrdinaryC, ///< Any normal C comment + CK_BCPLSlash, ///< \code /// stuff \endcode + CK_BCPLExcl, ///< \code //! stuff \endcode + CK_JavaDoc, ///< \code /** stuff */ \endcode + CK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc + CK_Merged ///< Two or more Doxygen comments merged together + }; + + RawComment() : Kind(CK_Invalid), IsAlmostTrailingComment(false) { } + + RawComment(const SourceManager &SourceMgr, SourceRange SR, + bool Merged = false); + + CommentKind getKind() const LLVM_READONLY { + return (CommentKind) Kind; + } + + bool isInvalid() const LLVM_READONLY { + return Kind == CK_Invalid; + } + + bool isMerged() const LLVM_READONLY { + return Kind == CK_Merged; + } + + /// Returns true if it is a comment that should be put after a member: + /// \code ///< stuff \endcode + /// \code //!< stuff \endcode + /// \code /**< stuff */ \endcode + /// \code /*!< stuff */ \endcode + bool isTrailingComment() const LLVM_READONLY { + assert(isDoxygen()); + return IsTrailingComment; + } + + /// Returns true if it is a probable typo: + /// \code //< stuff \endcode + /// \code /*< stuff */ \endcode + bool isAlmostTrailingComment() const LLVM_READONLY { + return IsAlmostTrailingComment; + } + + /// Returns true if this comment is not a Doxygen comment. + bool isOrdinary() const LLVM_READONLY { + return (Kind == CK_OrdinaryBCPL) || (Kind == CK_OrdinaryC); + } + + /// Returns true if this comment any kind of a Doxygen comment. + bool isDoxygen() const LLVM_READONLY { + return !isInvalid() && !isOrdinary(); + } + + /// Returns raw comment text with comment markers. + StringRef getRawText(const SourceManager &SourceMgr) const { + if (RawTextValid) + return RawText; + + RawText = getRawTextSlow(SourceMgr); + RawTextValid = true; + return RawText; + } + + SourceRange getSourceRange() const LLVM_READONLY { + return Range; + } + + unsigned getBeginLine(const SourceManager &SM) const; + unsigned getEndLine(const SourceManager &SM) const; + +private: + SourceRange Range; + + mutable StringRef RawText; + mutable bool RawTextValid : 1; ///< True if RawText is valid + + unsigned Kind : 3; + + bool IsTrailingComment : 1; + bool IsAlmostTrailingComment : 1; + + mutable bool BeginLineValid : 1; ///< True if BeginLine is valid + mutable bool EndLineValid : 1; ///< True if EndLine is valid + mutable unsigned BeginLine; ///< Cached line number + mutable unsigned EndLine; ///< Cached line number + + /// \brief Constructor for AST deserialization. + RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, + bool IsAlmostTrailingComment) : + Range(SR), RawTextValid(false), Kind(K), + IsTrailingComment(IsTrailingComment), + IsAlmostTrailingComment(IsAlmostTrailingComment), + BeginLineValid(false), EndLineValid(false) + { } + + StringRef getRawTextSlow(const SourceManager &SourceMgr) const; + + friend class ASTReader; +}; + +/// \brief Compare comments' source locations. +template<> +class BeforeThanCompare<RawComment> { + const SourceManager &SM; + +public: + explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } + + bool operator()(const RawComment &LHS, const SourceRange &RHS) { + return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(), + RHS.getBegin()); + } +}; + +/// \brief This class represents all comments included in the translation unit, +/// sorted in order of appearance in the translation unit. +class RawCommentList { +public: + RawCommentList(SourceManager &SourceMgr) : + SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } + + void addComment(const RawComment &RC, ASTContext &Context); + + ArrayRef<RawComment> getComments() const { + return Comments; + } + +private: + SourceManager &SourceMgr; + std::vector<RawComment> Comments; + RawComment LastComment; + bool OnlyWhitespaceSeen; + + void addCommentsToFront(const std::vector<RawComment> &C) { + size_t OldSize = Comments.size(); + Comments.resize(C.size() + OldSize); + std::copy_backward(Comments.begin(), Comments.begin() + OldSize, + Comments.end()); + std::copy(C.begin(), C.end(), Comments.begin()); + } + + friend class ASTReader; +}; + +} // end namespace clang + +#endif + diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 7d3d6e1080..3b94a5725e 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -510,12 +510,12 @@ public: } /// \brief Add the specified comment handler to the preprocessor. - void AddCommentHandler(CommentHandler *Handler); + void addCommentHandler(CommentHandler *Handler); /// \brief Remove the specified comment handler. /// /// It is an error to remove a handler that has not been registered. - void RemoveCommentHandler(CommentHandler *Handler); + void removeCommentHandler(CommentHandler *Handler); /// \brief Set the code completion handler to the given object. void setCodeCompletionHandler(CodeCompletionHandler &Handler) { diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index cf308327f3..b451ed97e9 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -170,6 +170,7 @@ class Parser : public CodeCompletionHandler { OwningPtr<PragmaHandler> RedefineExtnameHandler; OwningPtr<PragmaHandler> FPContractHandler; OwningPtr<PragmaHandler> OpenCLExtensionHandler; + OwningPtr<CommentHandler> CommentHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 408763f5cf..4be823a8db 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -849,6 +849,8 @@ public: /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } + void ActOnComment(SourceRange Comment); + //===--------------------------------------------------------------------===// // Type Analysis / Processing: SemaType.cpp. // diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 42d0ad2467..2049da9730 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -207,7 +207,10 @@ namespace clang { PREPROCESSOR_DETAIL_BLOCK_ID, /// \brief The block containing the submodule structure. - SUBMODULE_BLOCK_ID + SUBMODULE_BLOCK_ID, + + /// \brief The block containing comments. + COMMENTS_BLOCK_ID }; /// \brief Record types that occur within the AST block itself. @@ -545,7 +548,12 @@ namespace clang { /// \brief Specifies a required feature. SUBMODULE_REQUIRES = 7 }; - + + /// \brief Record types used within a comments block. + enum CommentRecordTypes { + COMMENTS_RAW_COMMENT = 0 + }; + /// \defgroup ASTAST AST file AST constants /// /// The constants in this group describe various components of the diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 21fd674b2a..d084254ead 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1501,6 +1501,13 @@ public: SwitchCase *getSwitchCaseWithID(unsigned ID); void ClearSwitchCaseIDs(); + + /// \brief Cursors for comments blocks. + SmallVector<std::pair<llvm::BitstreamCursor, + serialization::ModuleFile *>, 8> CommentsCursors; + + /// \brief Loads comments ranges. + void ReadComments(); }; /// \brief Helper class that saves the current stream position and diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 16c3766f8f..472b407992 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -414,6 +414,7 @@ private: uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); void WriteTypeDeclOffsets(); void WriteFileDeclIDsMap(); + void WriteComments(); void WriteSelectors(Sema &SemaRef); void WriteReferencedSelectorsPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, |