1
1
#include " clang/AST/JSONNodeDumper.h"
2
+ #include " clang/Lex/Lexer.h"
2
3
#include " llvm/ADT/StringSwitch.h"
3
4
4
5
using namespace clang ;
@@ -28,7 +29,7 @@ void JSONNodeDumper::Visit(const Attr *A) {
28
29
}
29
30
JOS.attribute (" id" , createPointerRepresentation (A));
30
31
JOS.attribute (" kind" , AttrName);
31
- JOS.attribute (" range" , createSourceRange (A->getRange ()));
32
+ JOS.attributeObject (" range" , [A, this ] { writeSourceRange (A->getRange ()); } );
32
33
attributeOnlyIfTrue (" inherited" , A->isInherited ());
33
34
attributeOnlyIfTrue (" implicit" , A->isImplicit ());
34
35
@@ -47,7 +48,8 @@ void JSONNodeDumper::Visit(const Stmt *S) {
47
48
48
49
JOS.attribute (" id" , createPointerRepresentation (S));
49
50
JOS.attribute (" kind" , S->getStmtClassName ());
50
- JOS.attribute (" range" , createSourceRange (S->getSourceRange ()));
51
+ JOS.attributeObject (" range" ,
52
+ [S, this ] { writeSourceRange (S->getSourceRange ()); });
51
53
52
54
if (const auto *E = dyn_cast<Expr>(S)) {
53
55
JOS.attribute (" type" , createQualType (E->getType ()));
@@ -90,8 +92,10 @@ void JSONNodeDumper::Visit(const Decl *D) {
90
92
return ;
91
93
92
94
JOS.attribute (" kind" , (llvm::Twine (D->getDeclKindName ()) + " Decl" ).str ());
93
- JOS.attribute (" loc" , createSourceLocation (D->getLocation ()));
94
- JOS.attribute (" range" , createSourceRange (D->getSourceRange ()));
95
+ JOS.attributeObject (" loc" ,
96
+ [D, this ] { writeSourceLocation (D->getLocation ()); });
97
+ JOS.attributeObject (" range" ,
98
+ [D, this ] { writeSourceRange (D->getSourceRange ()); });
95
99
attributeOnlyIfTrue (" isImplicit" , D->isImplicit ());
96
100
attributeOnlyIfTrue (" isInvalid" , D->isInvalidDecl ());
97
101
@@ -118,8 +122,10 @@ void JSONNodeDumper::Visit(const comments::Comment *C,
118
122
119
123
JOS.attribute (" id" , createPointerRepresentation (C));
120
124
JOS.attribute (" kind" , C->getCommentKindName ());
121
- JOS.attribute (" loc" , createSourceLocation (C->getLocation ()));
122
- JOS.attribute (" range" , createSourceRange (C->getSourceRange ()));
125
+ JOS.attributeObject (" loc" ,
126
+ [C, this ] { writeSourceLocation (C->getLocation ()); });
127
+ JOS.attributeObject (" range" ,
128
+ [C, this ] { writeSourceRange (C->getSourceRange ()); });
123
129
124
130
InnerCommentVisitor::visit (C, FC);
125
131
}
@@ -128,7 +134,7 @@ void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R,
128
134
const Decl *From, StringRef Label) {
129
135
JOS.attribute (" kind" , " TemplateArgument" );
130
136
if (R.isValid ())
131
- JOS.attribute (" range" , createSourceRange (R));
137
+ JOS.attributeObject (" range" , [R, this ] { writeSourceRange (R); } );
132
138
133
139
if (From)
134
140
JOS.attribute (Label.empty () ? " fromDecl" : Label, createBareDeclRef (From));
@@ -165,43 +171,47 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
165
171
attributeOnlyIfTrue (" selected" , A.isSelected ());
166
172
}
167
173
168
- llvm::json::Object
169
- JSONNodeDumper::createBareSourceLocation (SourceLocation Loc) {
174
+ void JSONNodeDumper::writeBareSourceLocation (SourceLocation Loc) {
170
175
PresumedLoc Presumed = SM.getPresumedLoc (Loc);
171
176
172
- if (Presumed.isInvalid ())
173
- return llvm::json::Object{};
174
-
175
- return llvm::json::Object{{" file" , Presumed.getFilename ()},
176
- {" line" , Presumed.getLine ()},
177
- {" col" , Presumed.getColumn ()}};
177
+ if (Presumed.isValid ()) {
178
+ if (LastLocFilename != Presumed.getFilename ()) {
179
+ JOS.attribute (" file" , Presumed.getFilename ());
180
+ JOS.attribute (" line" , Presumed.getLine ());
181
+ } else if (LastLocLine != Presumed.getLine ())
182
+ JOS.attribute (" line" , Presumed.getLine ());
183
+ JOS.attribute (" col" , Presumed.getColumn ());
184
+ JOS.attribute (" tokLen" ,
185
+ Lexer::MeasureTokenLength (Loc, SM, Ctx.getLangOpts ()));
186
+ LastLocFilename = Presumed.getFilename ();
187
+ LastLocLine = Presumed.getLine ();
188
+ }
178
189
}
179
190
180
- llvm::json::Object JSONNodeDumper::createSourceLocation (SourceLocation Loc) {
191
+ void JSONNodeDumper::writeSourceLocation (SourceLocation Loc) {
181
192
SourceLocation Spelling = SM.getSpellingLoc (Loc);
182
193
SourceLocation Expansion = SM.getExpansionLoc (Loc);
183
194
184
- llvm::json::Object SLoc = createBareSourceLocation (Spelling);
185
195
if (Expansion != Spelling) {
186
196
// If the expansion and the spelling are different, output subobjects
187
197
// describing both locations.
188
- llvm::json::Object ELoc = createBareSourceLocation (Expansion);
189
-
190
- // If there is a macro expansion, add extra information if the interesting
191
- // bit is the macro arg expansion.
192
- if (SM.isMacroArgExpansion (Loc))
193
- ELoc[" isMacroArgExpansion" ] = true ;
194
-
195
- return llvm::json::Object{{" spellingLoc" , std::move (SLoc)},
196
- {" expansionLoc" , std::move (ELoc)}};
197
- }
198
-
199
- return SLoc;
198
+ JOS.attributeObject (
199
+ " spellingLoc" , [Spelling, this ] { writeBareSourceLocation (Spelling); });
200
+ JOS.attributeObject (" expansionLoc" , [Expansion, Loc, this ] {
201
+ writeBareSourceLocation (Expansion);
202
+ // If there is a macro expansion, add extra information if the interesting
203
+ // bit is the macro arg expansion.
204
+ if (SM.isMacroArgExpansion (Loc))
205
+ JOS.attribute (" isMacroArgExpansion" , true );
206
+ });
207
+ } else
208
+ writeBareSourceLocation (Spelling);
200
209
}
201
210
202
- llvm::json::Object JSONNodeDumper::createSourceRange (SourceRange R) {
203
- return llvm::json::Object{{" begin" , createSourceLocation (R.getBegin ())},
204
- {" end" , createSourceLocation (R.getEnd ())}};
211
+ void JSONNodeDumper::writeSourceRange (SourceRange R) {
212
+ JOS.attributeObject (" begin" ,
213
+ [R, this ] { writeSourceLocation (R.getBegin ()); });
214
+ JOS.attributeObject (" end" , [R, this ] { writeSourceLocation (R.getEnd ()); });
205
215
}
206
216
207
217
std::string JSONNodeDumper::createPointerRepresentation (const void *Ptr ) {
@@ -523,7 +533,8 @@ void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) {
523
533
524
534
void JSONNodeDumper::VisitDependentSizedExtVectorType (
525
535
const DependentSizedExtVectorType *VT) {
526
- JOS.attribute (" attrLoc" , createSourceLocation (VT->getAttributeLoc ()));
536
+ JOS.attributeObject (
537
+ " attrLoc" , [VT, this ] { writeSourceLocation (VT->getAttributeLoc ()); });
527
538
}
528
539
529
540
void JSONNodeDumper::VisitVectorType (const VectorType *VT) {
0 commit comments