juliehockett updated this revision to Diff 153787.
juliehockett marked 12 inline comments as done.
juliehockett added a comment.
Refactoring second reduce code into the library, and adding bitcode
reader/writer support
https://reviews.llvm.org/D48341
Files:
clang-tools-extra/clang-doc/BitcodeReader.cpp
clang-tools-extra/clang-doc/BitcodeReader.h
clang-tools-extra/clang-doc/BitcodeWriter.cpp
clang-tools-extra/clang-doc/BitcodeWriter.h
clang-tools-extra/clang-doc/ClangDoc.cpp
clang-tools-extra/clang-doc/ClangDoc.h
clang-tools-extra/clang-doc/Representation.cpp
clang-tools-extra/clang-doc/Representation.h
clang-tools-extra/clang-doc/Serialize.cpp
clang-tools-extra/clang-doc/Serialize.h
clang-tools-extra/clang-doc/YAMLGenerator.cpp
clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
clang-tools-extra/test/clang-doc/yaml-comments.cpp
clang-tools-extra/test/clang-doc/yaml-namespace.cpp
clang-tools-extra/test/clang-doc/yaml-record.cpp
Index: clang-tools-extra/test/clang-doc/yaml-record.cpp
===================================================================
--- clang-tools-extra/test/clang-doc/yaml-record.cpp
+++ clang-tools-extra/test/clang-doc/yaml-record.cpp
@@ -1,250 +1,301 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: echo "" > %t/compile_flags.txt
-// RUN: cp "%s" "%t/test.cpp"
-// RUN: clang-doc -doxygen -p %t %t/test.cpp -output=%t/docs
-// RUN: cat %t/docs/A.yaml | FileCheck %s --check-prefix=CHECK-A
-// RUN: cat %t/docs/Bc.yaml | FileCheck %s --check-prefix=CHECK-BC
-// RUN: cat %t/docs/B.yaml | FileCheck %s --check-prefix=CHECK-B
-// RUN: cat %t/docs/C.yaml | FileCheck %s --check-prefix=CHECK-C
-// RUN: cat %t/docs/D.yaml | FileCheck %s --check-prefix=CHECK-D
-// RUN: cat %t/docs/E.yaml | FileCheck %s --check-prefix=CHECK-E
-// RUN: cat %t/docs/E/ProtectedMethod.yaml | FileCheck %s --check-prefix=CHECK-EPM
-// RUN: cat %t/docs/E/E.yaml | FileCheck %s --check-prefix=CHECK-ECON
-// RUN: cat %t/docs/E/'~E.yaml' | FileCheck %s --check-prefix=CHECK-EDES
-// RUN: cat %t/docs/F.yaml | FileCheck %s --check-prefix=CHECK-F
-// RUN: cat %t/docs/X.yaml | FileCheck %s --check-prefix=CHECK-X
-// RUN: cat %t/docs/X/Y.yaml | FileCheck %s --check-prefix=CHECK-Y
-// RUN: cat %t/docs/H.yaml | FileCheck %s --check-prefix=CHECK-H
-// RUN: cat %t/docs/H/I.yaml | FileCheck %s --check-prefix=CHECK-I
-
-union A { int X; int Y; };
-
-// CHECK-A: ---
-// CHECK-A-NEXT: USR: 'ACE81AFA6627B4CEF2B456FB6E1252925674AF7E'
-// CHECK-A-NEXT: Name: 'A'
-// CHECK-A-NEXT: DefLocation:
-// CHECK-A-NEXT: LineNumber: 21
-// CHECK-A-NEXT: Filename: '{{.*}}'
-// CHECK-A-NEXT: TagType: Union
-// CHECK-A-NEXT: Members:
-// CHECK-A-NEXT: - Type:
-// CHECK-A-NEXT: Name: 'int'
-// CHECK-A-NEXT: Name: 'X'
-// CHECK-A-NEXT: - Type:
-// CHECK-A-NEXT: Name: 'int'
-// CHECK-A-NEXT: Name: 'Y'
-// CHECK-A-NEXT: ...
+// RUN: cp "%s" "%t/{{.*}}.cpp"
+// RUN: clang-doc -doxygen -p %t %t/{{.*}}.cpp -output=%t/docs
+// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s --check-prefix=CHECK-G
+// RUN: cat %t/docs/Records.yaml | FileCheck %s --check-prefix=CHECK-R
+// RUN: cat %t/docs/Records/A.yaml | FileCheck %s --check-prefix=CHECK-A
+// RUN: cat %t/docs/Records/C.yaml | FileCheck %s --check-prefix=CHECK-C
+// RUN: cat %t/docs/Records/D.yaml | FileCheck %s --check-prefix=CHECK-D
+// RUN: cat %t/docs/Records/E.yaml | FileCheck %s --check-prefix=CHECK-E
+// RUN: cat %t/docs/Records/F.yaml | FileCheck %s --check-prefix=CHECK-F
+// RUN: cat %t/docs/Records/X.yaml | FileCheck %s --check-prefix=CHECK-X
+// RUN: cat %t/docs/Records/X/Y.yaml | FileCheck %s --check-prefix=CHECK-Y
+namespace Records {
-enum B { X, Y };
+union A {
+ int X;
+ int Y;
+};
-// CHECK-B: ---
-// CHECK-B-NEXT: USR: 'FC07BD34D5E77782C263FA944447929EA8753740'
-// CHECK-B-NEXT: Name: 'B'
-// CHECK-B-NEXT: DefLocation:
-// CHECK-B-NEXT: LineNumber: 40
-// CHECK-B-NEXT: Filename: '{{.*}}'
-// CHECK-B-NEXT: Members:
-// CHECK-B-NEXT: - 'X'
-// CHECK-B-NEXT: - 'Y'
-// CHECK-B-NEXT: ...
+//CHECK-A: ---
+//CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-A-NEXT: Name: 'A'
+//CHECK-A-NEXT: Namespace:
+//CHECK-A-NEXT: - Type: Namespace
+//CHECK-A-NEXT: Name: 'Records'
+//CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-A-NEXT: DefLocation:
+//CHECK-A-NEXT: LineNumber: 18
+//CHECK-A-NEXT: Filename: '{{.*}}'
+//CHECK-A-NEXT: TagType: Union
+//CHECK-A-NEXT: Members:
+//CHECK-A-NEXT: - Type:
+//CHECK-A-NEXT: Name: 'int'
+//CHECK-A-NEXT: Name: 'X'
+//CHECK-A-NEXT: - Type:
+//CHECK-A-NEXT: Name: 'int'
+//CHECK-A-NEXT: Name: 'Y'
+//CHECK-A-NEXT: ...
-enum class Bc { A, B };
+struct C {
+ int i;
+};
+
+//CHECK-C: ---
+//CHECK-C-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-C-NEXT: Name: 'C'
+//CHECK-C-NEXT: Namespace:
+//CHECK-C-NEXT: - Type: Namespace
+//CHECK-C-NEXT: Name: 'Records'
+//CHECK-C-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-C-NEXT: DefLocation:
+//CHECK-C-NEXT: LineNumber: 43
+//CHECK-C-NEXT: Filename: '{{.*}}'
+//CHECK-C-NEXT: Members:
+//CHECK-C-NEXT: - Type:
+//CHECK-C-NEXT: Name: 'int'
+//CHECK-C-NEXT: Name: 'i'
+//CHECK-C-NEXT: ...
-// CHECK-BC: ---
-// CHECK-BC-NEXT: USR: '1E3438A08BA22025C0B46289FF0686F92C8924C5'
-// CHECK-BC-NEXT: Name: 'Bc'
-// CHECK-BC-NEXT: DefLocation:
-// CHECK-BC-NEXT: LineNumber: 53
-// CHECK-BC-NEXT: Filename: '{{.*}}'
-// CHECK-BC-NEXT: Scoped: true
-// CHECK-BC-NEXT: Members:
-// CHECK-BC-NEXT: - 'A'
-// CHECK-BC-NEXT: - 'B'
-// CHECK-BC-NEXT: ...
-
-struct C { int i; };
-
-// CHECK-C: ---
-// CHECK-C-NEXT: USR: '06B5F6A19BA9F6A832E127C9968282B94619B210'
-// CHECK-C-NEXT: Name: 'C'
-// CHECK-C-NEXT: DefLocation:
-// CHECK-C-NEXT: LineNumber: 67
-// CHECK-C-NEXT: Filename: '{{.*}}'
-// CHECK-C-NEXT: Members:
-// CHECK-C-NEXT: - Type:
-// CHECK-C-NEXT: Name: 'int'
-// CHECK-C-NEXT: Name: 'i'
-// CHECK-C-NEXT: ...
class D {};
-// CHECK-D: ---
-// CHECK-D-NEXT: USR: '0921737541208B8FA9BB42B60F78AC1D779AA054'
-// CHECK-D-NEXT: Name: 'D'
-// CHECK-D-NEXT: DefLocation:
-// CHECK-D-NEXT: LineNumber: 81
-// CHECK-D-NEXT: Filename: '{{.*}}'
-// CHECK-D-NEXT: TagType: Class
-// CHECK-D-NEXT: ...
+//CHECK-D: ---
+//CHECK-D-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-D-NEXT: Name: 'D'
+//CHECK-D-NEXT: Namespace:
+//CHECK-D-NEXT: - Type: Namespace
+//CHECK-D-NEXT: Name: 'Records'
+//CHECK-D-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-D-NEXT: DefLocation:
+//CHECK-D-NEXT: LineNumber: 64
+//CHECK-D-NEXT: Filename: '{{.*}}'
+//CHECK-D-NEXT: TagType: Class
+//CHECK-D-NEXT: ...
+
class E {
public:
E() {}
-
-// CHECK-ECON: ---
-// CHECK-ECON-NEXT: USR: 'DEB4AC1CD9253CD9EF7FBE6BCAC506D77984ABD4'
-// CHECK-ECON-NEXT: Name: 'E'
-// CHECK-ECON-NEXT: Namespace:
-// CHECK-ECON-NEXT: - Type: Record
-// CHECK-ECON-NEXT: Name: 'E'
-// CHECK-ECON-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-ECON-NEXT: DefLocation:
-// CHECK-ECON-NEXT: LineNumber: 94
-// CHECK-ECON-NEXT: Filename: '{{.*}}'
-// CHECK-ECON-NEXT: IsMethod: true
-// CHECK-ECON-NEXT: Parent:
-// CHECK-ECON-NEXT: Type: Record
-// CHECK-ECON-NEXT: Name: 'E'
-// CHECK-ECON-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-ECON-NEXT: ReturnType:
-// CHECK-ECON-NEXT: Type:
-// CHECK-ECON-NEXT: Name: 'void'
-// CHECK-ECON-NEXT: ...
-
~E() {}
-
-// CHECK-EDES: ---
-// CHECK-EDES-NEXT: USR: 'BD2BDEBD423F80BACCEA75DE6D6622D355FC2D17'
-// CHECK-EDES-NEXT: Name: '~E'
-// CHECK-EDES-NEXT: Namespace:
-// CHECK-EDES-NEXT: - Type: Record
-// CHECK-EDES-NEXT: Name: 'E'
-// CHECK-EDES-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-EDES-NEXT: DefLocation:
-// CHECK-EDES-NEXT: LineNumber: 116
-// CHECK-EDES-NEXT: Filename: '{{.*}}'
-// CHECK-EDES-NEXT: IsMethod: true
-// CHECK-EDES-NEXT: Parent:
-// CHECK-EDES-NEXT: Type: Record
-// CHECK-EDES-NEXT: Name: 'E'
-// CHECK-EDES-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-EDES-NEXT: ReturnType:
-// CHECK-EDES-NEXT: Type:
-// CHECK-EDES-NEXT: Name: 'void'
-// CHECK-EDES-NEXT: ...
-
protected:
void ProtectedMethod();
};
-// CHECK-E: ---
-// CHECK-E-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-E-NEXT: Name: 'E'
-// CHECK-E-NEXT: DefLocation:
-// CHECK-E-NEXT: LineNumber: 92
-// CHECK-E-NEXT: Filename: '{{.*}}'
-// CHECK-E-NEXT: TagType: Class
-// CHECK-E-NEXT: ...
-
void E::ProtectedMethod() {}
-// CHECK-EPM: ---
-// CHECK-EPM-NEXT: USR: '5093D428CDC62096A67547BA52566E4FB9404EEE'
-// CHECK-EPM-NEXT: Name: 'ProtectedMethod'
-// CHECK-EPM-NEXT: Namespace:
-// CHECK-EPM-NEXT: - Type: Record
-// CHECK-EPM-NEXT: Name: 'E'
-// CHECK-EPM-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-EPM-NEXT: DefLocation:
-// CHECK-EPM-NEXT: LineNumber: 152
-// CHECK-EPM-NEXT: Filename: '{{.*}}'
-// CHECK-EPM-NEXT: Location:
-// CHECK-EPM-NEXT: - LineNumber: 140
-// CHECK-EPM-NEXT: Filename: '{{.*}}'
-// CHECK-EPM-NEXT: IsMethod: true
-// CHECK-EPM-NEXT: Parent:
-// CHECK-EPM-NEXT: Type: Record
-// CHECK-EPM-NEXT: Name: 'E'
-// CHECK-EPM-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-EPM-NEXT: ReturnType:
-// CHECK-EPM-NEXT: Type:
-// CHECK-EPM-NEXT: Name: 'void'
-// CHECK-EPM-NEXT: ...
+//CHECK-E: ---
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: Namespace:
+//CHECK-E-NEXT: - Type: Namespace
+//CHECK-E-NEXT: Name: 'Records'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: DefLocation:
+//CHECK-E-NEXT: LineNumber: 80
+//CHECK-E-NEXT: Filename: '{{.*}}'
+//CHECK-E-NEXT: TagType: Class
+//CHECK-E-NEXT: ChildFunctions:
+//CHECK-E-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: Name: '~E'
+//CHECK-E-NEXT: Namespace:
+//CHECK-E-NEXT: - Type: Record
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: - Type: Namespace
+//CHECK-E-NEXT: Name: 'Records'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: DefLocation:
+//CHECK-E-NEXT: LineNumber: 83
+//CHECK-E-NEXT: Filename: '{{.*}}'
+//CHECK-E-NEXT: IsMethod: true
+//CHECK-E-NEXT: Parent:
+//CHECK-E-NEXT: Type: Record
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: ReturnType:
+//CHECK-E-NEXT: Type:
+//CHECK-E-NEXT: Name: 'void'
+//CHECK-E-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: Name: 'ProtectedMethod'
+//CHECK-E-NEXT: Namespace:
+//CHECK-E-NEXT: - Type: Record
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: - Type: Namespace
+//CHECK-E-NEXT: Name: 'Records'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: DefLocation:
+//CHECK-E-NEXT: LineNumber: 89
+//CHECK-E-NEXT: Filename: '{{.*}}'
+//CHECK-E-NEXT: Location:
+//CHECK-E-NEXT: - LineNumber: 86
+//CHECK-E-NEXT: Filename: '{{.*}}'
+//CHECK-E-NEXT: IsMethod: true
+//CHECK-E-NEXT: Parent:
+//CHECK-E-NEXT: Type: Record
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: ReturnType:
+//CHECK-E-NEXT: Type:
+//CHECK-E-NEXT: Name: 'void'
+//CHECK-E-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: Namespace:
+//CHECK-E-NEXT: - Type: Record
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: - Type: Namespace
+//CHECK-E-NEXT: Name: 'Records'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: DefLocation:
+//CHECK-E-NEXT: LineNumber: 82
+//CHECK-E-NEXT: Filename: '{{.*}}'
+//CHECK-E-NEXT: IsMethod: true
+//CHECK-E-NEXT: Parent:
+//CHECK-E-NEXT: Type: Record
+//CHECK-E-NEXT: Name: 'E'
+//CHECK-E-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-E-NEXT: ReturnType:
+//CHECK-E-NEXT: Type:
+//CHECK-E-NEXT: Name: 'void'
+//CHECK-E-NEXT: ...
class F : virtual private D, public E {};
-// CHECK-F: ---
-// CHECK-F-NEXT: USR: 'E3B54702FABFF4037025BA194FC27C47006330B5'
-// CHECK-F-NEXT: Name: 'F'
-// CHECK-F-NEXT: DefLocation:
-// CHECK-F-NEXT: LineNumber: 177
-// CHECK-F-NEXT: Filename: '{{.*}}'
-// CHECK-F-NEXT: TagType: Class
-// CHECK-F-NEXT: Parents:
-// CHECK-F-NEXT: - Type: Record
-// CHECK-F-NEXT: Name: 'E'
-// CHECK-F-NEXT: USR: '289584A8E0FF4178A794622A547AA622503967A1'
-// CHECK-F-NEXT: VirtualParents:
-// CHECK-F-NEXT: - Type: Record
-// CHECK-F-NEXT: Name: 'D'
-// CHECK-F-NEXT: USR: '0921737541208B8FA9BB42B60F78AC1D779AA054'
-// CHECK-F-NEXT: ...
+//CHECK-F: ---
+//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-F-NEXT: Name: 'F'
+//CHECK-F-NEXT: Namespace:
+//CHECK-F-NEXT: - Type: Namespace
+//CHECK-F-NEXT: Name: 'Records'
+//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-F-NEXT: DefLocation:
+//CHECK-F-NEXT: LineNumber: 168
+//CHECK-F-NEXT: Filename: '{{.*}}'
+//CHECK-F-NEXT: TagType: Class
+//CHECK-F-NEXT: Parents:
+//CHECK-F-NEXT: - Type: Record
+//CHECK-F-NEXT: Name: 'E'
+//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-F-NEXT: VirtualParents:
+//CHECK-F-NEXT: - Type: Record
+//CHECK-F-NEXT: Name: 'D'
+//CHECK-F-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-F-NEXT: ...
class X {
class Y {};
-// CHECK-Y: ---
-// CHECK-Y-NEXT: USR: '641AB4A3D36399954ACDE29C7A8833032BF40472'
-// CHECK-Y-NEXT: Name: 'Y'
-// CHECK-Y-NEXT: Namespace:
-// CHECK-Y-NEXT: - Type: Record
-// CHECK-Y-NEXT: Name: 'X'
-// CHECK-Y-NEXT: USR: 'CA7C7935730B5EACD25F080E9C83FA087CCDC75E'
-// CHECK-Y-NEXT: DefLocation:
-// CHECK-Y-NEXT: LineNumber: 197
-// CHECK-Y-NEXT: Filename: '{{.*}}'
-// CHECK-Y-NEXT: TagType: Class
-// CHECK-Y-NEXT: ...
+//CHECK-Y: ---
+//CHECK-Y-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-Y-NEXT: Name: 'Y'
+//CHECK-Y-NEXT: Namespace:
+//CHECK-Y-NEXT: - Type: Record
+//CHECK-Y-NEXT: Name: 'X'
+//CHECK-Y-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-Y-NEXT: - Type: Namespace
+//CHECK-Y-NEXT: Name: 'Records'
+//CHECK-Y-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-Y-NEXT: DefLocation:
+//CHECK-Y-NEXT: LineNumber: 192
+//CHECK-Y-NEXT: Filename: '{{.*}}'
+//CHECK-Y-NEXT: TagType: Class
+//CHECK-Y-NEXT: ...
};
-// CHECK-X: ---
-// CHECK-X-NEXT: USR: 'CA7C7935730B5EACD25F080E9C83FA087CCDC75E'
-// CHECK-X-NEXT: Name: 'X'
-// CHECK-X-NEXT: DefLocation:
-// CHECK-X-NEXT: LineNumber: 196
-// CHECK-X-NEXT: Filename: '{{.*}}'
-// CHECK-X-NEXT: TagType: Class
-// CHECK-X-NEXT: ...
+//CHECK-X: ---
+//CHECK-X-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-X-NEXT: Name: 'X'
+//CHECK-X-NEXT: Namespace:
+//CHECK-X-NEXT: - Type: Namespace
+//CHECK-X-NEXT: Name: 'Records'
+//CHECK-X-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-X-NEXT: DefLocation:
+//CHECK-X-NEXT: LineNumber: 191
+//CHECK-X-NEXT: Filename: '{{.*}}'
+//CHECK-X-NEXT: TagType: Class
+//CHECK-X-NEXT: ChildRecords:
+//CHECK-X-NEXT: - Type: Record
+//CHECK-X-NEXT: Name: 'Y'
+//CHECK-X-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-X-NEXT: ...
void H() {
class I {};
-
-// CHECK-I: ---
-// CHECK-I-NEXT: USR: '{{.*}}'
-// CHECK-I-NEXT: Name: 'I'
-// CHECK-I-NEXT: Namespace:
-// CHECK-I-NEXT: - Type: Function
-// CHECK-I-NEXT: Name: 'H'
-// CHECK-I-NEXT: USR: 'B6AC4C5C9F2EA3F2B3ECE1A33D349F4EE502B24E'
-// CHECK-I-NEXT: DefLocation:
-// CHECK-I-NEXT: LineNumber: 224
-// CHECK-I-NEXT: Filename: 'test'
-// CHECK-I-NEXT: TagType: Class
-// CHECK-I-NEXT: ...
-
}
-// CHECK-H: ---
-// CHECK-H-NEXT: USR: 'B6AC4C5C9F2EA3F2B3ECE1A33D349F4EE502B24E'
-// CHECK-H-NEXT: Name: 'H'
-// CHECK-H-NEXT: DefLocation:
-// CHECK-H-NEXT: LineNumber: 223
-// CHECK-H-NEXT: Filename: 'test'
-// CHECK-H-NEXT: ReturnType:
-// CHECK-H-NEXT: Type:
-// CHECK-H-NEXT: Name: 'void'
-// CHECK-H-NEXT: ...
+} // namespace Records
+
+//CHECK-R: ---
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: Name: 'Records'
+//CHECK-R-NEXT: ChildRecords:
+//CHECK-R-NEXT: - Type: Record
+//CHECK-R-NEXT: Name: 'F'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: - Type: Record
+//CHECK-R-NEXT: Name: 'D'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: - Type: Record
+//CHECK-R-NEXT: Name: 'E'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: - Type: Record
+//CHECK-R-NEXT: Name: 'X'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: - Type: Record
+//CHECK-R-NEXT: Name: 'A'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: - Type: Record
+//CHECK-R-NEXT: Name: 'C'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: ChildFunctions:
+//CHECK-R-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: Name: 'H'
+//CHECK-R-NEXT: Namespace:
+//CHECK-R-NEXT: - Type: Namespace
+//CHECK-R-NEXT: Name: 'Records'
+//CHECK-R-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-R-NEXT: DefLocation:
+//CHECK-R-NEXT: LineNumber: 229
+//CHECK-R-NEXT: Filename: '{{.*}}'
+//CHECK-R-NEXT: ReturnType:
+//CHECK-R-NEXT: Type:
+//CHECK-R-NEXT: Name: 'void'
+//CHECK-R-NEXT: ...
+
+
+enum B { X, Y };
+
+enum class Bc { A, B };
+
+//CHECK-G: ---
+//CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-G-NEXT: ChildNamespaces:
+//CHECK-G-NEXT: - Type: Namespace
+//CHECK-G-NEXT: Name: 'Records'
+//CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-G-NEXT: ChildEnums:
+//CHECK-G-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-G-NEXT: Name: 'B'
+//CHECK-G-NEXT: DefLocation:
+//CHECK-G-NEXT: LineNumber: 273
+//CHECK-G-NEXT: Filename: '{{.*}}'
+//CHECK-G-NEXT: Members:
+//CHECK-G-NEXT: - 'X'
+//CHECK-G-NEXT: - 'Y'
+//CHECK-G-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+//CHECK-G-NEXT: Name: 'Bc'
+//CHECK-G-NEXT: DefLocation:
+//CHECK-G-NEXT: LineNumber: 275
+//CHECK-G-NEXT: Filename: '{{.*}}'
+//CHECK-G-NEXT: Scoped: true
+//CHECK-G-NEXT: Members:
+//CHECK-G-NEXT: - 'A'
+//CHECK-G-NEXT: - 'B'
+//CHECK-G-NEXT: ...
Index: clang-tools-extra/test/clang-doc/yaml-namespace.cpp
===================================================================
--- clang-tools-extra/test/clang-doc/yaml-namespace.cpp
+++ clang-tools-extra/test/clang-doc/yaml-namespace.cpp
@@ -3,100 +3,104 @@
// RUN: echo "" > %t/compile_flags.txt
// RUN: cp "%s" "%t/test.cpp"
// RUN: clang-doc -doxygen -p %t %t/test.cpp -output=%t/docs
+// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s --check-prefix=CHECK-G
// RUN: cat %t/docs/A.yaml | FileCheck %s --check-prefix=CHECK-A
// RUN: cat %t/docs/A/B.yaml | FileCheck %s --check-prefix=CHECK-B
-// RUN: cat %t/docs/A/f.yaml | FileCheck %s --check-prefix=CHECK-F
-// RUN: cat %t/docs/A/B/E.yaml | FileCheck %s --check-prefix=CHECK-E
-// RUN: cat %t/docs/A/B/func.yaml | FileCheck %s --check-prefix=CHECK-FUNC
-namespace A {
-
-// CHECK-A: ---
-// CHECK-A-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C'
-// CHECK-A-NEXT: Name: 'A'
-// CHECK-A-NEXT: ...
+// CHECK-G: ---
+// CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-G-NEXT: ChildNamespaces:
+// CHECK-G-NEXT: - Type: Namespace
+// CHECK-G-NEXT: Name: 'A'
+// CHECK-G-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-G-NEXT: ...
+namespace A {
+
void f();
} // namespace A
+// CHECK-A: ---
+// CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-A-NEXT: Name: 'A'
+// CHECK-A-NEXT: ChildNamespaces:
+// CHECK-A-NEXT: - Type: Namespace
+// CHECK-A-NEXT: Name: 'B'
+// CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-A-NEXT: ChildFunctions:
+// CHECK-A-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-A-NEXT: Name: 'f'
+// CHECK-A-NEXT: Namespace:
+// CHECK-A-NEXT: - Type: Namespace
+// CHECK-A-NEXT: Name: 'A'
+// CHECK-A-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-A-NEXT: DefLocation:
+// CHECK-A-NEXT: LineNumber: 52
+// CHECK-A-NEXT: Filename: '{{.*}}'
+// CHECK-A-NEXT: Location:
+// CHECK-A-NEXT: - LineNumber: 21
+// CHECK-A-NEXT: Filename: '{{.*}}'
+// CHECK-A-NEXT: ReturnType:
+// CHECK-A-NEXT: Type:
+// CHECK-A-NEXT: Name: 'void'
+// CHECK-A-NEXT: ...
+
namespace A {
void f(){};
-// CHECK-F: ---
-// CHECK-F-NEXT: USR: '39D3C95A5F7CE2BA4937BD7B01BAE09EBC2AD8AC'
-// CHECK-F-NEXT: Name: 'f'
-// CHECK-F-NEXT: Namespace:
-// CHECK-F-NEXT: - Type: Namespace
-// CHECK-F-NEXT: Name: 'A'
-// CHECK-F-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C'
-// CHECK-F-NEXT: DefLocation:
-// CHECK-F-NEXT: LineNumber: 26
-// CHECK-F-NEXT: Filename: '{{.*}}'
-// CHECK-F-NEXT: Location:
-// CHECK-F-NEXT: - LineNumber: 20
-// CHECK-F-NEXT: Filename: 'test'
-// CHECK-F-NEXT: ReturnType:
-// CHECK-F-NEXT: Type:
-// CHECK-F-NEXT: Name: 'void'
-// CHECK-F-NEXT: ...
-
namespace B {
-
-// CHECK-B: ---
-// CHECK-B-NEXT: USR: 'E21AF79E2A9D02554BA090D10DF39FE273F5CDB5'
-// CHECK-B-NEXT: Name: 'B'
-// CHECK-B-NEXT: Namespace:
-// CHECK-B-NEXT: - Type: Namespace
-// CHECK-B-NEXT: Name: 'A'
-// CHECK-B-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C'
-// CHECK-B-NEXT: ...
-
enum E { X };
-// CHECK-E: ---
-// CHECK-E-NEXT: USR: 'E9ABF7E7E2425B626723D41E76E4BC7E7A5BD775'
-// CHECK-E-NEXT: Name: 'E'
-// CHECK-E-NEXT: Namespace:
-// CHECK-E-NEXT: - Type: Namespace
-// CHECK-E-NEXT: Name: 'B'
-// CHECK-E-NEXT: USR: 'E21AF79E2A9D02554BA090D10DF39FE273F5CDB5'
-// CHECK-E-NEXT: - Type: Namespace
-// CHECK-E-NEXT: Name: 'A'
-// CHECK-E-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C'
-// CHECK-E-NEXT: DefLocation:
-// CHECK-E-NEXT: LineNumber: 58
-// CHECK-E-NEXT: Filename: '{{.*}}'
-// CHECK-E-NEXT: Members:
-// CHECK-E-NEXT: - 'X'
-// CHECK-E-NEXT: ...
-
E func(int i) { return X; }
-// CHECK-FUNC: ---
-// CHECK-FUNC-NEXT: USR: '9A82CB33ED0FDF81EE383D31CD0957D153C5E840'
-// CHECK-FUNC-NEXT: Name: 'func'
-// CHECK-FUNC-NEXT: Namespace:
-// CHECK-FUNC-NEXT: - Type: Namespace
-// CHECK-FUNC-NEXT: Name: 'B'
-// CHECK-FUNC-NEXT: USR: 'E21AF79E2A9D02554BA090D10DF39FE273F5CDB5'
-// CHECK-FUNC-NEXT: - Type: Namespace
-// CHECK-FUNC-NEXT: Name: 'A'
-// CHECK-FUNC-NEXT: USR: '8D042EFFC98B373450BC6B5B90A330C25A150E9C'
-// CHECK-FUNC-NEXT: DefLocation:
-// CHECK-FUNC-NEXT: LineNumber: 77
-// CHECK-FUNC-NEXT: Filename: '{{.*}}'
-// CHECK-FUNC-NEXT: Params:
-// CHECK-FUNC-NEXT: - Type:
-// CHECK-FUNC-NEXT: Name: 'int'
-// CHECK-FUNC-NEXT: Name: 'i'
-// CHECK-FUNC-NEXT: ReturnType:
-// CHECK-FUNC-NEXT: Type:
-// CHECK-FUNC-NEXT: Name: 'enum A::B::E'
-// CHECK-FUNC-NEXT: ...
-
} // namespace B
} // namespace A
+
+// CHECK-B: ---
+// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: Name: 'B'
+// CHECK-B-NEXT: Namespace:
+// CHECK-B-NEXT: - Type: Namespace
+// CHECK-B-NEXT: Name: 'A'
+// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: ChildFunctions:
+// CHECK-B-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: Name: 'func'
+// CHECK-B-NEXT: Namespace:
+// CHECK-B-NEXT: - Type: Namespace
+// CHECK-B-NEXT: Name: 'B'
+// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: - Type: Namespace
+// CHECK-B-NEXT: Name: 'A'
+// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: DefLocation:
+// CHECK-B-NEXT: LineNumber: 58
+// CHECK-B-NEXT: Filename: '{{.*}}'
+// CHECK-B-NEXT: Params:
+// CHECK-B-NEXT: - Type:
+// CHECK-B-NEXT: Name: 'int'
+// CHECK-B-NEXT: Name: 'i'
+// CHECK-B-NEXT: ReturnType:
+// CHECK-B-NEXT: Type:
+// CHECK-B-NEXT: Name: 'enum A::B::E'
+// CHECK-B-NEXT: ChildEnums:
+// CHECK-B-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: Name: 'E'
+// CHECK-B-NEXT: Namespace:
+// CHECK-B-NEXT: - Type: Namespace
+// CHECK-B-NEXT: Name: 'B'
+// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: - Type: Namespace
+// CHECK-B-NEXT: Name: 'A'
+// CHECK-B-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-B-NEXT: DefLocation:
+// CHECK-B-NEXT: LineNumber: 56
+// CHECK-B-NEXT: Filename: '{{.*}}'
+// CHECK-B-NEXT: Members:
+// CHECK-B-NEXT: - 'X'
+// CHECK-B-NEXT: ...
+
Index: clang-tools-extra/test/clang-doc/yaml-comments.cpp
===================================================================
--- clang-tools-extra/test/clang-doc/yaml-comments.cpp
+++ clang-tools-extra/test/clang-doc/yaml-comments.cpp
@@ -3,7 +3,7 @@
// RUN: echo "" > %t/compile_flags.txt
// RUN: cp "%s" "%t/test.cpp"
// RUN: clang-doc -doxygen -p %t %t/test.cpp -output=%t/docs
-// RUN: cat %t/docs/F.yaml | FileCheck %s
+// RUN: cat %t/docs/GlobalNamespace.yaml | FileCheck %s
/// \brief Brief description.
///
@@ -26,8 +26,10 @@
/// Bonus comment on definition
void F(int I, int J) {}
-// CHECK: ---
-// CHECK-NEXT: USR: '7574630614A535710E5A6ABCFFF98BCA2D06A4CA'
+// CHECK: ---
+// CHECK-NEXT: USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
+// CHECK-NEXT: ChildFunctions:
+// CHECK-NEXT: - USR: '{{[0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]}}'
// CHECK-NEXT: Name: 'F'
// CHECK-NEXT: Description:
// CHECK-NEXT: - Kind: 'FullComment'
Index: clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
===================================================================
--- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
+++ clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
@@ -117,6 +117,19 @@
return false;
}
+// A function to extract the appropriate path name for a given info's
+// documentation. The path returned is a composite of the parent namespaces as
+// directories plus the decl name as the filename.
+//
+// Example: Given the below, the yaml path for class C will be <root>/A/B/C.yaml
+//
+// namespace A {
+// namesapce B {
+//
+// class C {};
+//
+// }
+// }
llvm::Expected<llvm::SmallString<128>>
getPath(StringRef Root, StringRef Ext, StringRef Name,
llvm::SmallVectorImpl<doc::Reference> &Namespaces) {
@@ -130,6 +143,8 @@
return llvm::make_error<llvm::StringError>("Unable to create directory.\n",
llvm::inconvertibleErrorCode());
+ if (Name.empty())
+ Name = "GlobalNamespace";
llvm::sys::path::append(Path, Name + Ext);
return Path;
}
@@ -142,6 +157,32 @@
llvm_unreachable("Unknown OutputFormatTy");
}
+void addToInfoPassOutput(
+ StringRef Key, std::unique_ptr<doc::Info> &&I,
+ llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> &Output) {
+ auto R = Output.try_emplace(Key, std::vector<std::unique_ptr<doc::Info>>());
+ R.first->second.emplace_back(std::move(I));
+}
+
+bool mapResultsInMemory(
+ tooling::ToolResults &Results,
+ llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> &Output) {
+ bool Err = false;
+ Results.forEachResult([&](StringRef Key, StringRef Value) {
+ llvm::BitstreamCursor Stream(Value);
+ doc::ClangDocBitcodeReader Reader(Stream);
+ auto Infos = Reader.readBitcode();
+ if (!Infos) {
+ llvm::errs() << toString(Infos.takeError()) << "\n";
+ Err = true;
+ return;
+ }
+ for (auto &I : Infos.get())
+ addToInfoPassOutput(Key, std::move(I), Output);
+ });
+ return Err;
+}
+
int main(int argc, const char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
std::error_code OK;
@@ -191,30 +232,22 @@
}
// Collect values into output by key.
- llvm::outs() << "Collecting infos...\n";
- llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> MapOutput;
-
// In ToolResults, the Key is the hashed USR and the value is the
// bitcode-encoded representation of the Info object.
- Exec->get()->getToolResults()->forEachResult([&](StringRef Key,
- StringRef Value) {
- llvm::BitstreamCursor Stream(Value);
- doc::ClangDocBitcodeReader Reader(Stream);
- auto Infos = Reader.readBitcode();
- for (auto &I : Infos) {
- auto R =
- MapOutput.try_emplace(Key, std::vector<std::unique_ptr<doc::Info>>());
- R.first->second.emplace_back(std::move(I));
- }
- });
+ llvm::outs() << "Collecting infos...\n";
+ llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> MapOutput;
+ if (mapResultsInMemory(*Exec->get()->getToolResults(), MapOutput))
+ return 1;
- // Reducing and generation phases
- llvm::outs() << "Reducing " << MapOutput.size() << " infos...\n";
- llvm::StringMap<std::unique_ptr<doc::Info>> ReduceOutput;
+ // First reducing phase (reduce all decls into one info per decl).
+ llvm::outs() << "Reducing " << MapOutput.size() << " infos by name...\n";
+ tooling::InMemoryToolResults ReduceResults;
for (auto &Group : MapOutput) {
auto Reduced = doc::mergeInfos(Group.getValue());
- if (!Reduced)
+ if (!Reduced) {
llvm::errs() << llvm::toString(Reduced.takeError());
+ continue;
+ }
if (DumpIntermediateResult) {
SmallString<4096> Buffer;
@@ -226,17 +259,45 @@
continue;
}
+ // Prepare for second reduce pass by re-mapping infos by enclosing scope.
+ if (auto Error =
+ doc::mapByEnclosingScope(std::move(Reduced.get()), ReduceResults))
+ llvm::errs() << toString(std::move(Error)) << "\n";
+ }
+
+ // Collect values into output by enclosing scope.
+ // In ReduceResults, the Key is the hashed USR of the enclosing scope and the
+ // value is the bitcode-encoded representation of the Info object.
+ llvm::outs() << "Collecting infos by enclosing scope...\n";
+ llvm::StringMap<std::vector<std::unique_ptr<doc::Info>>> ReduceOutput;
+ if (mapResultsInMemory(ReduceResults, ReduceOutput))
+ return 1;
+
+ // Second reducing phase (by scope) and docs generation phase
+ // This pass reduces the re-mapped infos by enclosing scope, meaning that all
+ // function and enum infos are absorbed into their parent class or namespace,
+ // and references to classes/namespaces are stored in their parent
+ // class/namespace.
+ llvm::outs() << "Further reducing " << ReduceOutput.size()
+ << " infos by scope...\n";
+ for (auto &Group : ReduceOutput) {
// Create the relevant ostream and emit the documentation for this decl.
+ auto Reduced = doc::mergeInfos(Group.getValue());
+ if (!Reduced) {
+ llvm::errs() << llvm::toString(Reduced.takeError());
+ continue;
+ }
doc::Info *I = Reduced.get().get();
+
auto InfoPath = getPath(OutDirectory, "." + Format, I->Name, I->Namespace);
if (!InfoPath) {
llvm::errs() << toString(InfoPath.takeError()) << "\n";
continue;
}
std::error_code FileErr;
llvm::raw_fd_ostream InfoOS(InfoPath.get(), FileErr, llvm::sys::fs::F_None);
if (FileErr != OK) {
- llvm::errs() << "Error opening index file: " << FileErr.message() << "\n";
+ llvm::errs() << "Error opening info file: " << FileErr.message() << "\n";
continue;
}
Index: clang-tools-extra/clang-doc/YAMLGenerator.cpp
===================================================================
--- clang-tools-extra/clang-doc/YAMLGenerator.cpp
+++ clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -20,6 +20,8 @@
LLVM_YAML_IS_SEQUENCE_VECTOR(Reference)
LLVM_YAML_IS_SEQUENCE_VECTOR(Location)
LLVM_YAML_IS_SEQUENCE_VECTOR(CommentInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(EnumInfo)
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<CommentInfo>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::SmallString<16>)
@@ -175,7 +177,14 @@
};
template <> struct MappingTraits<NamespaceInfo> {
- static void mapping(IO &IO, NamespaceInfo &I) { InfoMapping(IO, I); }
+ static void mapping(IO &IO, NamespaceInfo &I) {
+ InfoMapping(IO, I);
+ IO.mapOptional("ChildNamespaces", I.ChildNamespaces,
+ std::vector<Reference>());
+ IO.mapOptional("ChildRecords", I.ChildRecords, std::vector<Reference>());
+ IO.mapOptional("ChildFunctions", I.ChildFunctions);
+ IO.mapOptional("ChildEnums", I.ChildEnums);
+ }
};
template <> struct MappingTraits<RecordInfo> {
@@ -186,6 +195,11 @@
IO.mapOptional("Parents", I.Parents, llvm::SmallVector<Reference, 4>());
IO.mapOptional("VirtualParents", I.VirtualParents,
llvm::SmallVector<Reference, 4>());
+ IO.mapOptional("ChildNamespaces", I.ChildNamespaces,
+ std::vector<Reference>());
+ IO.mapOptional("ChildRecords", I.ChildRecords, std::vector<Reference>());
+ IO.mapOptional("ChildFunctions", I.ChildFunctions);
+ IO.mapOptional("ChildEnums", I.ChildEnums);
}
};
Index: clang-tools-extra/clang-doc/Serialize.h
===================================================================
--- clang-tools-extra/clang-doc/Serialize.h
+++ clang-tools-extra/clang-doc/Serialize.h
@@ -46,6 +46,8 @@
// memory (vs storing USRs directly).
SymbolID hashUSR(llvm::StringRef USR);
+std::string serialize(std::unique_ptr<Info> &I);
+
} // namespace serialize
} // namespace doc
} // namespace clang
Index: clang-tools-extra/clang-doc/Serialize.cpp
===================================================================
--- clang-tools-extra/clang-doc/Serialize.cpp
+++ clang-tools-extra/clang-doc/Serialize.cpp
@@ -152,6 +152,21 @@
return Buffer.str().str();
}
+std::string serialize(std::unique_ptr<Info> &I) {
+ switch (I->IT) {
+ case InfoType::IT_namespace:
+ return serialize(*static_cast<NamespaceInfo *>(I.get()));
+ case InfoType::IT_record:
+ return serialize(*static_cast<RecordInfo *>(I.get()));
+ case InfoType::IT_enum:
+ return serialize(*static_cast<EnumInfo *>(I.get()));
+ case InfoType::IT_function:
+ return serialize(*static_cast<FunctionInfo *>(I.get()));
+ default:
+ return "";
+ }
+}
+
static void parseFullComment(const FullComment *C, CommentInfo &CI) {
ClangDocCommentVisitor Visitor(CI);
Visitor.parseComment(C);
Index: clang-tools-extra/clang-doc/Representation.h
===================================================================
--- clang-tools-extra/clang-doc/Representation.h
+++ clang-tools-extra/clang-doc/Representation.h
@@ -30,6 +30,9 @@
using SymbolID = std::array<uint8_t, 20>;
struct Info;
+struct FunctionInfo;
+struct EnumInfo;
+
enum class InfoType {
IT_default,
IT_namespace,
@@ -151,6 +154,8 @@
/// A base struct for Infos.
struct Info {
Info() = default;
+ Info(InfoType IT, SymbolID USR, StringRef Name)
+ : USR(USR), IT(IT), Name(Name) {}
Info(InfoType IT) : IT(IT) {}
Info(const Info &Other) = delete;
Info(Info &&Other) = default;
@@ -165,18 +170,30 @@
void mergeBase(Info &&I);
bool mergeable(const Info &Other);
+
+ // Returns a reference to the parent scope (that is, the immediate parent
+ // namespace or class in which this decl resides).
+ llvm::Expected<Reference> getEnclosingScope();
};
// Info for namespaces.
struct NamespaceInfo : public Info {
NamespaceInfo() : Info(InfoType::IT_namespace) {}
+ NamespaceInfo(SymbolID USR, StringRef Name)
+ : Info(InfoType::IT_namespace, USR, Name) {}
void merge(NamespaceInfo &&I);
+
+ std::vector<Reference> ChildNamespaces;
+ std::vector<Reference> ChildRecords;
+ std::vector<FunctionInfo> ChildFunctions;
+ std::vector<EnumInfo> ChildEnums;
};
// Info for symbols.
struct SymbolInfo : public Info {
SymbolInfo(InfoType IT) : Info(IT) {}
+ SymbolInfo(InfoType IT, SymbolID USR, StringRef Name) : Info(IT, USR, Name) {}
void merge(SymbolInfo &&I);
@@ -204,6 +221,8 @@
// Info for types.
struct RecordInfo : public SymbolInfo {
RecordInfo() : SymbolInfo(InfoType::IT_record) {}
+ RecordInfo(SymbolID USR, StringRef Name)
+ : SymbolInfo(InfoType::IT_record, USR, Name) {}
void merge(RecordInfo &&I);
@@ -217,6 +236,11 @@
// parents).
llvm::SmallVector<Reference, 4>
VirtualParents; // List of virtual base/parent records.
+
+ std::vector<Reference> ChildNamespaces;
+ std::vector<Reference> ChildRecords;
+ std::vector<FunctionInfo> ChildFunctions;
+ std::vector<EnumInfo> ChildEnums;
};
// TODO: Expand to allow for documenting templating.
@@ -239,6 +263,26 @@
llvm::Expected<std::unique_ptr<Info>>
mergeInfos(std::vector<std::unique_ptr<Info>> &Values);
+// A function to wrap a reference in an Info of the appropriate
+// enclosing scope.
+//
+// This takes a given info and the type of the decl scope in
+// which it resides (that is, the immediate parent namespace or class in which
+// it is declared). It returns an info of the type of the enclosing scope with
+// the given info in the appropriate child list.
+//
+// Example:
+// class Foo {
+// void Bar() {};
+// }
+//
+// For the method Bar, the enclosing scope is class Foo. Passing the Bar
+// FunctionInfo and the enclosing type 'class' to this function would return a
+// RecordInfo with the Bar functionInfo in the ChildFunctions field. This allows
+// for the child to be merged into the parent's info structure.
+llvm::Expected<std::unique_ptr<Info>>
+wrapInfoInEnclosingType(InfoType EnclosingType, std::unique_ptr<Info> &&Info);
+
} // namespace doc
} // namespace clang
Index: clang-tools-extra/clang-doc/Representation.cpp
===================================================================
--- clang-tools-extra/clang-doc/Representation.cpp
+++ clang-tools-extra/clang-doc/Representation.cpp
@@ -42,7 +42,7 @@
mergeInfos(std::vector<std::unique_ptr<Info>> &Values) {
if (Values.empty())
return llvm::make_error<llvm::StringError>("No info values to merge.\n",
- llvm::inconvertibleErrorCode());
+ llvm::inconvertibleErrorCode());
switch (Values[0]->IT) {
case InfoType::IT_namespace:
@@ -59,21 +59,94 @@
}
}
+template <typename T>
+bool addInfoToEnclosing(T *Enclosing, std::unique_ptr<Info> &&I) {
+ switch (I->IT) {
+ case InfoType::IT_namespace:
+ Enclosing->ChildNamespaces.emplace_back(I->USR, I->Name, I->IT);
+ return true;
+ case InfoType::IT_record:
+ Enclosing->ChildRecords.emplace_back(I->USR, I->Name, I->IT);
+ return true;
+ case InfoType::IT_function: {
+ FunctionInfo *Info = static_cast<FunctionInfo *>(I.release());
+ Enclosing->ChildFunctions.emplace_back(std::move(*Info));
+ return true;
+ }
+ case InfoType::IT_enum: {
+ EnumInfo *Info = static_cast<EnumInfo *>(I.release());
+ Enclosing->ChildEnums.emplace_back(std::move(*Info));
+ return true;
+ }
+ default:
+ return false;
+ }
+}
+
+llvm::Expected<std::unique_ptr<Info>>
+wrapInfoInEnclosingType(InfoType EnclosingType, std::unique_ptr<Info> &&I) {
+ switch (EnclosingType) {
+ case InfoType::IT_namespace: {
+ std::unique_ptr<Info> EnclosingInfo = llvm::make_unique<NamespaceInfo>();
+ NamespaceInfo *Enclosing =
+ static_cast<NamespaceInfo *>(EnclosingInfo.get());
+ if (!addInfoToEnclosing(Enclosing, std::move(I)))
+ return llvm::make_error<llvm::StringError>(
+ "Unexpected reference type.\n", llvm::inconvertibleErrorCode());
+ return EnclosingInfo;
+ }
+ case InfoType::IT_record: {
+ std::unique_ptr<Info> EnclosingInfo = llvm::make_unique<RecordInfo>();
+ RecordInfo *Enclosing = static_cast<RecordInfo *>(EnclosingInfo.get());
+ if (!addInfoToEnclosing(Enclosing, std::move(I)))
+ return llvm::make_error<llvm::StringError>(
+ "Unexpected reference type.\n", llvm::inconvertibleErrorCode());
+ return EnclosingInfo;
+ }
+ default:
+ return llvm::make_error<llvm::StringError>("Unexpected enclosing type.\n",
+ llvm::inconvertibleErrorCode());
+ }
+}
+
+llvm::Expected<Reference> Info::getEnclosingScope() {
+ // If this is top level, the enclosing scope is the global namespace.
+ if (Namespace.empty()) {
+ auto R = Reference();
+ R.RefType = InfoType::IT_namespace;
+ return R;
+ }
+
+ switch (Namespace[0].RefType) {
+ // Enclosing scopes should only be namespaces, functions, or records.
+ case InfoType::IT_namespace:
+ case InfoType::IT_record:
+ case InfoType::IT_function:
+ return Namespace[0];
+ case InfoType::IT_enum:
+ case InfoType::IT_default:
+ return llvm::make_error<llvm::StringError>("Unexpected scope type.\n",
+ llvm::inconvertibleErrorCode());
+ }
+}
+
void Info::mergeBase(Info &&Other) {
assert(mergeable(Other));
if (USR == EmptySID)
USR = Other.USR;
if (Name == "")
Name = Other.Name;
if (Namespace.empty())
Namespace = std::move(Other.Namespace);
- // Unconditionally extend the description, since each decl may have a comment.
+ // Unconditionally extend the description, since each decl may have a
+ // comment.
std::move(Other.Description.begin(), Other.Description.end(),
std::back_inserter(Description));
}
bool Info::mergeable(const Info &Other) {
- return IT == Other.IT && (USR == EmptySID || USR == Other.USR);
+ return IT == Other.IT &&
+ (USR == EmptySID || USR == Other.USR || Other.USR == EmptySID);
}
void SymbolInfo::merge(SymbolInfo &&Other) {
@@ -87,6 +160,16 @@
void NamespaceInfo::merge(NamespaceInfo &&Other) {
assert(mergeable(Other));
+ // Unconditionally extend the children, since they're added after the
+ // initial reduce and therefore there can only be one.
+ std::move(Other.ChildNamespaces.begin(), Other.ChildNamespaces.end(),
+ std::back_inserter(ChildNamespaces));
+ std::move(Other.ChildRecords.begin(), Other.ChildRecords.end(),
+ std::back_inserter(ChildRecords));
+ std::move(Other.ChildFunctions.begin(), Other.ChildFunctions.end(),
+ std::back_inserter(ChildFunctions));
+ std::move(Other.ChildEnums.begin(), Other.ChildEnums.end(),
+ std::back_inserter(ChildEnums));
mergeBase(std::move(Other));
}
@@ -100,6 +183,16 @@
Parents = std::move(Other.Parents);
if (VirtualParents.empty())
VirtualParents = std::move(Other.VirtualParents);
+ // Unconditionally extend the children, since they're added after the
+ // initial reduce and therefore there can only be one.
+ std::move(Other.ChildNamespaces.begin(), Other.ChildNamespaces.end(),
+ std::back_inserter(ChildNamespaces));
+ std::move(Other.ChildRecords.begin(), Other.ChildRecords.end(),
+ std::back_inserter(ChildRecords));
+ std::move(Other.ChildFunctions.begin(), Other.ChildFunctions.end(),
+ std::back_inserter(ChildFunctions));
+ std::move(Other.ChildEnums.begin(), Other.ChildEnums.end(),
+ std::back_inserter(ChildEnums));
SymbolInfo::merge(std::move(Other));
}
Index: clang-tools-extra/clang-doc/ClangDoc.h
===================================================================
--- clang-tools-extra/clang-doc/ClangDoc.h
+++ clang-tools-extra/clang-doc/ClangDoc.h
@@ -17,16 +17,21 @@
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_CLANGDOC_H
+#include "Representation.h"
#include "clang/Tooling/Execution.h"
#include "clang/Tooling/StandaloneExecution.h"
#include "clang/Tooling/Tooling.h"
+#include "llvm/Support/Error.h"
namespace clang {
namespace doc {
std::unique_ptr<tooling::FrontendActionFactory>
newMapperActionFactory(tooling::ExecutionContext *ECtx);
+llvm::Error mapByEnclosingScope(std::unique_ptr<Info> &&I,
+ tooling::ToolResults &Results);
+
} // namespace doc
} // namespace clang
Index: clang-tools-extra/clang-doc/ClangDoc.cpp
===================================================================
--- clang-tools-extra/clang-doc/ClangDoc.cpp
+++ clang-tools-extra/clang-doc/ClangDoc.cpp
@@ -15,6 +15,7 @@
#include "ClangDoc.h"
#include "Mapper.h"
+#include "Serialize.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
@@ -57,5 +58,72 @@
return llvm::make_unique<MapperActionFactory>(ECtx);
}
+llvm::Error addInfoToResults(std::unique_ptr<Info> &&I,
+ StringRef EnclosingScopeKey,
+ InfoType EnclosingScopeType,
+ tooling::ToolResults &Results) {
+ // Add this info to the enclosing scope's key.
+ auto Enclosing = wrapInfoInEnclosingType(EnclosingScopeType, std::move(I));
+ if (!Enclosing)
+ return Enclosing.takeError();
+ Results.addResult(EnclosingScopeKey, serialize::serialize(Enclosing.get()));
+ return llvm::Error::success();
+}
+
+template <typename T>
+llvm::Error
+addRefToResults(std::unique_ptr<Info> &&I, StringRef EnclosingScopeKey,
+ InfoType EnclosingScopeType, tooling::ToolResults &Results) {
+ // Add a reference to this info to the enclosing scope's key.
+ std::unique_ptr<Info> Ref = llvm::make_unique<T>(I->USR, I->Name);
+ auto Enclosing = wrapInfoInEnclosingType(EnclosingScopeType, std::move(Ref));
+ if (!Enclosing)
+ return Enclosing.takeError();
+ Results.addResult(EnclosingScopeKey, serialize::serialize(Enclosing.get()));
+
+ // Add this info to its own key.
+ Results.addResult(llvm::toHex(llvm::toStringRef(I->USR)),
+ serialize::serialize(I));
+ return llvm::Error::success();
+}
+
+llvm::Error mapByEnclosingScope(std::unique_ptr<Info> &&I,
+ tooling::ToolResults &Results) {
+ // Get the enclosing scope of this decl.
+ auto EnclosingScope = I->getEnclosingScope();
+ if (!EnclosingScope)
+ return EnclosingScope.takeError();
+
+ // Pass over things declared internally to functions.
+ // FIXME: Do this in the initial mapping phase and return an error here.
+ if (EnclosingScope.get().RefType == doc::InfoType::IT_function)
+ return llvm::Error::success();
+
+ std::string EnclosingScopeKey;
+ // An enclosing scope has an empty USR if it's the global namespace.
+ if (EnclosingScope.get().USR == doc::SymbolID())
+ EnclosingScopeKey = "Global";
+ else
+ EnclosingScopeKey =
+ llvm::toHex(llvm::toStringRef(EnclosingScope.get().USR));
+
+ switch (I->IT) {
+ case doc::InfoType::IT_namespace:
+ return addRefToResults<NamespaceInfo>(
+ std::move(I), EnclosingScopeKey, EnclosingScope.get().RefType, Results);
+ case doc::InfoType::IT_record:
+ return addRefToResults<RecordInfo>(std::move(I), EnclosingScopeKey,
+ EnclosingScope.get().RefType, Results);
+ case doc::InfoType::IT_enum:
+ case doc::InfoType::IT_function:
+ return addInfoToResults(std::move(I), EnclosingScopeKey,
+ EnclosingScope.get().RefType, Results);
+ default:
+ return llvm::make_error<llvm::StringError>(
+ "Unexpected type in mapping by enclosing scope.\n",
+ llvm::inconvertibleErrorCode());
+ }
+}
+
} // namespace doc
} // namespace clang
Index: clang-tools-extra/clang-doc/BitcodeWriter.h
===================================================================
--- clang-tools-extra/clang-doc/BitcodeWriter.h
+++ clang-tools-extra/clang-doc/BitcodeWriter.h
@@ -68,11 +68,10 @@
// New Ids need to be added to the enum here, and to the relevant IdNameMap and
// initialization list in the implementation file.
-#define INFORECORDS(X) X##_USR, X##_NAME
-
enum RecordId {
VERSION = 1,
- INFORECORDS(FUNCTION),
+ FUNCTION_USR,
+ FUNCTION_NAME,
FUNCTION_DEFLOCATION,
FUNCTION_LOCATION,
FUNCTION_ACCESS,
@@ -91,13 +90,16 @@
FIELD_TYPE_NAME,
MEMBER_TYPE_NAME,
MEMBER_TYPE_ACCESS,
- INFORECORDS(NAMESPACE),
- INFORECORDS(ENUM),
+ NAMESPACE_USR,
+ NAMESPACE_NAME,
+ ENUM_USR,
+ ENUM_NAME,
ENUM_DEFLOCATION,
ENUM_LOCATION,
ENUM_MEMBER,
ENUM_SCOPED,
- INFORECORDS(RECORD),
+ RECORD_USR,
+ RECORD_NAME,
RECORD_DEFLOCATION,
RECORD_LOCATION,
RECORD_TAG_TYPE,
@@ -112,10 +114,8 @@
static constexpr unsigned BlockIdCount = BI_LAST - BI_FIRST;
static constexpr unsigned RecordIdCount = RI_LAST - RI_FIRST;
-#undef INFORECORDS
-
// Identifiers for differentiating between subblocks
-enum class FieldId { F_default, F_namespace, F_parent, F_vparent, F_type };
+enum class FieldId { F_default, F_namespace, F_parent, F_vparent, F_type, F_child_namespace, F_child_record };
class ClangDocBitcodeWriter {
public:
Index: clang-tools-extra/clang-doc/BitcodeWriter.cpp
===================================================================
--- clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -434,6 +434,14 @@
emitBlock(N, FieldId::F_namespace);
for (const auto &CI : I.Description)
emitBlock(CI);
+ for (const auto &C : I.ChildNamespaces)
+ emitBlock(C, FieldId::F_child_namespace);
+ for (const auto &C : I.ChildRecords)
+ emitBlock(C, FieldId::F_child_record);
+ for (const auto &C : I.ChildFunctions)
+ emitBlock(C);
+ for (const auto &C : I.ChildEnums)
+ emitBlock(C);
}
void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) {
@@ -472,6 +480,14 @@
emitBlock(P, FieldId::F_parent);
for (const auto &P : I.VirtualParents)
emitBlock(P, FieldId::F_vparent);
+ for (const auto &C : I.ChildNamespaces)
+ emitBlock(C, FieldId::F_child_namespace);
+ for (const auto &C : I.ChildRecords)
+ emitBlock(C, FieldId::F_child_record);
+ for (const auto &C : I.ChildFunctions)
+ emitBlock(C);
+ for (const auto &C : I.ChildEnums)
+ emitBlock(C);
}
void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) {
Index: clang-tools-extra/clang-doc/BitcodeReader.h
===================================================================
--- clang-tools-extra/clang-doc/BitcodeReader.h
+++ clang-tools-extra/clang-doc/BitcodeReader.h
@@ -19,6 +19,7 @@
#include "BitcodeWriter.h"
#include "Representation.h"
#include "clang/AST/AST.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitcode/BitstreamReader.h"
@@ -31,7 +32,7 @@
ClangDocBitcodeReader(llvm::BitstreamCursor &Stream) : Stream(Stream) {}
// Main entry point, calls readBlock to read each block in the given stream.
- std::vector<std::unique_ptr<Info>> readBitcode();
+ llvm::Expected<std::vector<std::unique_ptr<Info>>> readBitcode();
private:
enum class Cursor { BadBlock = 1, Record, BlockEnd, BlockBegin };
Index: clang-tools-extra/clang-doc/BitcodeReader.cpp
===================================================================
--- clang-tools-extra/clang-doc/BitcodeReader.cpp
+++ clang-tools-extra/clang-doc/BitcodeReader.cpp
@@ -100,6 +100,8 @@
case FieldId::F_parent:
case FieldId::F_vparent:
case FieldId::F_type:
+ case FieldId::F_child_namespace:
+ case FieldId::F_child_record:
case FieldId::F_default:
Field = F;
return true;
@@ -372,6 +374,12 @@
case FieldId::F_namespace:
I->Namespace.emplace_back(std::move(R));
break;
+ case FieldId::F_child_namespace:
+ I->ChildNamespaces.emplace_back(std::move(R));
+ break;
+ case FieldId::F_child_record:
+ I->ChildRecords.emplace_back(std::move(R));
+ break;
default:
llvm::errs() << "Invalid field type for info.\n";
exit(1);
@@ -403,12 +411,39 @@
case FieldId::F_vparent:
I->VirtualParents.emplace_back(std::move(R));
break;
+ case FieldId::F_child_namespace:
+ I->ChildNamespaces.emplace_back(std::move(R));
+ break;
+ case FieldId::F_child_record:
+ I->ChildRecords.emplace_back(std::move(R));
+ break;
default:
llvm::errs() << "Invalid field type for info.\n";
exit(1);
}
}
+template <typename T, typename ChildInfoType> void addChild(T I, ChildInfoType &&R) {
+ llvm::errs() << "Invalid child type for info.\n";
+ exit(1);
+}
+
+template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
+ I->ChildFunctions.emplace_back(std::move(R));
+}
+
+template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
+ I->ChildEnums.emplace_back(std::move(R));
+}
+
+template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
+ I->ChildFunctions.emplace_back(std::move(R));
+}
+
+template <> void addChild(RecordInfo *I, EnumInfo &&R) {
+ I->ChildEnums.emplace_back(std::move(R));
+}
+
// Read records from bitcode into a given info.
template <typename T> bool ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
Record R;
@@ -455,7 +490,7 @@
template <typename T>
bool ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
switch (ID) {
- // Blocks can only have Comment, Reference, or TypeInfo subblocks
+ // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or EnumInfo subblocks
case BI_COMMENT_BLOCK_ID:
if (readBlock(ID, getCommentInfo(I)))
return true;
@@ -492,6 +527,22 @@
}
return false;
}
+ case BI_FUNCTION_BLOCK_ID: {
+ FunctionInfo F;
+ if (readBlock(ID, &F)) {
+ addChild(I, std::move(F));
+ return true;
+ }
+ return false;
+ }
+ case BI_ENUM_BLOCK_ID: {
+ EnumInfo E;
+ if (readBlock(ID, &E)) {
+ addChild(I, std::move(E));
+ return true;
+ }
+ return false;
+ }
default:
llvm::errs() << "Invalid subblock type.\n";
return false;
@@ -573,16 +624,20 @@
}
// Entry point
-std::vector<std::unique_ptr<Info>> ClangDocBitcodeReader::readBitcode() {
+llvm::Expected<std::vector<std::unique_ptr<Info>>> ClangDocBitcodeReader::readBitcode() {
std::vector<std::unique_ptr<Info>> Infos;
if (!validateStream())
- return Infos;
+ return llvm::make_error<llvm::StringError>(
+ "Invalid bitcode stream.\n",
+ llvm::inconvertibleErrorCode());;
// Read the top level blocks.
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code != llvm::bitc::ENTER_SUBBLOCK)
- return Infos;
+ return llvm::make_error<llvm::StringError>(
+ "Missing subblock in bitcode.\n",
+ llvm::inconvertibleErrorCode());;
unsigned ID = Stream.ReadSubBlockID();
switch (ID) {
@@ -592,24 +647,28 @@
case BI_MEMBER_TYPE_BLOCK_ID:
case BI_COMMENT_BLOCK_ID:
case BI_REFERENCE_BLOCK_ID:
- llvm::errs() << "Invalid top level block.\n";
- return Infos;
+ return llvm::make_error<llvm::StringError>(
+ "Invalid top level block in bitcode.\n",
+ llvm::inconvertibleErrorCode());;
case BI_NAMESPACE_BLOCK_ID:
case BI_RECORD_BLOCK_ID:
case BI_ENUM_BLOCK_ID:
case BI_FUNCTION_BLOCK_ID:
- if (std::unique_ptr<Info> I = readBlockToInfo(ID)) {
+ if (std::unique_ptr<Info> I = readBlockToInfo(ID))
Infos.emplace_back(std::move(I));
- }
return Infos;
case BI_VERSION_BLOCK_ID:
if (readBlock(ID, VersionNumber))
continue;
- return Infos;
+ return llvm::make_error<llvm::StringError>(
+ "Invalid bitcode version in bitcode.\n",
+ llvm::inconvertibleErrorCode());;
case llvm::bitc::BLOCKINFO_BLOCK_ID:
if (readBlockInfoBlock())
continue;
- return Infos;
+ return llvm::make_error<llvm::StringError>(
+ "Invalid BlockInfo in bitcode.\n",
+ llvm::inconvertibleErrorCode());;
default:
if (!Stream.SkipBlock())
continue;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits