aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/JSONNodeDumper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/JSONNodeDumper.cpp')
-rw-r--r--lib/AST/JSONNodeDumper.cpp49
1 files changed, 45 insertions, 4 deletions
diff --git a/lib/AST/JSONNodeDumper.cpp b/lib/AST/JSONNodeDumper.cpp
index 04b933b0fb30..f60d761c996c 100644
--- a/lib/AST/JSONNodeDumper.cpp
+++ b/lib/AST/JSONNodeDumper.cpp
@@ -66,6 +66,10 @@ void JSONNodeDumper::Visit(const Stmt *S) {
void JSONNodeDumper::Visit(const Type *T) {
JOS.attribute("id", createPointerRepresentation(T));
+
+ if (!T)
+ return;
+
JOS.attribute("kind", (llvm::Twine(T->getTypeClassName()) + "Type").str());
JOS.attribute("type", createQualType(QualType(T, 0), /*Desugar*/ false));
attributeOnlyIfTrue("isDependent", T->isDependentType());
@@ -107,9 +111,14 @@ void JSONNodeDumper::Visit(const Decl *D) {
if (const auto *ND = dyn_cast<NamedDecl>(D))
attributeOnlyIfTrue("isHidden", ND->isHidden());
- if (D->getLexicalDeclContext() != D->getDeclContext())
- JOS.attribute("parentDeclContext",
- createPointerRepresentation(D->getDeclContext()));
+ if (D->getLexicalDeclContext() != D->getDeclContext()) {
+ // Because of multiple inheritance, a DeclContext pointer does not produce
+ // the same pointer representation as a Decl pointer that references the
+ // same AST Node.
+ const auto *ParentDeclContextDecl = dyn_cast<Decl>(D->getDeclContext());
+ JOS.attribute("parentDeclContextId",
+ createPointerRepresentation(ParentDeclContextDecl));
+ }
addPreviousDeclaration(D);
InnerDeclVisitor::Visit(D);
@@ -171,12 +180,30 @@ void JSONNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) {
attributeOnlyIfTrue("selected", A.isSelected());
}
+void JSONNodeDumper::writeIncludeStack(PresumedLoc Loc, bool JustFirst) {
+ if (Loc.isInvalid())
+ return;
+
+ JOS.attributeBegin("includedFrom");
+ JOS.objectBegin();
+
+ if (!JustFirst) {
+ // Walk the stack recursively, then print out the presumed location.
+ writeIncludeStack(SM.getPresumedLoc(Loc.getIncludeLoc()));
+ }
+
+ JOS.attribute("file", Loc.getFilename());
+ JOS.objectEnd();
+ JOS.attributeEnd();
+}
+
void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc,
bool IsSpelling) {
PresumedLoc Presumed = SM.getPresumedLoc(Loc);
unsigned ActualLine = IsSpelling ? SM.getSpellingLineNumber(Loc)
: SM.getExpansionLineNumber(Loc);
if (Presumed.isValid()) {
+ JOS.attribute("offset", SM.getDecomposedLoc(Loc).second);
if (LastLocFilename != Presumed.getFilename()) {
JOS.attribute("file", Presumed.getFilename());
JOS.attribute("line", ActualLine);
@@ -193,6 +220,12 @@ void JSONNodeDumper::writeBareSourceLocation(SourceLocation Loc,
LastLocFilename = Presumed.getFilename();
LastLocPresumedLine = PresumedLine;
LastLocLine = ActualLine;
+
+ // Orthogonal to the file, line, and column de-duplication is whether the
+ // given location was a result of an include. If so, print where the
+ // include location came from.
+ writeIncludeStack(SM.getPresumedLoc(Presumed.getIncludeLoc()),
+ /*JustFirst*/ true);
}
}
@@ -238,6 +271,8 @@ llvm::json::Object JSONNodeDumper::createQualType(QualType QT, bool Desugar) {
SplitQualType DSQT = QT.getSplitDesugaredType();
if (DSQT != SQT)
Ret["desugaredQualType"] = QualType::getAsString(DSQT, PrintPolicy);
+ if (const auto *TT = QT->getAs<TypedefType>())
+ Ret["typeAliasDeclId"] = createPointerRepresentation(TT->getDecl());
}
return Ret;
}
@@ -275,7 +310,7 @@ llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {
const CXXBaseSpecifier *Base = *I;
const auto *RD =
- cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
llvm::json::Object Val{{"name", RD->getName()}};
if (Base->isVirtual())
@@ -839,6 +874,12 @@ void JSONNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *LSD) {
switch (LSD->getLanguage()) {
case LinkageSpecDecl::lang_c: Lang = "C"; break;
case LinkageSpecDecl::lang_cxx: Lang = "C++"; break;
+ case LinkageSpecDecl::lang_cxx_11:
+ Lang = "C++11";
+ break;
+ case LinkageSpecDecl::lang_cxx_14:
+ Lang = "C++14";
+ break;
}
JOS.attribute("language", Lang);
attributeOnlyIfTrue("hasBraces", LSD->hasBraces());