Index: docs/UsersManual.rst =================================================================== --- docs/UsersManual.rst +++ docs/UsersManual.rst @@ -1311,3 +1311,16 @@ `Some tests might fail `_ on ``x86_64-w64-mingw32``. + +Comment Processing Options +========================== + +Clang parses Doxygen and non-Doxygen style documentation comments and attaches +them to the appropriate declaration nodes. By default, it only parses Doxygen +style comments and ignores ordinary comments starting with `//` and `/*`. +The following option will change this default behavior: + +.. option:: -fparse-all-comments + + Clang will parse all comments as documentation comments (including ordinary + comments starting with `//` and `/*`). Index: include/clang/AST/RawCommentList.h =================================================================== --- include/clang/AST/RawCommentList.h +++ include/clang/AST/RawCommentList.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H #define LLVM_CLANG_AST_RAW_COMMENT_LIST_H +#include "clang/Basic/CommentOptions.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" @@ -40,7 +41,7 @@ RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { } RawComment(const SourceManager &SourceMgr, SourceRange SR, - bool Merged = false); + bool Merged, bool ParseAllComments); CommentKind getKind() const LLVM_READONLY { return (CommentKind) Kind; @@ -82,12 +83,18 @@ /// Returns true if this comment is not a documentation comment. bool isOrdinary() const LLVM_READONLY { - return (Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC); + return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) && + !ParseAllComments; } /// Returns true if this comment any kind of a documentation comment. bool isDocumentation() const LLVM_READONLY { - return !isInvalid() && !isOrdinary(); + return !isInvalid() && (!isOrdinary() || ParseAllComments); + } + + /// Returns whether we are parsing all comments. + bool isParseAllComments() const LLVM_READONLY { + return ParseAllComments; } /// Returns raw comment text with comment markers. @@ -135,6 +142,10 @@ bool IsTrailingComment : 1; bool IsAlmostTrailingComment : 1; + /// When true, ordinary comments starting with "//" and "/*" will be + /// considered as documentation comments. + bool ParseAllComments : 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 @@ -142,10 +153,12 @@ /// \brief Constructor for AST deserialization. RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, - bool IsAlmostTrailingComment) : + bool IsAlmostTrailingComment, + bool ParseAllComments) : Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), IsAttached(false), IsTrailingComment(IsTrailingComment), IsAlmostTrailingComment(IsAlmostTrailingComment), + ParseAllComments(ParseAllComments), BeginLineValid(false), EndLineValid(false) { } @@ -207,4 +220,3 @@ } // end namespace clang #endif - Index: include/clang/Basic/CommentOptions.h =================================================================== --- include/clang/Basic/CommentOptions.h +++ include/clang/Basic/CommentOptions.h @@ -27,6 +27,11 @@ /// \brief Command names to treat as block commands in comments. /// Should not include the leading backslash. BlockCommandNamesTy BlockCommandNames; + + /// \brief Treat ordinary comments as documentation comments. + bool ParseAllComments; + + CommentOptions() : ParseAllComments(false) { } }; } // end namespace clang Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -330,6 +330,7 @@ def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in as a documentation comment block command">, MetaVarName<"">; +def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group, Flags<[CC1Option]>; def fcommon : Flag<["-"], "fcommon">, Group; def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group; def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group; Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -141,7 +141,9 @@ // When searching for comments during parsing, the comment we are looking // for is usually among the last two comments we parsed -- check them // first. - RawComment CommentAtDeclLoc(SourceMgr, SourceRange(DeclLoc)); + RawComment CommentAtDeclLoc( + SourceMgr, SourceRange(DeclLoc), false, + LangOpts.CommentOpts.ParseAllComments); BeforeThanCompare Compare(SourceMgr); ArrayRef::iterator MaybeBeforeDecl = RawComments.end() - 1; bool Found = Compare(*MaybeBeforeDecl, &CommentAtDeclLoc); Index: lib/AST/RawCommentList.cpp =================================================================== --- lib/AST/RawCommentList.cpp +++ lib/AST/RawCommentList.cpp @@ -63,9 +63,10 @@ } // unnamed namespace RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR, - bool Merged) : + bool Merged, bool ParseAllComments) : Range(SR), RawTextValid(false), BriefTextValid(false), IsAttached(false), IsAlmostTrailingComment(false), + ParseAllComments(ParseAllComments), BeginLineValid(false), EndLineValid(false) { // Extract raw comment text, if possible. if (SR.getBegin() == SR.getEnd() || getRawText(SourceMgr).empty()) { @@ -253,7 +254,8 @@ if (C1EndLine + 1 == C2BeginLine || C1EndLine == C2BeginLine) { SourceRange MergedRange(C1.getSourceRange().getBegin(), C2.getSourceRange().getEnd()); - *Comments.back() = RawComment(SourceMgr, MergedRange, true); + *Comments.back() = RawComment(SourceMgr, MergedRange, true, + RC.isParseAllComments()); Merged = true; } } @@ -262,4 +264,3 @@ OnlyWhitespaceSeen = true; } - Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3294,6 +3294,8 @@ // Forward -fcomment-block-commands to -cc1. Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands); + // Forward -fparse-all-comments to -cc1. + Args.AddAllArgs(CmdArgs, options::OPT_fparse_all_comments); // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option // parser. Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -281,6 +281,7 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { Opts.BlockCommandNames = Args.getAllArgValues(OPT_fcomment_block_commands); + Opts.ParseAllComments = Args.hasArg(OPT_fparse_all_comments); } static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -1073,7 +1073,8 @@ if (!LangOpts.RetainCommentsFromSystemHeaders && SourceMgr.isInSystemHeader(Comment.getBegin())) return; - RawComment RC(SourceMgr, Comment); + RawComment RC(SourceMgr, Comment, false, + LangOpts.CommentOpts.ParseAllComments); if (RC.isAlmostTrailingComment()) { SourceRange MagicMarkerRange(Comment.getBegin(), Comment.getBegin().getLocWithOffset(3)); Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -3907,6 +3907,7 @@ LangOpts.CommentOpts.BlockCommandNames.push_back( ReadString(Record, Idx)); } + LangOpts.CommentOpts.ParseAllComments = Record[Idx++]; return Listener.ReadLanguageOptions(LangOpts, Complain); } @@ -7165,9 +7166,9 @@ (RawComment::CommentKind) Record[Idx++]; bool IsTrailingComment = Record[Idx++]; bool IsAlmostTrailingComment = Record[Idx++]; - Comments.push_back(new (Context) RawComment(SR, Kind, - IsTrailingComment, - IsAlmostTrailingComment)); + Comments.push_back(new (Context) RawComment( + SR, Kind, IsTrailingComment, IsAlmostTrailingComment, + Context.getLangOpts().CommentOpts.ParseAllComments)); break; } } Index: lib/Serialization/ASTWriter.cpp =================================================================== --- lib/Serialization/ASTWriter.cpp +++ lib/Serialization/ASTWriter.cpp @@ -1069,6 +1069,7 @@ I != IEnd; ++I) { AddString(*I, Record); } + Record.push_back(LangOpts.CommentOpts.ParseAllComments); Stream.EmitRecord(LANGUAGE_OPTIONS, Record); Index: test/Driver/fparse-all-comments.c =================================================================== --- /dev/null +++ test/Driver/fparse-all-comments.c @@ -0,0 +1,5 @@ +// Check that we pass -fparse-all-comments to frontend. +// +// RUN: %clang -c %s -fparse-all-comments -### 2>&1 | FileCheck %s --check-prefix=CHECK-ARG +// +// CHECK-ARG: -fparse-all-comments Index: test/Index/parse-all-comments.c =================================================================== --- /dev/null +++ test/Index/parse-all-comments.c @@ -0,0 +1,48 @@ +// Run lines are sensitive to line numbers and come below the code. + +#ifndef HEADER +#define HEADER + +// Not a Doxygen comment. notdoxy1 NOT_DOXYGEN +void notdoxy1(void); + +/* Not a Doxygen comment. notdoxy2 NOT_DOXYGEN */ +void notdoxy2(void); + +/*/ Not a Doxygen comment. notdoxy3 NOT_DOXYGEN */ +void notdoxy3(void); + +/** Doxygen comment. isdoxy4 IS_DOXYGEN_SINGLE */ +void isdoxy4(void); + +/* BLOCK_ORDINARY_COMMENT */ +// ORDINARY COMMENT +/// This is a BCPL comment. IS_DOXYGEN_START +/// It has only two lines. +/** But there are other blocks that are part of the comment, too. IS_DOXYGEN_END */ +void multi_line_comment_plus_ordinary(int); + +#endif + +// RUN: rm -rf %t +// RUN: mkdir %t + +// RUN: %clang_cc1 -fparse-all-comments -x c++ -std=c++11 -emit-pch -o %t/out.pch %s + +// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 -fparse-all-comments > %t/out.c-index-direct +// RUN: c-index-test -test-load-tu %t/out.pch all > %t/out.c-index-pch + +// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct +// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-pch + +// Ensure that XML is not invalid +// WRONG-NOT: CommentXMLInvalid + +// RUN: FileCheck %s < %t/out.c-index-direct +// RUN: FileCheck %s < %t/out.c-index-pch + +// CHECK: parse-all-comments.c:7:6: FunctionDecl=notdoxy1:{{.*}} notdoxy1 NOT_DOXYGEN +// CHECK: parse-all-comments.c:10:6: FunctionDecl=notdoxy2:{{.*}} notdoxy2 NOT_DOXYGEN +// CHECK: parse-all-comments.c:13:6: FunctionDecl=notdoxy3:{{.*}} notdoxy3 NOT_DOXYGEN +// CHECK: parse-all-comments.c:16:6: FunctionDecl=isdoxy4:{{.*}} isdoxy4 IS_DOXYGEN_SINGLE +// CHECK: parse-all-comments.c:23:6: FunctionDecl=multi_line_comment_plus_ordinary:{{.*}} BLOCK_ORDINARY_COMMENT {{.*}} ORDINARY COMMENT {{.*}} IS_DOXYGEN_START {{.*}} IS_DOXYGEN_END