diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -67,11 +67,13 @@ let IsDeclarationCommand = 1; } +// Make sure these are handled in comments::Sema::checkFunctionDeclVerbatimLine. class FunctionDeclarationVerbatimLineCommand : DeclarationVerbatimLineCommand { let IsFunctionDeclarationCommand = 1; } +// Make sure these are handled in comments::Sema::checkContainerDeclVerbatimLine. class RecordLikeDeclarationVerbatimLineCommand : DeclarationVerbatimLineCommand { let IsRecordLikeDeclarationCommand = 1; diff --git a/clang/include/clang/Basic/DiagnosticCommentKinds.td b/clang/include/clang/Basic/DiagnosticCommentKinds.td --- a/clang/include/clang/Basic/DiagnosticCommentKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommentKinds.td @@ -77,22 +77,18 @@ InGroup, DefaultIgnore; def warn_doc_function_method_decl_mismatch : Warning< - "'%select{\\|@}0%select{function|functiongroup|method|methodgroup|callback}1' " - "command should be used in a comment attached to " - "%select{a function|a function|an Objective-C method|an Objective-C method|" - "a pointer to function}2 declaration">, + "'%select{\\|@}0%1' command should be used in a comment attached to " + "%select{a function|an Objective-C method|a pointer to function}2 declaration">, InGroup, DefaultIgnore; def warn_doc_api_container_decl_mismatch : Warning< - "'%select{\\|@}0%select{class|interface|protocol|struct|union}1' " - "command should not be used in a comment attached to a " - "non-%select{class|interface|protocol|struct|union}2 declaration">, + "'%select{\\|@}0%1' command should not be used in a comment attached to a " + "non-%1 declaration">, InGroup, DefaultIgnore; def warn_doc_container_decl_mismatch : Warning< - "'%select{\\|@}0%select{classdesign|coclass|dependency|helper" - "|helperclass|helps|instancesize|ownership|performance|security|superclass}1' " - "command should not be used in a comment attached to a non-container declaration">, + "'%select{\\|@}0%1' command should not be used in a comment attached to a " + "non-container declaration">, InGroup, DefaultIgnore; def warn_doc_param_duplicate : Warning< diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp --- a/clang/lib/AST/CommentSema.cpp +++ b/clang/lib/AST/CommentSema.cpp @@ -107,115 +107,75 @@ void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) { unsigned DiagSelect; switch (Comment->getCommandID()) { - case CommandTraits::KCI_function: - DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 1 : 0; - break; - case CommandTraits::KCI_functiongroup: - DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 2 : 0; - break; - case CommandTraits::KCI_method: - DiagSelect = !isObjCMethodDecl() ? 3 : 0; - break; - case CommandTraits::KCI_methodgroup: - DiagSelect = !isObjCMethodDecl() ? 4 : 0; - break; - case CommandTraits::KCI_callback: - DiagSelect = !isFunctionPointerVarDecl() ? 5 : 0; - break; - default: - DiagSelect = 0; - break; + case CommandTraits::KCI_function: + case CommandTraits::KCI_functiongroup: + if (isAnyFunctionDecl() || isFunctionTemplateDecl()) + return; + DiagSelect = 0; + break; + case CommandTraits::KCI_method: + case CommandTraits::KCI_methodgroup: + if (isObjCMethodDecl()) + return; + DiagSelect = 1; + break; + case CommandTraits::KCI_callback: + if (isFunctionPointerVarDecl()) + return; + DiagSelect = 2; + break; + default: + llvm_unreachable("Unhandled command with IsFunctionDeclarationCommand"); } - if (DiagSelect) - Diag(Comment->getLocation(), diag::warn_doc_function_method_decl_mismatch) - << Comment->getCommandMarker() - << (DiagSelect-1) << (DiagSelect-1) - << Comment->getSourceRange(); + Diag(Comment->getLocation(), diag::warn_doc_function_method_decl_mismatch) + << Comment->getCommandMarker() + << Traits.getCommandInfo(Comment->getCommandID())->Name << DiagSelect + << Comment->getSourceRange(); } void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) { - unsigned DiagSelect; switch (Comment->getCommandID()) { case CommandTraits::KCI_class: - DiagSelect = - (!isClassOrStructOrTagTypedefDecl() && !isClassTemplateDecl()) ? 1 - : 0; + if (isClassOrStructOrTagTypedefDecl() || isClassTemplateDecl()) + return; // Allow @class command on @interface declarations. // FIXME. Currently, \class and @class are indistinguishable. So, // \class is also allowed on an @interface declaration - if (DiagSelect && Comment->getCommandMarker() && isObjCInterfaceDecl()) - DiagSelect = 0; + if (Comment->getCommandMarker() && isObjCInterfaceDecl()) + return; break; case CommandTraits::KCI_interface: - DiagSelect = !isObjCInterfaceDecl() ? 2 : 0; + if (isObjCInterfaceDecl()) + return; break; case CommandTraits::KCI_protocol: - DiagSelect = !isObjCProtocolDecl() ? 3 : 0; + if (isObjCProtocolDecl()) + return; break; case CommandTraits::KCI_struct: - DiagSelect = !isClassOrStructOrTagTypedefDecl() ? 4 : 0; + if (isClassOrStructOrTagTypedefDecl()) + return; break; case CommandTraits::KCI_union: - DiagSelect = !isUnionDecl() ? 5 : 0; + if (isUnionDecl()) + return; break; default: - DiagSelect = 0; - break; + llvm_unreachable("Unhandled command with IsRecordLikeDeclarationCommand"); } - if (DiagSelect) - Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch) - << Comment->getCommandMarker() - << (DiagSelect-1) << (DiagSelect-1) - << Comment->getSourceRange(); + Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch) + << Comment->getCommandMarker() + << Traits.getCommandInfo(Comment->getCommandID())->Name + << Comment->getSourceRange(); } void Sema::checkContainerDecl(const BlockCommandComment *Comment) { if (isRecordLikeDecl()) return; - unsigned DiagSelect; - switch (Comment->getCommandID()) { - case CommandTraits::KCI_classdesign: - DiagSelect = 1; - break; - case CommandTraits::KCI_coclass: - DiagSelect = 2; - break; - case CommandTraits::KCI_dependency: - DiagSelect = 3; - break; - case CommandTraits::KCI_helper: - DiagSelect = 4; - break; - case CommandTraits::KCI_helperclass: - DiagSelect = 5; - break; - case CommandTraits::KCI_helps: - DiagSelect = 6; - break; - case CommandTraits::KCI_instancesize: - DiagSelect = 7; - break; - case CommandTraits::KCI_ownership: - DiagSelect = 8; - break; - case CommandTraits::KCI_performance: - DiagSelect = 9; - break; - case CommandTraits::KCI_security: - DiagSelect = 10; - break; - case CommandTraits::KCI_superclass: - DiagSelect = 11; - break; - default: - DiagSelect = 0; - break; - } - if (DiagSelect) - Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch) - << Comment->getCommandMarker() - << (DiagSelect-1) - << Comment->getSourceRange(); + Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch) + << Comment->getCommandMarker() + << Traits.getCommandInfo(Comment->getCommandID())->Name + << Comment->getSourceRange(); } /// Turn a string into the corresponding PassDirection or -1 if it's not