Skip to content

Commit 6a29ae4

Browse files
[clang-doc] Fix bitcode writer for access specifiers
Bitcode writer was not emitting the corresponding record for the Access attribute of a FunctionInfo. This has been added. AS_none was being used as the default value for any AcesssSpecifier attribute (in FunctionInfo and MemberTypeInfo), this has been changed to AS_public because this is the enum value that evaluates to 0. The bitcode writer doesn't write values that are 0 so if an attribute was set to AS_public, this value is not written and after reading the bitcode it would have the default value which is AS_none. This is why the default value is now AS_public. Differential Revision: https://reviews.llvm.org/D66151 llvm-svn: 369063
1 parent 7534495 commit 6a29ae4

10 files changed

+41
-11
lines changed

clang-tools-extra/clang-doc/BitcodeWriter.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,7 @@ void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) {
510510
emitBlock(N, FieldId::F_namespace);
511511
for (const auto &CI : I.Description)
512512
emitBlock(CI);
513+
emitRecord(I.Access, FUNCTION_ACCESS);
513514
emitRecord(I.IsMethod, FUNCTION_IS_METHOD);
514515
if (I.DefLoc)
515516
emitRecord(I.DefLoc.getValue(), FUNCTION_DEFLOCATION);

clang-tools-extra/clang-doc/Representation.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,11 @@ struct MemberTypeInfo : public FieldTypeInfo {
198198
std::tie(Other.Type, Other.Name, Other.Access);
199199
}
200200

201-
AccessSpecifier Access = AccessSpecifier::AS_none; // Access level associated
202-
// with this info (public,
203-
// protected, private,
204-
// none).
201+
// Access level associated with this info (public, protected, private, none).
202+
// AS_public is set as default because the bitcode writer requires the enum
203+
// with value 0 to be used as the default.
204+
// (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
205+
AccessSpecifier Access = AccessSpecifier::AS_public;
205206
};
206207

207208
struct Location {
@@ -312,7 +313,10 @@ struct FunctionInfo : public SymbolInfo {
312313
TypeInfo ReturnType; // Info about the return type of this function.
313314
llvm::SmallVector<FieldTypeInfo, 4> Params; // List of parameters.
314315
// Access level for this method (public, private, protected, none).
315-
AccessSpecifier Access = AccessSpecifier::AS_none;
316+
// AS_public is set as default because the bitcode writer requires the enum
317+
// with value 0 to be used as the default.
318+
// (AS_public = 0, AS_protected = 1, AS_private = 2, AS_none = 3)
319+
AccessSpecifier Access = AccessSpecifier::AS_public;
316320
};
317321

318322
// TODO: Expand to allow for documenting templating, inheritance access,

clang-tools-extra/clang-doc/Serialize.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -463,12 +463,11 @@ emitInfo(const FunctionDecl *D, const FullComment *FC, int LineNumber,
463463
bool IsInAnonymousNamespace = false;
464464
populateFunctionInfo(Func, D, FC, LineNumber, File, IsFileInRootDir,
465465
IsInAnonymousNamespace);
466+
Func.Access = clang::AccessSpecifier::AS_none;
466467
if (PublicOnly && ((IsInAnonymousNamespace ||
467468
!isPublic(D->getAccess(), D->getLinkageInternal()))))
468469
return {};
469470

470-
Func.Access = clang::AccessSpecifier::AS_none;
471-
472471
// Wrap in enclosing scope
473472
auto ParentI = std::make_unique<NamespaceInfo>();
474473
if (!Func.Namespace.empty())

clang-tools-extra/clang-doc/YAMLGenerator.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ template <> struct MappingTraits<FieldTypeInfo> {
174174
template <> struct MappingTraits<MemberTypeInfo> {
175175
static void mapping(IO &IO, MemberTypeInfo &I) {
176176
FieldTypeInfoMapping(IO, I);
177+
// clang::AccessSpecifier::AS_none is used as the default here because it's
178+
// the AS that shouldn't be part of the output. Even though AS_public is the
179+
// default in the struct, it should be displayed in the YAML output.
177180
IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
178181
}
179182
};
@@ -218,6 +221,9 @@ template <> struct MappingTraits<FunctionInfo> {
218221
IO.mapOptional("Parent", I.Parent, Reference());
219222
IO.mapOptional("Params", I.Params);
220223
IO.mapOptional("ReturnType", I.ReturnType);
224+
// clang::AccessSpecifier::AS_none is used as the default here because it's
225+
// the AS that shouldn't be part of the output. Even though AS_public is the
226+
// default in the struct, it should be displayed in the YAML output.
221227
IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
222228
}
223229
};

clang-tools-extra/test/clang-doc/single-file-public.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ void Record::function_public() {}
4646
// CHECK-NEXT: ReturnType:
4747
// CHECK-NEXT: Type:
4848
// CHECK-NEXT: Name: 'void'
49+
// CHECK-NEXT: Access: Public
4950
// CHECK-NEXT: ...

clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ TEST(BitcodeTest, emitFunctionInfoBitcode) {
106106
I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
107107
I.Params.emplace_back("int", "P");
108108

109+
I.Access = AccessSpecifier::AS_none;
110+
109111
std::string WriteResult = writeInfo(&I);
110112
EXPECT_TRUE(WriteResult.size() > 0);
111113
std::vector<std::unique_ptr<Info>> ReadResults = readInfo(WriteResult, 1);
@@ -126,8 +128,7 @@ TEST(BitcodeTest, emitMethodInfoBitcode) {
126128
I.IsMethod = true;
127129
I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
128130

129-
// TODO: fix access
130-
// I.Access = AccessSpecifier::AS_private;
131+
I.Access = AccessSpecifier::AS_public;
131132

132133
std::string WriteResult = writeInfo(&I);
133134
EXPECT_TRUE(WriteResult.size() > 0);

clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ TEST(HTMLGeneratorTest, emitNamespaceHTML) {
4343
I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record,
4444
"Namespace");
4545
I.ChildFunctions.emplace_back();
46+
I.ChildFunctions.back().Access = AccessSpecifier::AS_none;
4647
I.ChildFunctions.back().Name = "OneFunction";
4748
I.ChildEnums.emplace_back();
4849
I.ChildEnums.back().Name = "OneEnum";
@@ -228,7 +229,7 @@ TEST(HTMLGeneratorTest, emitRecordHTML) {
228229
<h2 id="Functions">Functions</h2>
229230
<div>
230231
<h3 id="0000000000000000000000000000000000000000">OneFunction</h3>
231-
<p>OneFunction()</p>
232+
<p>public OneFunction()</p>
232233
</div>
233234
<h2 id="Enums">Enums</h2>
234235
<div>
@@ -248,6 +249,8 @@ TEST(HTMLGeneratorTest, emitFunctionHTML) {
248249
I.DefLoc = Location(10, llvm::SmallString<16>{"dir/test.cpp"}, false);
249250
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
250251

252+
I.Access = AccessSpecifier::AS_none;
253+
251254
SmallString<16> PathTo;
252255
llvm::sys::path::native("path/to", PathTo);
253256
I.ReturnType = TypeInfo(EmptySID, "float", InfoType::IT_default, PathTo);
@@ -331,6 +334,7 @@ TEST(HTMLGeneratorTest, emitCommentHTML) {
331334
I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
332335
I.Params.emplace_back("int", "I");
333336
I.Params.emplace_back("int", "J");
337+
I.Access = AccessSpecifier::AS_none;
334338

335339
CommentInfo Top;
336340
Top.Kind = "FullComment";

clang-tools-extra/unittests/clang-doc/MDGeneratorTest.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ TEST(MDGeneratorTest, emitNamespaceMD) {
3131
I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
3232
I.ChildFunctions.emplace_back();
3333
I.ChildFunctions.back().Name = "OneFunction";
34+
I.ChildFunctions.back().Access = AccessSpecifier::AS_none;
3435
I.ChildEnums.emplace_back();
3536
I.ChildEnums.back().Name = "OneEnum";
3637

@@ -127,7 +128,7 @@ ChildStruct
127128
128129
### OneFunction
129130
130-
* OneFunction()*
131+
*public OneFunction()*
131132
132133
133134
@@ -153,6 +154,8 @@ TEST(MDGeneratorTest, emitFunctionMD) {
153154
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
154155
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
155156

157+
I.Access = AccessSpecifier::AS_none;
158+
156159
I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
157160
I.Params.emplace_back("int", "P");
158161
I.IsMethod = true;
@@ -213,6 +216,7 @@ TEST(MDGeneratorTest, emitCommentMD) {
213216
I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
214217
I.Params.emplace_back("int", "I");
215218
I.Params.emplace_back("int", "J");
219+
I.Access = AccessSpecifier::AS_none;
216220

217221
CommentInfo Top;
218222
Top.Kind = "FullComment";

clang-tools-extra/unittests/clang-doc/SerializeTest.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ TEST(SerializeTest, emitNamespaceInfo) {
103103
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
104104
F.Namespace.emplace_back(EmptySID, "B", InfoType::IT_namespace);
105105
F.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
106+
F.Access = AccessSpecifier::AS_none;
106107
ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F));
107108
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
108109
}
@@ -299,6 +300,7 @@ TEST(SerializeTest, emitPublicFunctionInternalInfo) {
299300
F.Name = "F";
300301
F.ReturnType = TypeInfo(EmptySID, "int", InfoType::IT_default);
301302
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
303+
F.Access = AccessSpecifier::AS_none;
302304
ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F));
303305
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
304306
}
@@ -314,6 +316,7 @@ TEST(SerializeTest, emitInlinedFunctionInfo) {
314316
F.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
315317
F.DefLoc = Location(0, llvm::SmallString<16>{"test.cpp"});
316318
F.Params.emplace_back("int", "I");
319+
F.Access = AccessSpecifier::AS_none;
317320
ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F));
318321
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
319322
}
@@ -379,6 +382,7 @@ export double exportedModuleFunction(double y);)raw",
379382
F.ReturnType = TypeInfo(EmptySID, "int", InfoType::IT_default);
380383
F.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
381384
F.Params.emplace_back("int", "x");
385+
F.Access = AccessSpecifier::AS_none;
382386
ExpectedBWithFunction.ChildFunctions.emplace_back(std::move(F));
383387
CheckNamespaceInfo(&ExpectedBWithFunction, BWithFunction);
384388

@@ -389,6 +393,7 @@ export double exportedModuleFunction(double y);)raw",
389393
ExportedF.ReturnType = TypeInfo(EmptySID, "double", InfoType::IT_default);
390394
ExportedF.Loc.emplace_back(0, llvm::SmallString<16>{"test.cpp"});
391395
ExportedF.Params.emplace_back("double", "y");
396+
ExportedF.Access = AccessSpecifier::AS_none;
392397
ExpectedBWithExportedFunction.ChildFunctions.emplace_back(
393398
std::move(ExportedF));
394399
CheckNamespaceInfo(&ExpectedBWithExportedFunction, BWithExportedFunction);

clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ TEST(YAMLGeneratorTest, emitNamespaceYAML) {
3434
"path/to/A/Namespace");
3535
I.ChildFunctions.emplace_back();
3636
I.ChildFunctions.back().Name = "OneFunction";
37+
I.ChildFunctions.back().Access = AccessSpecifier::AS_none;
3738
I.ChildEnums.emplace_back();
3839
I.ChildEnums.back().Name = "OneEnum";
3940

@@ -138,6 +139,7 @@ TagType: Class
138139
- USR: '0000000000000000000000000000000000000000'
139140
Name: 'OneFunction'
140141
ReturnType: {}
142+
Access: Public
141143
ChildEnums:
142144
- USR: '0000000000000000000000000000000000000000'
143145
Name: 'OneEnum'
@@ -154,6 +156,8 @@ TEST(YAMLGeneratorTest, emitFunctionYAML) {
154156
I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
155157
I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
156158

159+
I.Access = AccessSpecifier::AS_none;
160+
157161
I.ReturnType =
158162
TypeInfo(EmptySID, "void", InfoType::IT_default, "path/to/void");
159163
I.Params.emplace_back("int", "path/to/int", "P");
@@ -242,6 +246,7 @@ TEST(YAMLGeneratorTest, emitCommentYAML) {
242246
I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
243247
I.Params.emplace_back("int", "I");
244248
I.Params.emplace_back("int", "J");
249+
I.Access = AccessSpecifier::AS_none;
245250

246251
CommentInfo Top;
247252
Top.Kind = "FullComment";

0 commit comments

Comments
 (0)