diff options
| author | Aaron Ballman <aaron@aaronballman.com> | 2019-06-24 20:07:11 +0000 |
|---|---|---|
| committer | Aaron Ballman <aaron@aaronballman.com> | 2019-06-24 20:07:11 +0000 |
| commit | a612e34c1473a74bc0c3a7fb1ec0cd3f550fb529 (patch) | |
| tree | 1888304113f9c1a829b7b40c099836c75f2ecc11 /clang/lib | |
| parent | 9c8282a9b33084d95c579e9f76daddfcd2f74c32 (diff) | |
| download | bcm5719-llvm-a612e34c1473a74bc0c3a7fb1ec0cd3f550fb529.tar.gz bcm5719-llvm-a612e34c1473a74bc0c3a7fb1ec0cd3f550fb529.zip | |
Augment location information when dumping the AST to JSON.
Rather than create JSON objects for source locations and ranges, we instead stream them out directly. This allows us to elide duplicate information (without JSON field reordering causing an issue) like file names and line numbers, similar to the text dump. This also adds token length information when dumping the source location.
llvm-svn: 364226
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/JSONNodeDumper.cpp | 77 |
1 files changed, 44 insertions, 33 deletions
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 6092b7b5a35..2bb72f9fe9b 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -1,4 +1,5 @@ #include "clang/AST/JSONNodeDumper.h" +#include "clang/Lex/Lexer.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; @@ -28,7 +29,7 @@ void JSONNodeDumper::Visit(const Attr *A) { } JOS.attribute("id", createPointerRepresentation(A)); JOS.attribute("kind", AttrName); - JOS.attribute("range", createSourceRange(A->getRange())); + JOS.attributeObject("range", [A, this] { writeSourceRange(A->getRange()); }); attributeOnlyIfTrue("inherited", A->isInherited()); attributeOnlyIfTrue("implicit", A->isImplicit()); @@ -47,7 +48,8 @@ void JSONNodeDumper::Visit(const Stmt *S) { JOS.attribute("id", createPointerRepresentation(S)); JOS.attribute("kind", S->getStmtClassName()); - JOS.attribute("range", createSourceRange(S->getSourceRange())); + JOS.attributeObject("range", + [S, this] { writeSourceRange(S->getSourceRange()); }); if (const auto *E = dyn_cast<Expr>(S)) { JOS.attribute("type", createQualType(E->getType())); @@ -90,8 +92,10 @@ void JSONNodeDumper::Visit(const Decl *D) { return; JOS.attribute("kind", (llvm::Twine(D->getDeclKindName()) + "Decl").str()); - JOS.attribute("loc", createSourceLocation(D->getLocation())); - JOS.attribute("range", createSourceRange(D->getSourceRange())); + JOS.attributeObject("loc", + [D, this] { writeSourceLocation(D->getLocation()); }); + JOS.attributeObject("range", + [D, this] { writeSourceRange(D->getSourceRange()); }); attributeOnlyIfTrue("isImplicit", D->isImplicit()); attributeOnlyIfTrue("isInvalid", D->isInvalidDecl()); @@ -118,8 +122,10 @@ void JSONNodeDumper::Visit(const comments::Comment *C, JOS.attribute("id", createPointerRepresentation(C)); JOS.attribute("kind", C->getCommentKindName()); - JOS.attribute("loc", createSourceLocation(C->getLocation())); - JOS.attribute("range", createSourceRange(C->getSourceRange())); + JOS.attributeObject("loc", + [C, this] { writeSourceLocation(C->getLocation()); }); + JOS.attributeObject("range", + [C, this] { writeSourceRange(C->getSourceRange()); }); InnerCommentVisitor::visit(C, FC); } @@ -128,7 +134,7 @@ void JSONNodeDumper::Visit(const TemplateArgument &TA, SourceRange R, const Decl *From, StringRef Label) { JOS.attribute("kind", "TemplateArgument"); if (R.isValid()) - JOS.attribute("range", createSourceRange(R)); + JOS.attributeObject("range", [R, this] { writeSourceRange(R); }); if (From) JOS.attribute(Label.empty() ? "fromDecl" : Label, createBareDeclRef(From)); @@ -165,43 +171,47 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { attributeOnlyIfTrue("selected", A.isSelected()); } -llvm::json::Object -JSONNodeDumper::createBareSourceLocation(SourceLocation Loc) { +void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc) { PresumedLoc Presumed = SM.getPresumedLoc(Loc); - if (Presumed.isInvalid()) - return llvm::json::Object{}; - - return llvm::json::Object{{"file", Presumed.getFilename()}, - {"line", Presumed.getLine()}, - {"col", Presumed.getColumn()}}; + if (Presumed.isValid()) { + if (LastLocFilename != Presumed.getFilename()) { + JOS.attribute("file", Presumed.getFilename()); + JOS.attribute("line", Presumed.getLine()); + } else if (LastLocLine != Presumed.getLine()) + JOS.attribute("line", Presumed.getLine()); + JOS.attribute("col", Presumed.getColumn()); + JOS.attribute("tokLen", + Lexer::MeasureTokenLength(Loc, SM, Ctx.getLangOpts())); + LastLocFilename = Presumed.getFilename(); + LastLocLine = Presumed.getLine(); + } } -llvm::json::Object JSONNodeDumper::createSourceLocation(SourceLocation Loc) { +void JSONNodeDumper::writeSourceLocation(SourceLocation Loc) { SourceLocation Spelling = SM.getSpellingLoc(Loc); SourceLocation Expansion = SM.getExpansionLoc(Loc); - llvm::json::Object SLoc = createBareSourceLocation(Spelling); if (Expansion != Spelling) { // If the expansion and the spelling are different, output subobjects // describing both locations. - llvm::json::Object ELoc = createBareSourceLocation(Expansion); - - // If there is a macro expansion, add extra information if the interesting - // bit is the macro arg expansion. - if (SM.isMacroArgExpansion(Loc)) - ELoc["isMacroArgExpansion"] = true; - - return llvm::json::Object{{"spellingLoc", std::move(SLoc)}, - {"expansionLoc", std::move(ELoc)}}; - } - - return SLoc; + JOS.attributeObject( + "spellingLoc", [Spelling, this] { writeBareSourceLocation(Spelling); }); + JOS.attributeObject("expansionLoc", [Expansion, Loc, this] { + writeBareSourceLocation(Expansion); + // If there is a macro expansion, add extra information if the interesting + // bit is the macro arg expansion. + if (SM.isMacroArgExpansion(Loc)) + JOS.attribute("isMacroArgExpansion", true); + }); + } else + writeBareSourceLocation(Spelling); } -llvm::json::Object JSONNodeDumper::createSourceRange(SourceRange R) { - return llvm::json::Object{{"begin", createSourceLocation(R.getBegin())}, - {"end", createSourceLocation(R.getEnd())}}; +void JSONNodeDumper::writeSourceRange(SourceRange R) { + JOS.attributeObject("begin", + [R, this] { writeSourceLocation(R.getBegin()); }); + JOS.attributeObject("end", [R, this] { writeSourceLocation(R.getEnd()); }); } std::string JSONNodeDumper::createPointerRepresentation(const void *Ptr) { @@ -523,7 +533,8 @@ void JSONNodeDumper::VisitConstantArrayType(const ConstantArrayType *CAT) { void JSONNodeDumper::VisitDependentSizedExtVectorType( const DependentSizedExtVectorType *VT) { - JOS.attribute("attrLoc", createSourceLocation(VT->getAttributeLoc())); + JOS.attributeObject( + "attrLoc", [VT, this] { writeSourceLocation(VT->getAttributeLoc()); }); } void JSONNodeDumper::VisitVectorType(const VectorType *VT) { |

