From: Fariborz Jahanian Date: Tue, 5 Mar 2013 01:05:07 +0000 (+0000) Subject: doc parsing. We want to issue a strong warning when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a268f2629b49958427e8eb02f2c3d565be71acc;p=clang doc parsing. We want to issue a strong warning when an @function comment is not followed by a function decl. // rdar://13094352 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176468 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index ad4f29988c..360a54b378 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -100,7 +100,10 @@ struct CommandInfo { /// \fn void f(int a); /// \endcode unsigned IsDeclarationCommand : 1; - + + /// \brief True if verbatim-like line command is a function declaraton. + unsigned IsFunctionDeclarationCommand : 1; + /// \brief True if this command is unknown. This \c CommandInfo object was /// created during parsing. unsigned IsUnknownCommand : 1; diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td index f04509c5ca..50abc5948c 100644 --- a/include/clang/AST/CommentCommands.td +++ b/include/clang/AST/CommentCommands.td @@ -24,6 +24,7 @@ class Command { bit IsVerbatimBlockEndCommand = 0; bit IsVerbatimLineCommand = 0; bit IsDeclarationCommand = 0; + bit IsFunctionDeclarationCommand = 0; } class InlineCommand : Command { @@ -59,6 +60,12 @@ class DeclarationVerbatimLineCommand : let IsDeclarationCommand = 1; } +class FunctionDeclarationVerbatimLineCommand : + VerbatimLineCommand { + let IsDeclarationCommand = 1; + let IsFunctionDeclarationCommand = 1; +} + //===----------------------------------------------------------------------===// // InlineCommand //===----------------------------------------------------------------------===// @@ -179,7 +186,7 @@ def Interface : DeclarationVerbatimLineCommand<"interface">; def Protocol : DeclarationVerbatimLineCommand<"protocol">; def Category : DeclarationVerbatimLineCommand<"category">; def Template : DeclarationVerbatimLineCommand<"template">; -def Function : DeclarationVerbatimLineCommand<"function">; +def Function : FunctionDeclarationVerbatimLineCommand<"function">; def Method : DeclarationVerbatimLineCommand<"method">; def Callback : DeclarationVerbatimLineCommand<"callback">; def Const : DeclarationVerbatimLineCommand<"const">; diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 6613feb3d7..6df48dcce1 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -198,6 +198,8 @@ public: void checkBlockCommandDuplicate(const BlockCommandComment *Command); void checkDeprecatedCommand(const BlockCommandComment *Comment); + + void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment); /// Resolve parameter names to parameter indexes in function declaration. /// Emit diagnostics about unknown parametrs. diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td index 829f98dfd7..5f28625151 100644 --- a/include/clang/Basic/DiagnosticCommentKinds.td +++ b/include/clang/Basic/DiagnosticCommentKinds.td @@ -73,6 +73,11 @@ def warn_doc_param_not_attached_to_a_function_decl : Warning< "a function declaration">, InGroup, DefaultIgnore; +def warn_doc_function_not_attached_to_a_function_decl : Warning< + "'@function' command used in a comment that is attached to " + "a non-function declaration immediately following it">, + InGroup, DefaultIgnore; + def warn_doc_param_duplicate : Warning< "parameter '%0' is already documented">, InGroup, DefaultIgnore; diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp index 09912c6188..c361679e90 100644 --- a/lib/AST/CommentParser.cpp +++ b/lib/AST/CommentParser.cpp @@ -706,6 +706,8 @@ VerbatimLineComment *Parser::parseVerbatimLine() { TextBegin, Text); consumeToken(); + S.checkFunctionDeclVerbatimLine(VL); + return VL; } diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp index d959d19b91..0cf7b5fd50 100644 --- a/lib/AST/CommentSema.cpp +++ b/lib/AST/CommentSema.cpp @@ -88,6 +88,15 @@ ParamCommandComment *Sema::actOnParamCommandStart( return Command; } +void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) { + const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); + if (Info->IsFunctionDeclarationCommand && + !isFunctionDecl()) + Diag(Comment->getLocation(), + diag::warn_doc_function_not_attached_to_a_function_decl) + << Comment->getSourceRange(); +} + void Sema::actOnParamCommandDirectionArg(ParamCommandComment *Command, SourceLocation ArgLocBegin, SourceLocation ArgLocEnd, diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index 431bec1147..8b38ddd81a 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -911,3 +911,12 @@ int test_nocrash12(); ///@param x@param y int test_nocrash13(int x, int y); +// expected-warning@+3 {{'@function' command used in a comment that is attached to a non-function declaration immediately following it}} +// expected-warning@+3 {{'@param' command used in a comment that is not attached to a function declaration}} +// expected-warning@+3 {{'@result' command used in a comment that is not attached to a function or method declaration}} +/*! @function Base64EncodeEx + @param inFlags This is error flag + @result Error +*/ +typedef unsigned int Base64Flags; +unsigned Base64EncodeEx(Base64Flags inFlags); diff --git a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp index 4dafc2eec9..b0bf75217d 100644 --- a/utils/TableGen/ClangCommentCommandInfoEmitter.cpp +++ b/utils/TableGen/ClangCommentCommandInfoEmitter.cpp @@ -47,6 +47,7 @@ void EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", " << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " << Tag.getValueAsBit("IsDeclarationCommand") << ", " + << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " << /* IsUnknownCommand = */ "0" << " }"; if (i + 1 != e)