Print enum constant values using the original source formatting
if possible when creating "Declaration" nodes in XML comments
rdar://14765746
llvm-svn: 311085
diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h
index 274df22..54fe398 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -50,7 +50,8 @@
UseVoidForZeroParams(!LO.CPlusPlus),
TerseOutput(false), PolishForDeclaration(false),
Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
- IncludeNewlines(true), MSVCFormatting(false) { }
+ IncludeNewlines(true), MSVCFormatting(false),
+ ConstantsAsWritten(false) { }
/// \brief Adjust this printing policy for cases where it's known that
/// we're printing C++ code (for instance, if AST dumping reaches a
@@ -200,6 +201,24 @@
/// prints anonymous namespaces as `anonymous namespace' and does not insert
/// spaces after template arguments.
bool MSVCFormatting : 1;
+
+ /// \brief Whether we should print the constant expressions as written in the
+ /// sources.
+ ///
+ /// This flag determines whether constants expressions like
+ ///
+ /// \code
+ /// 0x10
+ /// 2.5e3
+ /// \endcode
+ ///
+ /// will be printed as written or as follows:
+ ///
+ /// \code
+ /// 0x10
+ /// 2.5e3
+ /// \endcode
+ bool ConstantsAsWritten;
};
} // end namespace clang
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index c210bd1..795f4d6 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -389,8 +389,8 @@
/// back to its original source language syntax.
void dumpPretty(const ASTContext &Context) const;
void printPretty(raw_ostream &OS, PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0) const;
+ const PrintingPolicy &Policy, unsigned Indentation = 0,
+ const ASTContext *Context = nullptr) const;
/// viewAST - Visualize an AST rooted at this Stmt* using GraphViz. Only
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 6eeba88..00db026 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -28,6 +28,7 @@
class DeclPrinter : public DeclVisitor<DeclPrinter> {
raw_ostream &Out;
PrintingPolicy Policy;
+ const ASTContext &Context;
unsigned Indentation;
bool PrintInstantiation;
@@ -48,9 +49,10 @@
public:
DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
- unsigned Indentation = 0, bool PrintInstantiation = false)
- : Out(Out), Policy(Policy), Indentation(Indentation),
- PrintInstantiation(PrintInstantiation) { }
+ const ASTContext &Context, unsigned Indentation = 0,
+ bool PrintInstantiation = false)
+ : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
+ PrintInstantiation(PrintInstantiation) {}
void VisitDeclContext(DeclContext *DC, bool Indent = true);
@@ -115,7 +117,8 @@
void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation, bool PrintInstantiation) const {
- DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation);
+ DeclPrinter Printer(Out, Policy, getASTContext(), Indentation,
+ PrintInstantiation);
Printer.Visit(const_cast<Decl*>(this));
}
@@ -192,7 +195,7 @@
DC = DC->getParent();
ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
- DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), 0);
+ DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0);
Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
}
@@ -467,7 +470,7 @@
prettyPrintAttributes(D);
if (Expr *Init = D->getInitExpr()) {
Out << " = ";
- Init->printPretty(Out, nullptr, Policy, Indentation);
+ Init->printPretty(Out, nullptr, Policy, Indentation, &Context);
}
}
@@ -521,7 +524,7 @@
Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
llvm::raw_string_ostream POut(Proto);
- DeclPrinter TArgPrinter(POut, SubPolicy, Indentation);
+ DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
TArgPrinter.printTemplateArguments(*TArgs);
}
@@ -539,7 +542,7 @@
Proto += "(";
if (FT) {
llvm::raw_string_ostream POut(Proto);
- DeclPrinter ParamPrinter(POut, SubPolicy, Indentation);
+ DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
if (i) POut << ", ";
ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
@@ -695,7 +698,7 @@
// This is a K&R function definition, so we need to print the
// parameters.
Out << '\n';
- DeclPrinter ParamPrinter(Out, SubPolicy, Indentation);
+ DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
Indentation += Policy.Indentation;
for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
Indent();
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index e3b9628..950d0e2 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -24,6 +24,7 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
using namespace clang;
@@ -38,12 +39,14 @@
unsigned IndentLevel;
clang::PrinterHelper* Helper;
PrintingPolicy Policy;
+ const ASTContext *Context;
public:
- StmtPrinter(raw_ostream &os, PrinterHelper* helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0)
- : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy) {}
+ StmtPrinter(raw_ostream &os, PrinterHelper *helper,
+ const PrintingPolicy &Policy, unsigned Indentation = 0,
+ const ASTContext *Context = nullptr)
+ : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
+ Context(Context) {}
void PrintStmt(Stmt *S) {
PrintStmt(S, Policy.Indentation);
@@ -1441,7 +1444,26 @@
}
}
+/// Prints the given expression using the original source text. Returns true on
+/// success, false otherwise.
+static bool printExprAsWritten(raw_ostream &OS, Expr *E,
+ const ASTContext *Context) {
+ if (!Context)
+ return false;
+ bool Invalid = false;
+ StringRef Source = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(E->getSourceRange()),
+ Context->getSourceManager(), Context->getLangOpts(), &Invalid);
+ if (!Invalid) {
+ OS << Source;
+ return true;
+ }
+ return false;
+}
+
void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
+ if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+ return;
bool isSigned = Node->getType()->isSignedIntegerType();
OS << Node->getValue().toString(10, isSigned);
@@ -1485,6 +1507,8 @@
}
void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
+ if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+ return;
PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
}
@@ -2696,11 +2720,10 @@
printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
}
-void Stmt::printPretty(raw_ostream &OS,
- PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation) const {
- StmtPrinter P(OS, Helper, Policy, Indentation);
+void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy, unsigned Indentation,
+ const ASTContext *Context) const {
+ StmtPrinter P(OS, Helper, Policy, Indentation, Context);
P.Visit(const_cast<Stmt*>(this));
}
diff --git a/clang/lib/Index/CommentToXML.cpp b/clang/lib/Index/CommentToXML.cpp
index e568c83..918068a 100644
--- a/clang/lib/Index/CommentToXML.cpp
+++ b/clang/lib/Index/CommentToXML.cpp
@@ -579,6 +579,7 @@
PrintingPolicy PPolicy(LangOpts);
PPolicy.PolishForDeclaration = true;
PPolicy.TerseOutput = true;
+ PPolicy.ConstantsAsWritten = true;
ThisDecl->CurrentDecl->print(OS, PPolicy,
/*Indentation*/0, /*PrintInstantiation*/false);
}
diff --git a/clang/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp b/clang/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp
new file mode 100644
index 0000000..26ca223
--- /dev/null
+++ b/clang/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp
@@ -0,0 +1,26 @@
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 | FileCheck %s
+
+constexpr int value(float f) { return int(f); }
+
+enum MyEnum {
+hexadecimal = 0x10 //!< a
+// CHECK: <Declaration>hexadecimal = 0x10</Declaration>
+
+, withSuffix = 1u + 010 //!< b
+// CHECK: <Declaration>withSuffix = 1u + 010</Declaration>
+
+#define ARG(x) x
+, macroArg = ARG(0x1) //!< c
+// CHECK: <Declaration>macroArg = ARG(0x1)</Declaration>
+
+#define MACROCONCAT(x, y) 22##x##y
+, macroConcat = MACROCONCAT(3, 2) //!< d
+// CHECK: <Declaration>macroConcat = MACROCONCAT(3, 2)</Declaration>
+
+#define MACRO(a,n) = 0x##a##n
+, weirdMacros MACRO(2,1) //!< e
+// CHECK: <Declaration>weirdMacros = 33</Declaration>
+
+, floatLiteral = value(0.25e3) //!< f
+// CHECK: <Declaration>floatLiteral = value(0.25e3)</Declaration>
+};