/// \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;
bit IsVerbatimBlockEndCommand = 0;
bit IsVerbatimLineCommand = 0;
bit IsDeclarationCommand = 0;
+ bit IsFunctionDeclarationCommand = 0;
}
class InlineCommand<string name> : Command<name> {
let IsDeclarationCommand = 1;
}
+class FunctionDeclarationVerbatimLineCommand<string name> :
+ VerbatimLineCommand<name> {
+ let IsDeclarationCommand = 1;
+ let IsFunctionDeclarationCommand = 1;
+}
+
//===----------------------------------------------------------------------===//
// InlineCommand
//===----------------------------------------------------------------------===//
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">;
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.
"a function declaration">,
InGroup<Documentation>, 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<Documentation>, DefaultIgnore;
+
def warn_doc_param_duplicate : Warning<
"parameter '%0' is already documented">,
InGroup<Documentation>, DefaultIgnore;
TextBegin,
Text);
consumeToken();
+ S.checkFunctionDeclVerbatimLine(VL);
+
return VL;
}
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,
///@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);
<< Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", "
<< Tag.getValueAsBit("IsVerbatimLineCommand") << ", "
<< Tag.getValueAsBit("IsDeclarationCommand") << ", "
+ << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", "
<< /* IsUnknownCommand = */ "0"
<< " }";
if (i + 1 != e)