clang 20.0.0git
CommentCommandTraits.cpp
Go to the documentation of this file.
1//===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/STLExtras.h"
11#include <cassert>
12
13namespace clang {
14namespace comments {
15
16#include "clang/AST/CommentCommandInfo.inc"
17
18CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator,
20 : NextID(std::size(Commands)), Allocator(Allocator) {
22}
23
26 for (CommentOptions::BlockCommandNamesTy::const_iterator
29 I != E; I++) {
31 }
32}
33
35 if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
36 return Info;
37 return getRegisteredCommandInfo(Name);
38}
39
40const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
41 if (const CommandInfo *Info = getBuiltinCommandInfo(CommandID))
42 return Info;
43 return getRegisteredCommandInfo(CommandID);
44}
45
46const CommandInfo *
48 // Single-character command impostures, such as \t or \n, should not go
49 // through the fixit logic.
50 if (Typo.size() <= 1)
51 return nullptr;
52
53 // The maximum edit distance we're prepared to accept.
54 const unsigned MaxEditDistance = 1;
55
56 unsigned BestEditDistance = MaxEditDistance;
58
59 auto ConsiderCorrection = [&](const CommandInfo *Command) {
60 StringRef Name = Command->Name;
61
62 unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
63 if (MinPossibleEditDistance <= BestEditDistance) {
64 unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
65 if (EditDistance < BestEditDistance) {
66 BestEditDistance = EditDistance;
67 BestCommand.clear();
68 }
69 if (EditDistance == BestEditDistance)
70 BestCommand.push_back(Command);
71 }
72 };
73
74 for (const auto &Command : Commands)
75 ConsiderCorrection(&Command);
76
77 for (const auto *Command : RegisteredCommands)
78 if (!Command->IsUnknownCommand)
79 ConsiderCorrection(Command);
80
81 return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
82}
83
84CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
85 char *Name = Allocator.Allocate<char>(CommandName.size() + 1);
86 memcpy(Name, CommandName.data(), CommandName.size());
87 Name[CommandName.size()] = '\0';
88
89 // Value-initialize (=zero-initialize in this case) a new CommandInfo.
90 CommandInfo *Info = new (Allocator) CommandInfo();
91 Info->Name = Name;
92 // We only have a limited number of bits to encode command IDs in the
93 // CommandInfo structure, so the ID numbers can potentially wrap around.
94 assert((NextID < (1 << CommandInfo::NumCommandIDBits))
95 && "Too many commands. We have limited bits for the command ID.");
96 Info->ID = NextID++;
97
98 RegisteredCommands.push_back(Info);
99
100 return Info;
101}
102
104 StringRef CommandName) {
105 CommandInfo *Info = createCommandInfoWithName(CommandName);
106 Info->IsUnknownCommand = true;
107 return Info;
108}
109
111 CommandInfo *Info = createCommandInfoWithName(CommandName);
112 Info->IsBlockCommand = true;
113 return Info;
114}
115
117 unsigned CommandID) {
118 if (CommandID < std::size(Commands))
119 return &Commands[CommandID];
120 return nullptr;
121}
122
123const CommandInfo *CommandTraits::getRegisteredCommandInfo(
124 StringRef Name) const {
125 for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i) {
126 if (RegisteredCommands[i]->Name == Name)
127 return RegisteredCommands[i];
128 }
129 return nullptr;
130}
131
132const CommandInfo *CommandTraits::getRegisteredCommandInfo(
133 unsigned CommandID) const {
134 return RegisteredCommands[CommandID - std::size(Commands)];
135}
136
137} // end namespace comments
138} // end namespace clang
139
Expr * E
__DEVICE__ long long abs(long long __n)
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
static const CommandInfo * getBuiltinCommandInfo(StringRef Name)
const CommandInfo * getCommandInfo(StringRef Name) const
CommandTraits(llvm::BumpPtrAllocator &Allocator, const CommentOptions &CommentOptions)
const CommandInfo * registerBlockCommand(StringRef CommandName)
const CommandInfo * registerUnknownCommand(StringRef CommandName)
void registerCommentOptions(const CommentOptions &CommentOptions)
const CommandInfo * getCommandInfoOrNULL(StringRef Name) const
const CommandInfo * getTypoCorrectCommandInfo(StringRef Typo) const
The JSON file list parser is used to communicate input to InstallAPI.
Options for controlling comment parsing.
BlockCommandNamesTy BlockCommandNames
Command names to treat as block commands in comments.
Information about a single command.
unsigned IsBlockCommand
True if this command is a block command (of any kind).
unsigned ID
The ID of the command.
unsigned IsUnknownCommand
True if this command is unknown.