Comment parsing: handle non-builtin commands correctly. After semantic

analysis registers a command, it becomes a "known" command for the lexer, since
it has an ID.  Having this freedom of choice to register a command is a good
thing since BriefParser does not need this.

But the parser should still invoke the correct semantic analysis method
(actOnUnknownCommand) in this case.

llvm-svn: 163646
This commit is contained in:
Dmitri Gribenko 2012-09-11 19:22:03 +00:00
parent 1778831a3d
commit 9304d86329
6 changed files with 28 additions and 5 deletions

View File

@ -34,8 +34,8 @@ enum TokenKind {
eof,
newline,
text,
unknown_command,
command,
unknown_command, // Command that does not have an ID.
command, // Command with an ID.
verbatim_block_begin,
verbatim_block_line,
verbatim_block_end,

View File

@ -139,7 +139,11 @@ public:
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
StringRef Name);
StringRef CommandName);
InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
unsigned CommandID);
TextComment *actOnText(SourceLocation LocBegin,
SourceLocation LocEnd,

View File

@ -40,6 +40,7 @@ const CommandInfo *CommandTraits::registerUnknownCommand(StringRef CommandName)
CommandInfo *Info = new (Allocator) CommandInfo();
Info->Name = Name;
Info->ID = NextID++;
Info->IsUnknownCommand = true;
RegisteredCommands.push_back(Info);

View File

@ -554,6 +554,13 @@ BlockContentComment *Parser::parseParagraphOrBlockCommand() {
return parseBlockCommand();
break; // Block command ahead, finish this parapgaph.
}
if (Info->IsUnknownCommand) {
Content.push_back(S.actOnUnknownCommand(Tok.getLocation(),
Tok.getEndLocation(),
Info->getID()));
consumeToken();
continue;
}
assert(Info->IsInlineCommand);
Content.push_back(parseInlineCommand());
continue;

View File

@ -272,9 +272,15 @@ InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
StringRef Name) {
StringRef CommandName) {
unsigned CommandID = Traits.registerUnknownCommand(CommandName)->getID();
return actOnUnknownCommand(LocBegin, LocEnd, CommandID);
}
InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd,
unsigned CommandID) {
ArrayRef<InlineCommandComment::Argument> Args;
unsigned CommandID = Traits.registerUnknownCommand(Name)->getID();
return new (Allocator) InlineCommandComment(
LocBegin, LocEnd, CommandID,
InlineCommandComment::RenderNormal,

View File

@ -761,3 +761,8 @@ inline void test_nocrash6()
*/
typedef const struct test_nocrash7 * test_nocrash8;
// We used to crash on this.
/// aaa \unknown aaa \unknown aaa
int test_nocrash9;