In r176739. Thanks for the review. - Fariborz
On Mar 7, 2013, at 3:51 PM, Dmitri Gribenko <[email protected]> wrote: > Hi Fariborz, > > On Fri, Mar 8, 2013 at 1:33 AM, Fariborz Jahanian <[email protected]> wrote: >> Author: fjahanian >> Date: Thu Mar 7 17:33:11 2013 >> New Revision: 176667 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=176667&view=rev >> Log: >> HeaderDoc: Support more of HeaderDoc documentation >> commands; top level tags such as @interface and >> their 2nd level tags such as @coclass, etc. >> // rdar://12379114 >> >> Modified: >> cfe/trunk/include/clang/AST/CommentCommandTraits.h >> cfe/trunk/include/clang/AST/CommentCommands.td >> cfe/trunk/include/clang/AST/CommentSema.h >> cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td >> cfe/trunk/lib/AST/CommentSema.cpp >> cfe/trunk/test/Sema/warn-documentation.cpp >> cfe/trunk/test/Sema/warn-documentation.m >> cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp >> >> Modified: cfe/trunk/include/clang/AST/CommentCommandTraits.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentCommandTraits.h?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/CommentCommandTraits.h (original) >> +++ cfe/trunk/include/clang/AST/CommentCommandTraits.h Thu Mar 7 17:33:11 >> 2013 >> @@ -101,8 +101,15 @@ struct CommandInfo { >> /// \endcode >> unsigned IsDeclarationCommand : 1; >> >> - /// \brief True if verbatim-like line command is a function declaraton. >> + /// \brief True if verbatim-like line command is a function declaration. >> unsigned IsFunctionDeclarationCommand : 1; >> + >> + /// \brief True if block command is further describing a container API; >> such >> + /// as @coclass, @classdesign, etc. >> + unsigned IsContainerDetailCommand : 1; >> + >> + /// \brief True if block command is a container API; such as @interface. >> + unsigned IsContainerDeclarationCommand : 1; > > Is the 'container' the best term for this? I don't know ObjC, but a > container is something like std::vector for me. > >> >> /// \brief True if this command is unknown. This \c CommandInfo object was >> /// created during parsing. >> >> Modified: cfe/trunk/include/clang/AST/CommentCommands.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentCommands.td?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/CommentCommands.td (original) >> +++ cfe/trunk/include/clang/AST/CommentCommands.td Thu Mar 7 17:33:11 2013 >> @@ -25,6 +25,8 @@ class Command<string name> { >> bit IsVerbatimLineCommand = 0; >> bit IsDeclarationCommand = 0; >> bit IsFunctionDeclarationCommand = 0; >> + bit IsContainerDetailCommand = 0; >> + bit IsContainerDeclarationCommand = 0; >> } >> >> class InlineCommand<string name> : Command<name> { >> @@ -66,6 +68,12 @@ class FunctionDeclarationVerbatimLineCom >> let IsFunctionDeclarationCommand = 1; >> } >> >> +class ContainerDeclarationVerbatimLineCommand<string name> : >> + VerbatimLineCommand<name> { >> + let IsDeclarationCommand = 1; >> + let IsContainerDeclarationCommand = 1; >> +} >> + >> //===----------------------------------------------------------------------===// >> // InlineCommand >> //===----------------------------------------------------------------------===// >> @@ -181,9 +189,11 @@ def Typedef : DeclarationVerbatimLineC >> def Var : DeclarationVerbatimLineCommand<"var">; >> >> // HeaderDoc commands. >> -def Class : DeclarationVerbatimLineCommand<"class">; >> -def Interface : DeclarationVerbatimLineCommand<"interface">; >> -def Protocol : DeclarationVerbatimLineCommand<"protocol">; >> +def Class : ContainerDeclarationVerbatimLineCommand<"class">; >> +def Interface : ContainerDeclarationVerbatimLineCommand<"interface">; >> +def Protocol : ContainerDeclarationVerbatimLineCommand<"protocol">; >> +def Struct : ContainerDeclarationVerbatimLineCommand<"struct">; >> +def Union : ContainerDeclarationVerbatimLineCommand<"union">; >> def Category : DeclarationVerbatimLineCommand<"category">; >> def Template : DeclarationVerbatimLineCommand<"template">; >> def Function : FunctionDeclarationVerbatimLineCommand<"function">; >> @@ -191,7 +201,38 @@ def Method : FunctionDeclarationVerba >> def Callback : FunctionDeclarationVerbatimLineCommand<"callback">; >> def Const : DeclarationVerbatimLineCommand<"const">; >> def Constant : DeclarationVerbatimLineCommand<"constant">; >> -def Struct : DeclarationVerbatimLineCommand<"struct">; >> -def Union : DeclarationVerbatimLineCommand<"union">; >> def Enum : DeclarationVerbatimLineCommand<"enum">; >> >> +def ClassDesign : BlockCommand<"classdesign"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def CoClass : BlockCommand<"coclass"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def Dependency : BlockCommand<"dependency"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def Helper : BlockCommand<"helper"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def HelperClass : BlockCommand<"helperclass"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def Helps : BlockCommand<"helps"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def InstanceSize : BlockCommand<"instancesize"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def Ownership : BlockCommand<"ownership"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def Performance : BlockCommand<"performance"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def Security : BlockCommand<"security"> { >> + let IsContainerDetailCommand = 1; >> +} >> +def SuperClass : BlockCommand<"superclass"> { >> + let IsContainerDetailCommand = 1; >> +} > > Please clean this up by defining a class in .td that is derived from > BlockCommand. > >> >> Modified: cfe/trunk/include/clang/AST/CommentSema.h >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CommentSema.h?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/AST/CommentSema.h (original) >> +++ cfe/trunk/include/clang/AST/CommentSema.h Thu Mar 7 17:33:11 2013 >> @@ -200,6 +200,10 @@ public: >> void checkDeprecatedCommand(const BlockCommandComment *Comment); >> >> void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment); >> + >> + void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment); >> + >> + void checkContainerDecl(const BlockCommandComment *Comment); >> >> /// Resolve parameter names to parameter indexes in function declaration. >> /// Emit diagnostics about unknown parametrs. >> @@ -211,6 +215,11 @@ public: >> bool isObjCMethodDecl(); >> bool isObjCPropertyDecl(); >> bool isTemplateOrSpecialization(); >> + bool isContainerDecl(); >> + bool isClassStructDecl(); >> + bool isUnionDecl(); >> + bool isObjCInterfaceDecl(); >> + bool isObjCProtocolDecl(); >> >> ArrayRef<const ParmVarDecl *> getParamVars(); >> >> >> Modified: cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td (original) >> +++ cfe/trunk/include/clang/Basic/DiagnosticCommentKinds.td Thu Mar 7 >> 17:33:11 2013 >> @@ -79,6 +79,18 @@ def warn_doc_function_method_decl_mismat >> "%select{a function|an Objective-C method|a pointer to function}2 >> declaration">, >> InGroup<Documentation>, 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">, >> + InGroup<Documentation>, 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">, >> + InGroup<Documentation>, DefaultIgnore; >> + >> def warn_doc_param_duplicate : Warning< >> "parameter '%0' is already documented">, >> InGroup<Documentation>, DefaultIgnore; >> >> Modified: cfe/trunk/lib/AST/CommentSema.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentSema.cpp?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/lib/AST/CommentSema.cpp (original) >> +++ cfe/trunk/lib/AST/CommentSema.cpp Thu Mar 7 17:33:11 2013 >> @@ -52,8 +52,11 @@ BlockCommandComment *Sema::actOnBlockCom >> SourceLocation LocEnd, >> unsigned CommandID, >> CommandMarkerKind CommandMarker) { >> - return new (Allocator) BlockCommandComment(LocBegin, LocEnd, CommandID, >> - CommandMarker); >> + BlockCommandComment *BC = new (Allocator) BlockCommandComment(LocBegin, >> LocEnd, >> + CommandID, >> + >> CommandMarker); >> + checkContainerDecl(BC); >> + return BC; >> } >> >> void Sema::actOnBlockCommandArgs(BlockCommandComment *Command, >> @@ -105,6 +108,52 @@ void Sema::checkFunctionDeclVerbatimLine >> << (DiagSelect-1) << (DiagSelect-1) >> << Comment->getSourceRange(); >> } >> + >> +void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment >> *Comment) { >> + const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); >> + if (!Info->IsContainerDeclarationCommand) >> + return; >> + StringRef Name = Info->Name; >> + unsigned DiagSelect = llvm::StringSwitch<unsigned>(Name) >> + .Case("class", !isClassStructDecl() ? 1 : 0) >> + .Case("interface", !isObjCInterfaceDecl() ? 2 : 0) >> + .Case("protocol", !isObjCProtocolDecl() ? 3 : 0) >> + .Case("struct", !isClassStructDecl() ? 4 : 0) >> + .Case("union", !isUnionDecl() ? 5 : 0) >> + .Default(0); > > Please don't StringSwitch on the command name. Statically known > commands have IDs. See > CommentASTToXMLConverter::visitBlockCommandComment for an example of > how to use these. > >> + >> + if (DiagSelect) >> + Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch) >> + << Comment->getCommandMarker() >> + << (DiagSelect-1) << (DiagSelect-1) >> + << Comment->getSourceRange(); >> +} >> + >> +void Sema::checkContainerDecl(const BlockCommandComment *Comment) { >> + const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); >> + if (!Info->IsContainerDetailCommand || isContainerDecl()) >> + return; >> + StringRef Name = Info->Name; >> + unsigned DiagSelect = llvm::StringSwitch<unsigned>(Name) >> + .Case("classdesign", 1) >> + .Case("coclass", 2) >> + .Case("dependency", 3) >> + .Case("helper", 4) >> + .Case("helperclass", 5) >> + .Case("helps", 6) >> + .Case("instancesize", 7) >> + .Case("ownership", 8) >> + .Case("performance", 9) >> + .Case("security", 10) >> + .Case("superclass", 11) >> + .Default(0); > > Same here. > >> + >> + if (DiagSelect) >> + Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch) >> + << Comment->getCommandMarker() >> + << (DiagSelect-1) >> + << Comment->getSourceRange(); >> +} >> >> void Sema::actOnParamCommandDirectionArg(ParamCommandComment *Command, >> SourceLocation ArgLocBegin, >> @@ -362,6 +411,7 @@ VerbatimLineComment *Sema::actOnVerbatim >> TextBegin, >> Text); >> checkFunctionDeclVerbatimLine(VL); >> + checkContainerDeclVerbatimLine(VL); >> return VL; >> } >> >> @@ -735,6 +785,54 @@ bool Sema::isTemplateOrSpecialization() >> return ThisDeclInfo->getTemplateKind() != DeclInfo::NotTemplate; >> } >> >> +bool Sema::isContainerDecl() { >> + if (!ThisDeclInfo) >> + return false; >> + if (!ThisDeclInfo->IsFilled) >> + inspectThisDecl(); >> + return isUnionDecl() || isClassStructDecl() >> + || isObjCInterfaceDecl() || isObjCProtocolDecl(); >> +} >> + >> +bool Sema::isUnionDecl() { >> + if (!ThisDeclInfo) >> + return false; >> + if (!ThisDeclInfo->IsFilled) >> + inspectThisDecl(); >> + if (const RecordDecl *RD = >> + dyn_cast_or_null<RecordDecl>(ThisDeclInfo->CurrentDecl)) >> + return RD->isUnion(); >> + return false; >> +} >> + >> +bool Sema::isClassStructDecl() { > > isClassOrStructDecl() would be a better name. > >> + if (!ThisDeclInfo) >> + return false; >> + if (!ThisDeclInfo->IsFilled) >> + inspectThisDecl(); >> + return ThisDeclInfo->CurrentDecl && >> + isa<RecordDecl>(ThisDeclInfo->CurrentDecl) && >> + !isUnionDecl(); >> +} >> + >> +bool Sema::isObjCInterfaceDecl() { >> + if (!ThisDeclInfo) >> + return false; >> + if (!ThisDeclInfo->IsFilled) >> + inspectThisDecl(); >> + return ThisDeclInfo->CurrentDecl && >> + isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl); >> +} >> + >> +bool Sema::isObjCProtocolDecl() { >> + if (!ThisDeclInfo) >> + return false; >> + if (!ThisDeclInfo->IsFilled) >> + inspectThisDecl(); >> + return ThisDeclInfo->CurrentDecl && >> + isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl); >> +} >> + >> ArrayRef<const ParmVarDecl *> Sema::getParamVars() { >> if (!ThisDeclInfo->IsFilled) >> inspectThisDecl(); >> >> Modified: cfe/trunk/test/Sema/warn-documentation.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.cpp?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/test/Sema/warn-documentation.cpp (original) >> +++ cfe/trunk/test/Sema/warn-documentation.cpp Thu Mar 7 17:33:11 2013 >> @@ -922,3 +922,31 @@ int test_nocrash12(); >> // expected-warning@+1 {{empty paragraph passed to '@param' command}} >> ///@param x@param y >> int test_nocrash13(int x, int y); >> + >> +// rdar://12379114 >> +// expected-warning@+2 {{'@union' command should not be used in a comment >> attached to a non-union declaration}} >> +/*! >> + @union U This is new >> +*/ >> +struct U { int iS; }; >> + >> +/*! >> + @union U1 >> +*/ >> +union U1 {int i; }; >> + >> +// expected-warning@+2 {{'@struct' command should not be used in a comment >> attached to a non-struct declaration}} >> +/*! >> + @struct S2 >> +*/ >> +union S2 {}; >> + >> +/*! >> + @class C1 >> +*/ >> +class C1; >> + >> +/*! >> + @struct S3; >> +*/ >> +class S3; >> >> Modified: cfe/trunk/test/Sema/warn-documentation.m >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.m?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/test/Sema/warn-documentation.m (original) >> +++ cfe/trunk/test/Sema/warn-documentation.m Thu Mar 7 17:33:11 2013 >> @@ -105,3 +105,55 @@ typedef int (^test_param1)(int aaa, int >> typedef id ID; >> - (unsigned) Base64EncodeEx : (ID)Arg; >> @end >> + >> +// rdar://12379114 >> +// expected-warning@+5 {{'@interface' command should not be used in a >> comment attached to a non-interface declaration}} >> +// expected-warning@+5 {{'@classdesign' command should not be used in a >> comment attached to a non-container declaration}} >> +// expected-warning@+5 {{'@coclass' command should not be used in a comment >> attached to a non-container declaration}} >> +@interface NSObject @end >> +/*! >> +@interface IOCommandGate >> +@classdesign Multiple paragraphs go here. >> +@coclass myCoClass >> +*/ >> + >> +typedef id OBJ; >> +@interface IOCommandGate : NSObject { >> + OBJ iv; >> +} >> +@end >> + >> +// expected-warning@+2 {{'@protocol' command should not be used in a >> comment attached to a non-protocol declaration}} >> +/*! >> +@protocol PROTO >> +*/ >> +struct S; >> + >> +/*! >> + @interface NSArray This is an array >> +*/ >> +@class NSArray; >> +@interface NSArray @end >> + >> +/*! >> +@interface NSMutableArray >> +@super NSArray >> +*/ >> +@interface NSMutableArray : NSArray @end >> + >> +/*! >> + @protocol MyProto >> +*/ >> +@protocol MyProto @end >> + >> +// expected-warning@+2 {{'@protocol' command should not be used in a >> comment attached to a non-protocol declaration}} >> +/*! >> + @protocol MyProto >> +*/ >> +@interface INTF <MyProto> @end >> + >> +// expected-warning@+2 {{'@struct' command should not be used in a comment >> attached to a non-struct declaration}} >> +/*! >> + @struct S1 THIS IS IT >> +*/ >> +@interface S1 @end >> >> Modified: cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp?rev=176667&r1=176666&r2=176667&view=diff >> ============================================================================== >> --- cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp (original) >> +++ cfe/trunk/utils/TableGen/ClangCommentCommandInfoEmitter.cpp Thu Mar 7 >> 17:33:11 2013 >> @@ -48,6 +48,8 @@ void EmitClangCommentCommandInfo(RecordK >> << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " >> << Tag.getValueAsBit("IsDeclarationCommand") << ", " >> << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " >> + << Tag.getValueAsBit("IsContainerDetailCommand") << ", " >> + << Tag.getValueAsBit("IsContainerDeclarationCommand") << ", " >> << /* IsUnknownCommand = */ "0" >> << " }"; >> if (i + 1 != e) > > Dmitri > > -- > main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if > (j){printf("%d\n",i);}}} /*Dmitri Gribenko <[email protected]>*/ _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
