-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang-doc] add namespaces to JSON generator #143209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// RUN: rm -rf %t && mkdir -p %t | ||
// RUN: clang-doc --output=%t --format=json --executor=standalone %s | ||
// RUN: FileCheck %s < %t/GlobalNamespace/index.json | ||
|
||
static void myFunction() {} | ||
|
||
void noExceptFunction() noexcept {} | ||
|
||
inline void inlineFunction() {} | ||
|
||
extern void externFunction() {} | ||
|
||
constexpr void constexprFunction() {} | ||
|
||
// CHECK: "Functions": [ | ||
// CHECK-NEXT: { | ||
// CHECK: "IsStatic": true, | ||
// COM: FIXME: Emit ExceptionSpecificationType | ||
// CHECK-NOT: "ExceptionSpecifcation" : "noexcept", | ||
// COM: FIXME: Emit inline | ||
// CHECK-NOT: "IsInline": true, | ||
// COM: FIXME: Emit extern | ||
// CHECK-NOT: "IsExtern": true, | ||
// COM: FIXME: Emit constexpr | ||
// CHECK-NOT: "IsConstexpr": true, |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,107 @@ | ||||||||||||||
// RUN: rm -rf %t && mkdir -p %t | ||||||||||||||
// RUN: clang-doc --output=%t --format=json --executor=standalone %s | ||||||||||||||
// RUN: FileCheck %s < %t/GlobalNamespace/index.json | ||||||||||||||
|
||||||||||||||
class MyClass {}; | ||||||||||||||
|
||||||||||||||
void myFunction(int Param); | ||||||||||||||
|
||||||||||||||
namespace NestedNamespace { | ||||||||||||||
} // namespace NestedNamespace | ||||||||||||||
|
||||||||||||||
// FIXME: Global variables are not mapped or serialized. | ||||||||||||||
static int Global; | ||||||||||||||
|
||||||||||||||
enum Color { | ||||||||||||||
RED, | ||||||||||||||
GREEN, | ||||||||||||||
BLUE = 5 | ||||||||||||||
}; | ||||||||||||||
|
||||||||||||||
typedef int MyTypedef; | ||||||||||||||
|
||||||||||||||
// CHECK: { | ||||||||||||||
// CHECK-NEXT: "Enums": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Location": { | ||||||||||||||
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp", | ||||||||||||||
// CHECK-NEXT: "LineNumber": 15 | ||||||||||||||
// CHECK-NEXT: }, | ||||||||||||||
// CHECK-NEXT: "Members": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Name": "RED", | ||||||||||||||
// CHECK-NEXT: "Value": "0" | ||||||||||||||
// CHECK-NEXT: }, | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Name": "GREEN", | ||||||||||||||
// CHECK-NEXT: "Value": "1" | ||||||||||||||
// CHECK-NEXT: }, | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Name": "BLUE", | ||||||||||||||
// CHECK-NEXT: "ValueExpr": "5" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "Name": "Color", | ||||||||||||||
// CHECK-NEXT: "Scoped": false, | ||||||||||||||
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "Functions": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "IsStatic": false, | ||||||||||||||
// CHECK-NEXT: "Name": "myFunction", | ||||||||||||||
// CHECK-NEXT: "Params": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Name": "Param", | ||||||||||||||
// CHECK-NEXT: "Type": "int" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "ReturnType": { | ||||||||||||||
// CHECK-NEXT: "IsBuiltIn": false, | ||||||||||||||
// CHECK-NEXT: "IsTemplate": false, | ||||||||||||||
// CHECK-NEXT: "Name": "void", | ||||||||||||||
// CHECK-NEXT: "QualName": "void", | ||||||||||||||
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do builtin types like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes those USRs are fixed.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, we're probably updating the wrong data structure/copy. Booleans should serialize fine. It could also be that we're doing something silly in a copy constructor or using a bad initializer list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fairly certain the reason we are seeing lots of default values is that these values aren't defined in BitecodeWriter.cpp. Every Info field has a corresponding enum thing. llvm-project/clang-tools-extra/clang-doc/BitcodeWriter.cpp Lines 196 to 201 in d75e284
And then corresponding values in a couple other places + BitcodeReader.cpp |
||||||||||||||
// CHECK-NEXT: }, | ||||||||||||||
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "Name": "", | ||||||||||||||
// CHECK-NEXT: "Namespaces": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Name": "NestedNamespace", | ||||||||||||||
// CHECK-NEXT: "Path": "", | ||||||||||||||
// CHECK-NEXT: "QualName": "NestedNamespace", | ||||||||||||||
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "Records": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "Name": "MyClass", | ||||||||||||||
// CHECK-NEXT: "Path": "GlobalNamespace", | ||||||||||||||
// CHECK-NEXT: "QualName": "MyClass", | ||||||||||||||
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "Typedefs": [ | ||||||||||||||
// CHECK-NEXT: { | ||||||||||||||
// CHECK-NEXT: "IsUsing": false, | ||||||||||||||
// CHECK-NEXT: "Location": { | ||||||||||||||
// CHECK-NEXT: "Filename": "{{.*}}namespace.cpp", | ||||||||||||||
// CHECK-NEXT: "LineNumber": 21 | ||||||||||||||
// CHECK-NEXT: }, | ||||||||||||||
// CHECK-NEXT: "Name": "MyTypedef", | ||||||||||||||
// CHECK-NEXT: "TypeDeclaration": "", | ||||||||||||||
// CHECK-NEXT: "USR": "{{[0-9A-F]*}}", | ||||||||||||||
// CHECK-NEXT: "Underlying": { | ||||||||||||||
// CHECK-NEXT: "IsBuiltIn": false, | ||||||||||||||
// CHECK-NEXT: "IsTemplate": false, | ||||||||||||||
// CHECK-NEXT: "Name": "int", | ||||||||||||||
// CHECK-NEXT: "QualName": "int", | ||||||||||||||
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: } | ||||||||||||||
// CHECK-NEXT: ], | ||||||||||||||
// CHECK-NEXT: "USR": "0000000000000000000000000000000000000000" | ||||||||||||||
// CHECK-NOT: "Variables": [ | ||||||||||||||
// CHECK-NEXT: } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you need something like CHECK-LABEL to make sure you're matching the correct part of the output? If the name is later in the output, maybe we should move it to make testing easier? Otherwise, I'd guess we would still need to check that we're matching the right property w/ the right entity...
Most of this test is just precommit for the FIXMEs, so it isn't a big deal right now, but I can imagine as the test grows, it may become harder to maintain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this was motivated by convenience. The functions are serialized in order, so I know that the first entry to be checked will be the static function. Hence, the
"IsStatic": true
check. The contents of an object are serialized alphabetically, so I haven't figured how to check the name first, since that comes after all theIs
fields.That would be useful. I can investigate this more.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matching the property and the name after should be OK, though not ideal. IIRC the JSON we emit from llvm-readobj isn't sorted by key, so maybe there is a setting in the JSON builder? Or maybe it's because it uses a JSON stream? I can't quite recall, but it may be worth looking at other subprojects to see how they deal with the issue.