[cfe-commits] r165643 - in /cfe/trunk: include/clang/AST/Comment.h include/clang/AST/DeclObjC.h lib/AST/ASTContext.cpp lib/AST/Comment.cpp lib/AST/CommentDumper.cpp lib/AST/CommentSema.cpp lib/AST/DeclObjC.cpp test/Index/overriding-method-comments.mm tools/libclang/CXComment.cpp unittests/AST/CommentParser.cpp

Fariborz Jahanian fjahanian at apple.com
Wed Oct 10 11:34:52 PDT 2012


Author: fjahanian
Date: Wed Oct 10 13:34:52 2012
New Revision: 165643

URL: http://llvm.org/viewvc/llvm-project?rev=165643&view=rev
Log:
[Doc parsing] This patch searches overridden objc/c++
methods looking for documentation on a particular base
class inherited by any method that overrides the base class.
In case of redeclaration, as when objc method is defined
in the implementation, it also looks up for documentation
in class/class extension being redeclared.

Added:
    cfe/trunk/test/Index/overriding-method-comments.mm
Modified:
    cfe/trunk/include/clang/AST/Comment.h
    cfe/trunk/include/clang/AST/DeclObjC.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Comment.cpp
    cfe/trunk/lib/AST/CommentDumper.cpp
    cfe/trunk/lib/AST/CommentSema.cpp
    cfe/trunk/lib/AST/DeclObjC.cpp
    cfe/trunk/tools/libclang/CXComment.cpp
    cfe/trunk/unittests/AST/CommentParser.cpp

Modified: cfe/trunk/include/clang/AST/Comment.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Comment.h?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Comment.h (original)
+++ cfe/trunk/include/clang/AST/Comment.h Wed Oct 10 13:34:52 2012
@@ -17,6 +17,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 
@@ -727,7 +728,17 @@
     return getNumArgs() > 0;
   }
 
-  StringRef getParamName() const {
+  StringRef getParamName(const Decl *OverridingDecl) const {
+    if (OverridingDecl && isParamIndexValid()) {
+      if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(OverridingDecl)) {
+        const ParmVarDecl *ParamDecl = OMD->param_begin()[getParamIndex()];
+        return ParamDecl->getName();
+      }
+      else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(OverridingDecl)) {
+        const ParmVarDecl *ParamDecl = FD->param_begin()[getParamIndex()];
+        return ParamDecl->getName();
+      }
+    }
     return Args[0].Text;
   }
 
@@ -936,22 +947,22 @@
 /// Information about the declaration, useful to clients of FullComment.
 struct DeclInfo {
   /// Declaration the comment is attached to.  Should not be NULL.
-  const Decl *ThisDecl;
-
-  /// Parameters that can be referenced by \\param if \c ThisDecl is something
+  const Decl *CommentDecl;
+  
+  /// Parameters that can be referenced by \\param if \c CommentDecl is something
   /// that we consider a "function".
   ArrayRef<const ParmVarDecl *> ParamVars;
 
-  /// Function result type if \c ThisDecl is something that we consider
+  /// Function result type if \c CommentDecl is something that we consider
   /// a "function".
   QualType ResultType;
 
-  /// Template parameters that can be referenced by \\tparam if \c ThisDecl is
+  /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
   /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
   /// true).
   const TemplateParameterList *TemplateParameters;
 
-  /// A simplified description of \c ThisDecl kind that should be good enough
+  /// A simplified description of \c CommentDecl kind that should be good enough
   /// for documentation rendering purposes.
   enum DeclKind {
     /// Everything else not explicitly mentioned below.
@@ -992,7 +1003,7 @@
     EnumKind
   };
 
-  /// What kind of template specialization \c ThisDecl is.
+  /// What kind of template specialization \c CommentDecl is.
   enum TemplateDeclKind {
     NotTemplate,
     Template,
@@ -1000,16 +1011,16 @@
     TemplatePartialSpecialization
   };
 
-  /// If false, only \c ThisDecl is valid.
+  /// If false, only \c CommentDecl is valid.
   unsigned IsFilled : 1;
 
-  /// Simplified kind of \c ThisDecl, see\c DeclKind enum.
+  /// Simplified kind of \c CommentDecl, see\c DeclKind enum.
   unsigned Kind : 3;
 
-  /// Is \c ThisDecl a template declaration.
+  /// Is \c CommentDecl a template declaration.
   unsigned TemplateKind : 2;
 
-  /// Is \c ThisDecl an ObjCMethodDecl.
+  /// Is \c CommentDecl an ObjCMethodDecl.
   unsigned IsObjCMethod : 1;
 
   /// Is \c ThisDecl a non-static member function of C++ class or
@@ -1017,7 +1028,7 @@
   /// Can be true only if \c IsFunctionDecl is true.
   unsigned IsInstanceMethod : 1;
 
-  /// Is \c ThisDecl a static member function of C++ class or
+  /// Is \c CommentDecl a static member function of C++ class or
   /// class method of ObjC class.
   /// Can be true only if \c IsFunctionDecl is true.
   unsigned IsClassMethod : 1;
@@ -1038,11 +1049,16 @@
   llvm::ArrayRef<BlockContentComment *> Blocks;
 
   DeclInfo *ThisDeclInfo;
+  /// Declaration that a comment is being looked for. This declaration and
+  /// CommentDecl in ThisDeclInfo are generally the same. But they could be
+  /// different when ThisDecl does not have comment and uses CommentDecl's comment.
+  const Decl *ThisDecl;
 
 public:
-  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
+  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D,
+              Decl *TD) :
       Comment(FullCommentKind, SourceLocation(), SourceLocation()),
-      Blocks(Blocks), ThisDeclInfo(D) {
+      Blocks(Blocks), ThisDeclInfo(D), ThisDecl(TD) {
     if (Blocks.empty())
       return;
 
@@ -1066,16 +1082,27 @@
   }
 
   const Decl *getDecl() const LLVM_READONLY {
-    return ThisDeclInfo->ThisDecl;
+    return ThisDeclInfo->CommentDecl;
   }
 
+  const Decl *getDeclForCommentLookup() const LLVM_READONLY {
+    return ThisDecl;
+  }
+  
   const DeclInfo *getDeclInfo() const LLVM_READONLY {
     if (!ThisDeclInfo->IsFilled)
       ThisDeclInfo->fill();
     return ThisDeclInfo;
   }
+  
+  DeclInfo *getThisDeclInfo() const LLVM_READONLY {
+    return ThisDeclInfo;
+  }
+  
+  llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
+  
 };
-
+  
 } // end namespace comments
 } // end namespace clang
 

Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Oct 10 13:34:52 2012
@@ -421,7 +421,8 @@
   /// \brief Return overridden methods for the given \p Method.
   ///
   /// An ObjC method is considered to override any method in the class's
-  /// base classes, its protocols, or its categories' protocols, that has
+  /// base classes (and base's categories), its protocols, or its categories'
+  /// protocols, that has
   /// the same selector and is of the same kind (class or instance).
   /// A method in an implementation is not considered as overriding the same
   /// method in the interface or its categories.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Oct 10 13:34:52 2012
@@ -24,6 +24,7 @@
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/Mangle.h"
+#include "clang/AST/Comment.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -355,21 +356,72 @@
   return RC;
 }
 
+static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
+                   SmallVectorImpl<const NamedDecl *> &Redeclared) {
+  const DeclContext *DC = ObjCMethod->getDeclContext();
+  if (const ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(DC)) {
+    const ObjCInterfaceDecl *ID = IMD->getClassInterface();
+    if (!ID)
+      return;
+    // Add redeclared method here.
+    for (const ObjCCategoryDecl *ClsExtDecl = ID->getFirstClassExtension();
+         ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) {
+      if (ObjCMethodDecl *RedeclaredMethod =
+            ClsExtDecl->getMethod(ObjCMethod->getSelector(),
+                                  ObjCMethod->isInstanceMethod()))
+        Redeclared.push_back(RedeclaredMethod);
+    }
+  }
+}
+
 comments::FullComment *ASTContext::getCommentForDecl(
                                               const Decl *D,
                                               const Preprocessor *PP) const {
   D = adjustDeclToTemplate(D);
+  
   const Decl *Canonical = D->getCanonicalDecl();
   llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =
       ParsedComments.find(Canonical);
-  if (Pos != ParsedComments.end())
+  
+  if (Pos != ParsedComments.end()) {
+    if (Canonical != D &&
+        (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D))) {
+      // case of method being redeclaration of the canonical, not
+      // overriding it; i.e. method in implementation, canonical in
+      // interface. Or, out-of-line cxx-method definition. 
+      comments::FullComment *FC = Pos->second;
+      comments::FullComment *CFC =
+        new (*this) comments::FullComment(FC->getBlocks(),
+                                          FC->getThisDeclInfo(),
+                                          const_cast<Decl *>(D));
+      return CFC;
+    }
     return Pos->second;
-
+  }
+  
   const Decl *OriginalDecl;
+  
   const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl);
-  if (!RC)
+  if (!RC) {
+    if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
+      SmallVector<const NamedDecl*, 8> overridden;
+      if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
+        addRedeclaredMethods(OMD, overridden);
+      const_cast<ASTContext *>(this)->getOverriddenMethods(dyn_cast<NamedDecl>(D),
+                                                           overridden);
+      for (unsigned i = 0, e = overridden.size(); i < e; i++) {
+        if (comments::FullComment *FC = getCommentForDecl(overridden[i], PP)) {
+          comments::FullComment *CFC =
+            new (*this) comments::FullComment(FC->getBlocks(),
+                                              FC->getThisDeclInfo(),
+                                              const_cast<Decl *>(D));
+          return CFC;
+        }
+      }
+    }
     return NULL;
-
+  }
+  
   // If the RawComment was attached to other redeclaration of this Decl, we
   // should parse the comment in context of that other Decl.  This is important
   // because comments can contain references to parameter names which can be

Modified: cfe/trunk/lib/AST/Comment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Comment.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Comment.cpp (original)
+++ cfe/trunk/lib/AST/Comment.cpp Wed Oct 10 13:34:52 2012
@@ -151,13 +151,13 @@
   ParamVars = ArrayRef<const ParmVarDecl *>();
   TemplateParameters = NULL;
 
-  if (!ThisDecl) {
+  if (!CommentDecl) {
     // If there is no declaration, the defaults is our only guess.
     IsFilled = true;
     return;
   }
 
-  Decl::Kind K = ThisDecl->getKind();
+  Decl::Kind K = CommentDecl->getKind();
   switch (K) {
   default:
     // Defaults are should be good for declarations we don't handle explicitly.
@@ -167,7 +167,7 @@
   case Decl::CXXConstructor:
   case Decl::CXXDestructor:
   case Decl::CXXConversion: {
-    const FunctionDecl *FD = cast<FunctionDecl>(ThisDecl);
+    const FunctionDecl *FD = cast<FunctionDecl>(CommentDecl);
     Kind = FunctionKind;
     ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
                                               FD->getNumParams());
@@ -181,14 +181,14 @@
 
     if (K == Decl::CXXMethod || K == Decl::CXXConstructor ||
         K == Decl::CXXDestructor || K == Decl::CXXConversion) {
-      const CXXMethodDecl *MD = cast<CXXMethodDecl>(ThisDecl);
+      const CXXMethodDecl *MD = cast<CXXMethodDecl>(CommentDecl);
       IsInstanceMethod = MD->isInstance();
       IsClassMethod = !IsInstanceMethod;
     }
     break;
   }
   case Decl::ObjCMethod: {
-    const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(ThisDecl);
+    const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(CommentDecl);
     Kind = FunctionKind;
     ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
                                               MD->param_size());
@@ -199,7 +199,7 @@
     break;
   }
   case Decl::FunctionTemplate: {
-    const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(ThisDecl);
+    const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(CommentDecl);
     Kind = FunctionKind;
     TemplateKind = Template;
     const FunctionDecl *FD = FTD->getTemplatedDecl();
@@ -210,7 +210,7 @@
     break;
   }
   case Decl::ClassTemplate: {
-    const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(ThisDecl);
+    const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(CommentDecl);
     Kind = ClassKind;
     TemplateKind = Template;
     TemplateParameters = CTD->getTemplateParameters();
@@ -218,7 +218,7 @@
   }
   case Decl::ClassTemplatePartialSpecialization: {
     const ClassTemplatePartialSpecializationDecl *CTPSD =
-        cast<ClassTemplatePartialSpecializationDecl>(ThisDecl);
+        cast<ClassTemplatePartialSpecializationDecl>(CommentDecl);
     Kind = ClassKind;
     TemplateKind = TemplatePartialSpecialization;
     TemplateParameters = CTPSD->getTemplateParameters();
@@ -246,7 +246,7 @@
     Kind = TypedefKind;
     // If this is a typedef to something we consider a function, extract
     // arguments and return type.
-    const TypedefDecl *TD = cast<TypedefDecl>(ThisDecl);
+    const TypedefDecl *TD = cast<TypedefDecl>(CommentDecl);
     const TypeSourceInfo *TSI = TD->getTypeSourceInfo();
     if (!TSI)
       break;
@@ -290,7 +290,7 @@
     Kind = TypedefKind;
     break;
   case Decl::TypeAliasTemplate: {
-    const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(ThisDecl);
+    const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(CommentDecl);
     Kind = TypedefKind;
     TemplateKind = Template;
     TemplateParameters = TAT->getTemplateParameters();

Modified: cfe/trunk/lib/AST/CommentDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentDumper.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentDumper.cpp (original)
+++ cfe/trunk/lib/AST/CommentDumper.cpp Wed Oct 10 13:34:52 2012
@@ -183,7 +183,7 @@
     OS << " implicitly";
 
   if (C->hasParamName())
-    OS << " Param=\"" << C->getParamName() << "\"";
+    OS << " Param=\"" << C->getParamName(0) << "\"";
 
   if (C->isParamIndexValid())
     OS << " ParamIndex=" << C->getParamIndex();

Modified: cfe/trunk/lib/AST/CommentSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentSema.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentSema.cpp (original)
+++ cfe/trunk/lib/AST/CommentSema.cpp Wed Oct 10 13:34:52 2012
@@ -36,7 +36,7 @@
     return;
 
   ThisDeclInfo = new (Allocator) DeclInfo;
-  ThisDeclInfo->ThisDecl = D;
+  ThisDeclInfo->CommentDecl = D;
   ThisDeclInfo->IsFilled = false;
 }
 
@@ -413,7 +413,7 @@
 
 FullComment *Sema::actOnFullComment(
                               ArrayRef<BlockContentComment *> Blocks) {
-  FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo);
+  FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo, 0);
   resolveParamCommandIndexes(FC);
   return FC;
 }
@@ -441,7 +441,7 @@
   if (isFunctionDecl()) {
     if (ThisDeclInfo->ResultType->isVoidType()) {
       unsigned DiagKind;
-      switch (ThisDeclInfo->ThisDecl->getKind()) {
+      switch (ThisDeclInfo->CommentDecl->getKind()) {
       default:
         if (ThisDeclInfo->IsObjCMethod)
           DiagKind = 3;
@@ -508,7 +508,7 @@
   if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand)
     return;
 
-  const Decl *D = ThisDeclInfo->ThisDecl;
+  const Decl *D = ThisDeclInfo->CommentDecl;
   if (!D)
     return;
 
@@ -574,7 +574,7 @@
     ParamCommandComment *PCC = dyn_cast<ParamCommandComment>(*I);
     if (!PCC || !PCC->hasParamName())
       continue;
-    StringRef ParamName = PCC->getParamName();
+    StringRef ParamName = PCC->getParamName(0);
 
     // Check that referenced parameter name is in the function decl.
     const unsigned ResolvedParamIndex = resolveParmVarReference(ParamName,
@@ -609,7 +609,7 @@
     const ParamCommandComment *PCC = UnresolvedParamCommands[i];
 
     SourceRange ArgRange = PCC->getParamNameRange();
-    StringRef ParamName = PCC->getParamName();
+    StringRef ParamName = PCC->getParamName(0);
     Diag(ArgRange.getBegin(), diag::warn_doc_param_not_found)
       << ParamName << ArgRange;
 

Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Wed Oct 10 13:34:52 2012
@@ -859,6 +859,8 @@
 /// overrides lookup that it does for methods, inside implementations, will
 /// stop at the interface level (if there is a method there) and not look
 /// further in super classes.
+/// Methods in an implementation can overide methods in super class's category
+/// but not in current class's category. But, such methods
 static void collectOverriddenMethodsFast(SourceManager &SM,
                                          const ObjCMethodDecl *Method,
                              SmallVectorImpl<const ObjCMethodDecl *> &Methods) {

Added: cfe/trunk/test/Index/overriding-method-comments.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/overriding-method-comments.mm?rev=165643&view=auto
==============================================================================
--- cfe/trunk/test/Index/overriding-method-comments.mm (added)
+++ cfe/trunk/test/Index/overriding-method-comments.mm Wed Oct 10 13:34:52 2012
@@ -0,0 +1,111 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s > %t/out
+// RUN: FileCheck %s < %t/out
+// rdar://12378793
+
+// Ensure that XML we generate is not invalid.
+// RUN: FileCheck %s -check-prefix=WRONG < %t/out
+// WRONG-NOT: CommentXMLInvalid
+
+ at protocol P
+- (void)METH:(id)PPP;
+ at end
+
+ at interface Root<P>
+/**
+ * \param[in] AAA ZZZ
+ */
+- (void)METH:(id)AAA;
+ at end
+
+ at interface Sub : Root
+ at end
+
+ at interface Sub (CAT)
+- (void)METH:(id)BBB;
+ at end
+
+ at implementation Sub(CAT)
+- (void)METH:(id)III {}
+ at end
+
+// CHECK: FullCommentAsHTML=[<dl><dt class="param-name-index-0">AAA</dt><dd class="param-descr-index-0"> ZZZ </dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="19" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<dl><dt class="param-name-index-0">BBB</dt><dd class="param-descr-index-0"> ZZZ </dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="19" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Parameters><Parameter><Name>BBB</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<dl><dt class="param-name-index-0">III</dt><dd class="param-descr-index-0"> ZZZ </dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="19" column="1"><Name>METH:</Name><USR>c:objc(cs)Root(im)METH:</USR><Parameters><Parameter><Name>III</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> ZZZ </Para></Discussion></Parameter></Parameters></Function>
+
+ at interface Redec : Root
+ at end
+
+ at interface Redec()
+/**
+ * \param[in] AAA input value  
+ * \param[out] CCC output value is int 
+ * \param[in] BBB 2nd input value is double 
+ */
+- (void)EXT_METH:(id)AAA : (double)BBB : (int)CCC;
+ at end
+
+ at implementation Redec
+- (void)EXT_METH:(id)PPP : (double)QQQ : (int)RRR {}
+ at end
+
+// CHECK: FullCommentAsHTML=[<dl><dt class="param-name-index-0">AAA</dt><dd class="param-descr-index-0"> input value   </dd><dt class="param-name-index-1">BBB</dt><dd class="param-descr-index-1"> 2nd input value is double  </dd><dt class="param-name-index-2">CCC</dt><dd class="param-descr-index-2"> output value is int  </dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="48" column="1"><Name>EXT_METH:::</Name><USR>c:objc(cs)Redec(im)EXT_METH:::</USR><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> input value   </Para></Discussion></Parameter><Parameter><Name>BBB</Name><Index>1</Index><Direction isExplicit="1">in</Direction><Discussion><Para> 2nd input value is double  </Para></Discussion></Parameter><Parameter><Name>CCC</Name><Index>2</Index><Direction isExplicit="1">out</Direction><Discussion><Para> output value is int  </Para></Discussion></Paramete
 r></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<dl><dt class="param-name-index-0">PPP</dt><dd class="param-descr-index-0"> input value   </dd><dt class="param-name-index-1">QQQ</dt><dd class="param-descr-index-1"> 2nd input value is double  </dd><dt class="param-name-index-2">RRR</dt><dd class="param-descr-index-2"> output value is int  </dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="48" column="1"><Name>EXT_METH:::</Name><USR>c:objc(cs)Redec(im)EXT_METH:::</USR><Parameters><Parameter><Name>PPP</Name><Index>0</Index><Direction isExplicit="1">in</Direction><Discussion><Para> input value   </Para></Discussion></Parameter><Parameter><Name>QQQ</Name><Index>1</Index><Direction isExplicit="1">in</Direction><Discussion><Para> 2nd input value is double  </Para></Discussion></Parameter><Parameter><Name>RRR</Name><Index>2</Index><Direction isExplicit="1">out</Direction><Discussion><Para> output value is int  </Para></Discussion></Paramete
 r></Parameters></Function>
+
+struct Base {
+  /// \brief Does something.
+  /// \param AAA argument to foo_pure.
+  virtual void foo_pure(int AAA) = 0;
+
+  /// \brief Does something.
+  /// \param BBB argument to defined virtual.
+  virtual void foo_inline(int BBB) {}
+
+  /// \brief Does something.
+  /// \param CCC argument to undefined virtual.
+  virtual void foo_outofline(int CCC);
+};
+
+void Base::foo_outofline(int RRR) {}
+
+struct Derived : public Base {
+  virtual void foo_pure(int PPP);
+
+  virtual void foo_inline(int QQQ) {}
+};
+
+/// \brief Does something.
+/// \param DDD a value.
+void foo(int DDD);
+
+void foo(int SSS) {}
+
+/// \brief Does something.
+/// \param EEE argument to function decl. 
+void foo1(int EEE);
+
+void foo1(int TTT);
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">AAA</dt><dd class="param-descr-index-0"> argument to foo_pure.</dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="62" column="16"><Name>foo_pure</Name><USR>c:@S at Base@F at foo_pure#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>AAA</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to foo_pure.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">BBB</dt><dd class="param-descr-index-0"> argument to defined virtual.</dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="66" column="16"><Name>foo_inline</Name><USR>c:@S at Base@F at foo_inline#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>BBB</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to defined virtual.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">CCC</dt><dd class="param-descr-index-0"> argument to undefined virtual.</dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="70" column="16"><Name>foo_outofline</Name><USR>c:@S at Base@F at foo_outofline#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>CCC</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to undefined virtual.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">RRR</dt><dd class="param-descr-index-0"> argument to undefined virtual.</dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="70" column="16"><Name>foo_outofline</Name><USR>c:@S at Base@F at foo_outofline#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>RRR</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to undefined virtual.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">PPP</dt><dd class="param-descr-index-0"> argument to foo_pure.</dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="62" column="16"><Name>foo_pure</Name><USR>c:@S at Base@F at foo_pure#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>PPP</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to foo_pure.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">QQQ</dt><dd class="param-descr-index-0"> argument to defined virtual.</dd></dl>] FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="66" column="16"><Name>foo_inline</Name><USR>c:@S at Base@F at foo_inline#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>QQQ</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to defined virtual.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">DDD</dt><dd class="param-descr-index-0"> a value.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}overriding-method-comments.mm" line="83" column="6"><Name>foo</Name><USR>c:@F at foo#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>DDD</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> a value.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">SSS</dt><dd class="param-descr-index-0"> a value.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}overriding-method-comments.mm" line="83" column="6"><Name>foo</Name><USR>c:@F at foo#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>SSS</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> a value.</Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">EEE</dt><dd class="param-descr-index-0"> argument to function decl. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}overriding-method-comments.mm" line="89" column="6"><Name>foo1</Name><USR>c:@F at foo1#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>EEE</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to function decl. </Para></Discussion></Parameter></Parameters></Function>
+
+// CHECK: FullCommentAsHTML=[<p class="para-brief"> Does something. </p><dl><dt class="param-name-index-0">TTT</dt><dd class="param-descr-index-0"> argument to function decl. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}overriding-method-comments.mm" line="89" column="6"><Name>foo1</Name><USR>c:@F at foo1#I#</USR><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>TTT</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to function decl. </Para></Discussion></Parameter></Parameters></Function>

Modified: cfe/trunk/tools/libclang/CXComment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXComment.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXComment.cpp (original)
+++ cfe/trunk/tools/libclang/CXComment.cpp Wed Oct 10 13:34:52 2012
@@ -254,7 +254,7 @@
   if (!PCC || !PCC->hasParamName())
     return createCXString((const char *) 0);
 
-  return createCXString(PCC->getParamName(), /*DupString=*/ false);
+  return createCXString(PCC->getParamName(0), /*DupString=*/ false);
 }
 
 unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
@@ -535,9 +535,10 @@
     public ConstCommentVisitor<CommentASTToHTMLConverter> {
 public:
   /// \param Str accumulator for HTML.
-  CommentASTToHTMLConverter(SmallVectorImpl<char> &Str,
+  CommentASTToHTMLConverter(FullComment *FC,
+                            SmallVectorImpl<char> &Str,
                             const CommandTraits &Traits) :
-      Result(Str), Traits(Traits)
+      FC(FC), Result(Str), Traits(Traits)
   { }
 
   // Inline content.
@@ -566,6 +567,7 @@
   void appendToResultWithHTMLEscaping(StringRef S);
 
 private:
+  FullComment *FC;
   /// Output stream for HTML.
   llvm::raw_svector_ostream Result;
 
@@ -669,7 +671,7 @@
   } else
     Result << "<dt class=\"param-name-index-invalid\">";
 
-  appendToResultWithHTMLEscaping(C->getParamName());
+  appendToResultWithHTMLEscaping(C->getParamName(FC->getDeclForCommentLookup()));
   Result << "</dt>";
 
   if (C->isParamIndexValid()) {
@@ -827,7 +829,7 @@
     return createCXString((const char *) 0);
 
   SmallString<128> HTML;
-  CommentASTToHTMLConverter Converter(HTML, getCommandTraits(CXC));
+  CommentASTToHTMLConverter Converter(0, HTML, getCommandTraits(CXC));
   Converter.visit(HTC);
   return createCXString(HTML.str(), /* DupString = */ true);
 }
@@ -838,7 +840,8 @@
     return createCXString((const char *) 0);
 
   SmallString<1024> HTML;
-  CommentASTToHTMLConverter Converter(HTML, getCommandTraits(CXC));
+  CommentASTToHTMLConverter Converter(const_cast<FullComment *>(FC),
+                                      HTML, getCommandTraits(CXC));
   Converter.visit(FC);
   return createCXString(HTML.str(), /* DupString = */ true);
 }
@@ -850,10 +853,11 @@
     public ConstCommentVisitor<CommentASTToXMLConverter> {
 public:
   /// \param Str accumulator for XML.
-  CommentASTToXMLConverter(SmallVectorImpl<char> &Str,
+  CommentASTToXMLConverter(FullComment *FC,
+                           SmallVectorImpl<char> &Str,
                            const CommandTraits &Traits,
                            const SourceManager &SM) :
-      Result(Str), Traits(Traits), SM(SM) { }
+      FC(FC), Result(Str), Traits(Traits), SM(SM) { }
 
   // Inline content.
   void visitTextComment(const TextComment *C);
@@ -876,6 +880,8 @@
   void appendToResultWithXMLEscaping(StringRef S);
 
 private:
+  FullComment *FC;
+      
   /// Output stream for XML.
   llvm::raw_svector_ostream Result;
 
@@ -954,7 +960,7 @@
 
 void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
   Result << "<Parameter><Name>";
-  appendToResultWithXMLEscaping(C->getParamName());
+  appendToResultWithXMLEscaping(C->getParamName(FC->getDeclForCommentLookup()));
   Result << "</Name>";
 
   if (C->isParamIndexValid())
@@ -1090,7 +1096,7 @@
 
     {
       // Print line and column number.
-      SourceLocation Loc = DI->ThisDecl->getLocation();
+      SourceLocation Loc = DI->CommentDecl->getLocation();
       std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
       FileID FID = LocInfo.first;
       unsigned FileOffset = LocInfo.second;
@@ -1111,7 +1117,7 @@
     Result << ">";
 
     bool FoundName = false;
-    if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->ThisDecl)) {
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) {
       if (DeclarationName DeclName = ND->getDeclName()) {
         Result << "<Name>";
         std::string Name = DeclName.getAsString();
@@ -1126,7 +1132,7 @@
     {
       // Print USR.
       SmallString<128> USR;
-      cxcursor::getDeclCursorUSR(DI->ThisDecl, USR);
+      cxcursor::getDeclCursorUSR(DI->CommentDecl, USR);
       if (!USR.empty()) {
         Result << "<USR>";
         appendToResultWithXMLEscaping(USR);
@@ -1171,8 +1177,8 @@
     Result << "</ResultDiscussion>";
   }
   
-  if (DI->ThisDecl->hasAttrs()) {
-    const AttrVec &Attrs = DI->ThisDecl->getAttrs();
+  if (DI->CommentDecl->hasAttrs()) {
+    const AttrVec &Attrs = DI->CommentDecl->getAttrs();
     for (unsigned i = 0, e = Attrs.size(); i != e; i++) {
       const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]);
       if (!AA) {
@@ -1295,7 +1301,8 @@
   SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
 
   SmallString<1024> XML;
-  CommentASTToXMLConverter Converter(XML, getCommandTraits(CXC), SM);
+  CommentASTToXMLConverter Converter(const_cast<FullComment *>(FC), XML,
+                                     getCommandTraits(CXC), SM);
   Converter.visit(FC);
   return createCXString(XML.str(), /* DupString = */ true);
 }

Modified: cfe/trunk/unittests/AST/CommentParser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CommentParser.cpp?rev=165643&r1=165642&r2=165643&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/CommentParser.cpp (original)
+++ cfe/trunk/unittests/AST/CommentParser.cpp Wed Oct 10 13:34:52 2012
@@ -213,7 +213,7 @@
     return ::testing::AssertionFailure()
         << "ParamCommandComment has no parameter name";
 
-  StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamName() : "";
+  StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamName(0) : "";
   if (ActualParamName != ParamName)
     return ::testing::AssertionFailure()
         << "ParamCommandComment has parameter name \"" << ActualParamName.str()





More information about the cfe-commits mailing list