Correctly update diff from original base.

Hi indygreg, gribozavr, doug.gregor,

http://llvm-reviews.chandlerc.com/D272

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D272?vs=881&id=882#toc

Files:
  include/clang/AST/CommentCommandTraits.h
  include/clang/Basic/CommentOptions.h
  include/clang/Basic/LangOptions.h
  include/clang/Driver/Options.td
  lib/AST/ASTContext.cpp
  lib/AST/CommentCommandTraits.cpp
  lib/Driver/Tools.cpp
  lib/Frontend/ASTUnit.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/Driver/fcomment-block-commands.c
  test/Index/comment-custom-block-command.cpp
  unittests/AST/CommentLexer.cpp
  unittests/AST/CommentParser.cpp
Index: include/clang/AST/CommentCommandTraits.h
===================================================================
--- include/clang/AST/CommentCommandTraits.h
+++ include/clang/AST/CommentCommandTraits.h
@@ -16,6 +16,7 @@
 #ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
 #define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
 
+#include "clang/Basic/CommentOptions.h"
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
@@ -116,7 +117,10 @@
     KCI_Last
   };
 
-  CommandTraits(llvm::BumpPtrAllocator &Allocator);
+  CommandTraits(llvm::BumpPtrAllocator &Allocator,
+                const CommentOptions &CommentOptions);
+
+  void RegisterCommentOptions(const CommentOptions &CommentOptions);
 
   /// \returns a CommandInfo object for a given command name or
   /// NULL if no CommandInfo object exists for this command.
@@ -132,6 +136,8 @@
 
   const CommandInfo *registerUnknownCommand(StringRef CommandName);
 
+  const CommandInfo *registerBlockCommand(StringRef CommandName);
+
   /// \returns a CommandInfo object for a given command name or
   /// NULL if \c Name is not a builtin command.
   static const CommandInfo *getBuiltinCommandInfo(StringRef Name);
@@ -147,6 +153,8 @@
   const CommandInfo *getRegisteredCommandInfo(StringRef Name) const;
   const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const;
 
+  CommandInfo *createCommandInfoWithName(StringRef CommandName);
+
   unsigned NextID;
 
   /// Allocator for CommandInfo objects.
Index: include/clang/Basic/CommentOptions.h
===================================================================
--- /dev/null
+++ include/clang/Basic/CommentOptions.h
@@ -0,0 +1,34 @@
+//===--- CommentOptions.h - Options for parsing comments -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the clang::CommentOptions interface.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_COMMENTOPTIONS_H
+#define LLVM_CLANG_COMMENTOPTIONS_H
+
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// \brief Options for controlling comment parsing.
+struct CommentOptions {
+  typedef std::vector<std::string> BlockCommandNamesTy;
+
+  /// \brief Command names to treat as block commands in comments.
+  /// Should not include the leading backslash.
+  BlockCommandNamesTy BlockCommandNames;
+};
+
+}  // end namespace clang
+
+#endif
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h
+++ include/clang/Basic/LangOptions.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_LANGOPTIONS_H
 #define LLVM_CLANG_LANGOPTIONS_H
 
+#include "clang/Basic/CommentOptions.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/Visibility.h"
@@ -78,6 +79,9 @@
 
   /// \brief The name of the current module.
   std::string CurrentModule;
+
+  /// \brief Options for parsing comments.
+  CommentOptions CommentOpts;
   
   LangOptions();
 
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -327,6 +327,9 @@
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Use colors in diagnostics">;
+def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>,
+  HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">,
+  MetaVarName<"<arg>">;
 def fcommon : Flag<["-"], "fcommon">, Group<f_Group>;
 def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>;
 def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>;
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -654,7 +654,7 @@
     DeclarationNames(*this),
     ExternalSource(0), Listener(0),
     Comments(SM), CommentsLoaded(false),
-    CommentCommandTraits(BumpAlloc),
+    CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
     LastSDM(0, 0),
     UniqueBlockByRefTypeID(0)
 {
Index: lib/AST/CommentCommandTraits.cpp
===================================================================
--- lib/AST/CommentCommandTraits.cpp
+++ lib/AST/CommentCommandTraits.cpp
@@ -15,9 +15,21 @@
 
 #include "clang/AST/CommentCommandInfo.inc"
 
-CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator) :
-    NextID(llvm::array_lengthof(Commands)), Allocator(Allocator)
-{ }
+CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator,
+                             const CommentOptions &CommentOptions) :
+    NextID(llvm::array_lengthof(Commands)), Allocator(Allocator) {
+  RegisterCommentOptions(CommentOptions);
+}
+
+void CommandTraits::RegisterCommentOptions(
+  const CommentOptions &CommentOptions) {
+  for (CommentOptions::BlockCommandNamesTy::const_iterator I =
+         CommentOptions.BlockCommandNames.begin();
+       I != CommentOptions.BlockCommandNames.end();
+       I++) {
+    registerBlockCommand(*I);
+  }
+}
 
 const CommandInfo *CommandTraits::getCommandInfoOrNULL(StringRef Name) const {
   if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
@@ -31,22 +43,37 @@
   return getRegisteredCommandInfo(CommandID);
 }
 
-const CommandInfo *CommandTraits::registerUnknownCommand(StringRef CommandName) {
+CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
   char *Name = Allocator.Allocate<char>(CommandName.size() + 1);
   memcpy(Name, CommandName.data(), CommandName.size());
   Name[CommandName.size()] = '\0';
 
   // Value-initialize (=zero-initialize in this case) a new CommandInfo.
   CommandInfo *Info = new (Allocator) CommandInfo();
   Info->Name = Name;
   Info->ID = NextID++;
+
+  return Info;
+}
+
+const CommandInfo *CommandTraits::registerUnknownCommand(StringRef CommandName) {
+  CommandInfo *Info = createCommandInfoWithName(CommandName);
   Info->IsUnknownCommand = true;
 
   RegisteredCommands.push_back(Info);
 
   return Info;
 }
 
+const CommandInfo *CommandTraits::registerBlockCommand(StringRef CommandName) {
+  CommandInfo *Info = createCommandInfoWithName(CommandName);
+  Info->IsBlockCommand = true;
+
+  RegisteredCommands.push_back(Info);
+
+  return Info;
+}
+
 const CommandInfo *CommandTraits::getBuiltinCommandInfo(
                                                   unsigned CommandID) {
   if (CommandID < llvm::array_lengthof(Commands))
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3113,6 +3113,9 @@
   if (Args.hasArg(options::OPT_fretain_comments_from_system_headers))
     CmdArgs.push_back("-fretain-comments-from-system-headers");
 
+  // Forward -fcomment-block-commands to -cc1.
+  Args.AddAllArgs(CmdArgs, options::OPT_fcomment_block_commands);
+
   // Forward -Xclang arguments to -cc1, and -mllvm arguments to the LLVM option
   // parser.
   Args.AddAllArgValues(CmdArgs, options::OPT_Xclang);
Index: lib/Frontend/ASTUnit.cpp
===================================================================
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -573,6 +573,11 @@
 
     // Initialize the ASTContext
     Context.InitBuiltinTypes(*Target);
+
+    // We didn't have access to the comment options when the Context was
+    // constructed, so register them now.
+    Context.getCommentCommandTraits().RegisterCommentOptions(
+      LangOpt.CommentOpts);
   }
 };
 
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -279,6 +279,10 @@
   return true;
 }
 
+static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) {
+  Opts.BlockCommandNames = Args.getAllArgValues(OPT_fcomment_block_commands);
+}
+
 static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
                              DiagnosticsEngine &Diags) {
   using namespace options;
@@ -1496,6 +1500,7 @@
   ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
   Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, &Diags)
             && Success;
+  ParseCommentArgs(Res.getLangOpts()->CommentOpts, *Args);
   ParseFileSystemArgs(Res.getFileSystemOpts(), *Args);
   // FIXME: We shouldn't have to pass the DashX option around here
   InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags);
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -3633,6 +3633,15 @@
   unsigned Length = Record[Idx++];
   LangOpts.CurrentModule.assign(Record.begin() + Idx, 
                                 Record.begin() + Idx + Length);
+
+  Idx += Length;
+
+  // Comment options.
+  for (unsigned N = Record[Idx++]; N; --N) {
+    LangOpts.CommentOpts.BlockCommandNames.push_back(
+      ReadString(Record, Idx));
+  }
+
   return Listener.ReadLanguageOptions(LangOpts, Complain);
 }
 
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -1057,6 +1057,19 @@
   
   Record.push_back(LangOpts.CurrentModule.size());
   Record.append(LangOpts.CurrentModule.begin(), LangOpts.CurrentModule.end());
+
+  // Comment options.
+  Record.push_back(LangOpts.CommentOpts.BlockCommandNames.size());
+  for (CommentOptions::BlockCommandNamesTy::const_iterator I =
+         LangOpts.CommentOpts.BlockCommandNames.begin(), IEnd =
+         LangOpts.CommentOpts.BlockCommandNames.end();
+       I != IEnd;
+       ++I) {
+    const std::string& BlockCommandName = *I;
+    Record.push_back(BlockCommandName.size());
+    Record.append(BlockCommandName.begin(), BlockCommandName.end());
+  }
+
   Stream.EmitRecord(LANGUAGE_OPTIONS, Record);
 
   // Target options.
Index: test/Driver/fcomment-block-commands.c
===================================================================
--- /dev/null
+++ test/Driver/fcomment-block-commands.c
@@ -0,0 +1,8 @@
+// Check that we pass -fcomment-block-commands to frontend.
+//
+// RUN: %clang -c %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RETAIN
+// RUN: %clang -c %s -fcomment-block-commands=Foo -### 2>&1 | FileCheck %s --check-prefix=CHECK-RETAIN
+//
+// CHECK-RETAIN: -fcomment-block-commands=Foo
+//
+// CHECK-NO-RETAIN-NOT: -fcomment-block-commands=Foo
Index: test/Index/comment-custom-block-command.cpp
===================================================================
--- /dev/null
+++ test/Index/comment-custom-block-command.cpp
@@ -0,0 +1,38 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// Check that custom block commands are defined correctly.
+// RUN: %clang_cc1 -fcomment-block-commands=CustomCommand -x c++ -std=c++11 -emit-pch -o %t/out.pch %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t/out.pch -fsyntax-only %s
+
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 -fcomment-block-commands=CustomCommand > %t/out.c-index-direct
+// RUN: c-index-test -test-load-tu %t/out.pch all -fcomment-block-commands=CustomCommand > %t/out.c-index-pch
+
+// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct
+// RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-pch
+
+// Ensure that XML is not invalid
+// WRONG-NOT: CommentXMLInvalid
+
+// RUN: FileCheck %s < %t/out.c-index-direct
+// RUN: FileCheck %s < %t/out.c-index-pch
+
+// XFAIL: valgrind
+
+#ifndef HEADER
+#define HEADER
+
+/// \CustomCommand Aaa.
+void comment_custom_block_command_1();
+
+// CHECK: comment-custom-block-command.cpp:[[@LINE-2]]:6: FunctionDecl=comment_custom_block_command_1:{{.*}} FullCommentAsHTML=[<p> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}comment-custom-block-command.cpp" line="[[@LINE-2]]" column="6"><Name>comment_custom_block_command_1</Name><USR>c:@F@comment_custom_block_command_1#</USR><Declaration>void comment_custom_block_command_1()</Declaration><Discussion><Para> Aaa.</Para></Discussion></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_BlockCommand CommandName=[CustomCommand]
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
+
+#endif
+
Index: unittests/AST/CommentLexer.cpp
===================================================================
--- unittests/AST/CommentLexer.cpp
+++ unittests/AST/CommentLexer.cpp
@@ -9,6 +9,7 @@
 
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentCommandTraits.h"
+#include "clang/Basic/CommentOptions.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -31,7 +32,7 @@
       DiagID(new DiagnosticIDs()),
       Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
-      Traits(Allocator) {
+      Traits(Allocator, CommentOptions()) {
   }
 
   FileSystemOptions FileMgrOpts;
@@ -451,6 +452,76 @@
   ASSERT_EQ(tok::newline,   Toks[2].getKind());
 }
 
+TEST_F(CommentLexerTest, RegisterCustomBlockCommand) {
+  const char *Source = "/// \\NewBlockCommand Aaa.\n";
+
+  Traits.registerBlockCommand(StringRef("NewBlockCommand"));
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,      Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "), Toks[0].getText());
+
+  ASSERT_EQ(tok::command,                 Toks[1].getKind());
+  ASSERT_EQ(StringRef("NewBlockCommand"), getCommandName(Toks[1]));
+
+  ASSERT_EQ(tok::text,          Toks[2].getKind());
+  ASSERT_EQ(StringRef(" Aaa."), Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,        Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, RegisterMultipleBlockCommands) {
+  const char *Source =
+    "/// \\Foo\n"
+    "/// \\Bar Baz\n"
+    "/// \\Blech quux=corge\n";
+
+  Traits.registerBlockCommand(StringRef("Foo"));
+  Traits.registerBlockCommand(StringRef("Bar"));
+  Traits.registerBlockCommand(StringRef("Blech"));
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(11U, Toks.size());
+
+  ASSERT_EQ(tok::text,      Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "), Toks[0].getText());
+
+  ASSERT_EQ(tok::command,     Toks[1].getKind());
+  ASSERT_EQ(StringRef("Foo"), getCommandName(Toks[1]));
+
+  ASSERT_EQ(tok::newline,     Toks[2].getKind());
+
+  ASSERT_EQ(tok::text,      Toks[3].getKind());
+  ASSERT_EQ(StringRef(" "), Toks[3].getText());
+
+  ASSERT_EQ(tok::command,     Toks[4].getKind());
+  ASSERT_EQ(StringRef("Bar"), getCommandName(Toks[4]));
+
+  ASSERT_EQ(tok::text,         Toks[5].getKind());
+  ASSERT_EQ(StringRef(" Baz"), Toks[5].getText());
+
+  ASSERT_EQ(tok::newline,     Toks[6].getKind());
+
+  ASSERT_EQ(tok::text,      Toks[7].getKind());
+  ASSERT_EQ(StringRef(" "), Toks[7].getText());
+
+  ASSERT_EQ(tok::command,       Toks[8].getKind());
+  ASSERT_EQ(StringRef("Blech"), getCommandName(Toks[8]));
+
+  ASSERT_EQ(tok::text,                Toks[9].getKind());
+  ASSERT_EQ(StringRef(" quux=corge"), Toks[9].getText());
+
+  ASSERT_EQ(tok::newline,     Toks[10].getKind());
+}
+
 // Empty verbatim block.
 TEST_F(CommentLexerTest, VerbatimBlock1) {
   const char *Sources[] = {
Index: unittests/AST/CommentParser.cpp
===================================================================
--- unittests/AST/CommentParser.cpp
+++ unittests/AST/CommentParser.cpp
@@ -12,6 +12,7 @@
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentSema.h"
+#include "clang/Basic/CommentOptions.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
@@ -38,7 +39,7 @@
       DiagID(new DiagnosticIDs()),
       Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
       SourceMgr(Diags, FileMgr),
-      Traits(Allocator) {
+      Traits(Allocator, CommentOptions()) {
   }
 
   FileSystemOptions FileMgrOpts;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to