From d249e1d1f1498b81314459ceda19d6ff25c278ad Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 29 May 2009 20:38:28 +0000 Subject: [PATCH] Create a new PrintingPolicy class, which we pass down through the AST printing logic to help customize the output. For now, we use this rather than a special flag to suppress the "struct" when printing "struct X" and to print the Boolean type as "bool" in C++ but "_Bool" in C. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72590 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 4 +- include/clang/AST/NestedNameSpecifier.h | 3 +- include/clang/AST/PrettyPrinter.h | 60 ++++++- include/clang/AST/Stmt.h | 7 +- include/clang/AST/TemplateName.h | 4 +- include/clang/AST/Type.h | 74 ++++----- lib/AST/ASTContext.cpp | 1 + lib/AST/CFG.cpp | 37 +++-- lib/AST/Decl.cpp | 6 +- lib/AST/NestedNameSpecifier.cpp | 18 ++- lib/AST/StmtDumper.cpp | 5 +- lib/AST/StmtPrinter.cpp | 41 ++--- lib/AST/TemplateName.cpp | 13 +- lib/AST/Type.cpp | 175 +++++++++++---------- lib/CodeGen/CGDebugInfo.cpp | 4 +- lib/Frontend/ASTConsumers.cpp | 26 +-- lib/Frontend/DocumentXML.cpp | 2 +- lib/Frontend/RewriteBlocks.cpp | 20 ++- lib/Frontend/RewriteObjC.cpp | 22 +-- lib/Sema/Sema.cpp | 2 +- lib/Sema/SemaTemplateInstantiate.cpp | 3 +- test/SemaCXX/bool.cpp | 2 + test/SemaCXX/convert-to-bool.cpp | 2 +- test/SemaCXX/overloaded-operator.cpp | 2 +- test/SemaTemplate/typename-specifier-2.cpp | 2 +- 25 files changed, 326 insertions(+), 209 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 0badd81be0..e99e9f2b18 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -20,6 +20,7 @@ #include "clang/AST/Builtins.h" #include "clang/AST/Decl.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/Basic/SourceLocation.h" @@ -143,6 +144,7 @@ public: SelectorTable &Selectors; DeclarationNameTable DeclarationNames; llvm::OwningPtr ExternalSource; + clang::PrintingPolicy PrintingPolicy; SourceManager& getSourceManager() { return SourceMgr; } const SourceManager& getSourceManager() const { return SourceMgr; } @@ -207,7 +209,7 @@ public: void PrintStats() const; const std::vector& getTypes() const { return Types; } - + //===--------------------------------------------------------------------===// // Type Constructors //===--------------------------------------------------------------------===// diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index 96eebe8be6..4eea1031f0 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -26,6 +26,7 @@ namespace clang { class ASTContext; class NamespaceDecl; class IdentifierInfo; +class PrintingPolicy; class Type; /// \brief Represents a C++ nested name specifier, such as @@ -163,7 +164,7 @@ public: /// \brief Print this nested name specifier to the given output /// stream. - void print(llvm::raw_ostream &OS) const; + void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(Prefix.getOpaqueValue()); diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index f43b59f693..76574bb2b9 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -14,18 +14,74 @@ #ifndef LLVM_CLANG_AST_PRETTY_PRINTER_H #define LLVM_CLANG_AST_PRETTY_PRINTER_H -#include "llvm/Support/raw_ostream.h" +namespace llvm { + class raw_ostream; +} namespace clang { class Stmt; - +class TagDecl; + class PrinterHelper { public: virtual ~PrinterHelper(); virtual bool handledStmt(Stmt* E, llvm::raw_ostream& OS) = 0; }; +/// \brief Describes how types, statements, expressions, and +/// declarations should be printed. +struct PrintingPolicy { + /// \brief Create a default printing policy for C. + PrintingPolicy() + : Indentation(2), CPlusPlus(false), SuppressTypeSpecifiers(false), + SuppressTagKind(false), OwnedTag(0) { } + + /// \brief The number of spaces to use to indent each line. + unsigned Indentation : 8; + + /// \brief Whether we're printing C++ code (otherwise, we're + /// printing C code). + bool CPlusPlus : 1; + + /// \brief Whether we should suppress printing of the actual type + /// specifiers within the type that we are printing. + /// + /// This flag is only used when we are printing declarators beyond + /// the first declarator within a declaration group. For example, given: + /// + /// \code + /// const int *x, *y; + /// \endcode + /// + /// SuppressTypeSpecifiers will be false when printing the + /// declaration for "x", so that we will print "int *x"; it will be + /// \c true when we print "y", so that we suppress printing the + /// "const int" type specifier and instead only print the "*y". + bool SuppressTypeSpecifiers : 1; + + /// \brief If we are printing a tag type, suppresses printing of the + /// kind of tag, e.g., "struct", "union", "enum". + bool SuppressTagKind : 1; + + /// \brief If we are printing a type where the tag type (e.g., a + /// class or enum type) was declared or defined within the type + /// itself, OwnedTag will point at the declaration node owned by + /// this type. + /// + /// Owned tags occur when a tag type is defined as part of the + /// declaration specifiers of another declarator, e.g., + /// + /// \code + /// typedef struct { int x, y; } Point; + /// \endcode + /// + /// Here, the anonymous struct definition is owned by the type of + /// Point. The actual representation uses a DeclGroup to store both + /// the RecordDecl and the TypedefDecl. + TagDecl *OwnedTag; +}; + } // end namespace clang #endif diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 136a83e1a9..9ac540740e 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -17,6 +17,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" #include "clang/Basic/SourceLocation.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/AST/StmtIterator.h" #include "clang/AST/DeclGroup.h" #include "llvm/ADT/SmallVector.h" @@ -35,7 +36,6 @@ namespace clang { class SourceManager; class StringLiteral; class SwitchStmt; - class PrinterHelper; //===----------------------------------------------------------------------===// // ExprIterator - Iterators for iterating over Stmt* arrays that contain @@ -187,8 +187,9 @@ public: /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST /// back to its original source language syntax. void dumpPretty() const; - void printPretty(llvm::raw_ostream &OS, PrinterHelper* = NULL, unsigned = 0, - bool NoIndent=false) const; + void printPretty(llvm::raw_ostream &OS, PrinterHelper* = 0, + const PrintingPolicy &Policy = PrintingPolicy(), + unsigned Indentation = 0) 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/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 76ac8a6f98..511934c1db 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -26,6 +26,7 @@ namespace clang { class DependentTemplateName; class IdentifierInfo; class NestedNameSpecifier; +class PrintingPolicy; class QualifiedTemplateName; class TemplateDecl; @@ -103,7 +104,8 @@ public: /// \param SuppressNNS if true, don't print the /// nested-name-specifier that precedes the template name (if it has /// one). - void print(llvm::raw_ostream &OS, bool SuppressNNS = false) const; + void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, + bool SuppressNNS = false) const; /// \brief Debugging aid that dumps the template name to standard /// error. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 5361ffb730..beca7088be 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -66,6 +66,7 @@ namespace clang { class StmtIteratorBase; class TemplateArgument; class QualifiedNameType; + class PrintingPolicy; // Provide forward declarations for all of the *Type classes #define TYPE(Class, Base) class Class##Type; @@ -180,12 +181,14 @@ public: bool operator!=(const QualType &RHS) const { return Value != RHS.Value; } - std::string getAsString() const { + std::string getAsString() const; + + std::string getAsString(const PrintingPolicy &Policy) const { std::string S; - getAsStringInternal(S); + getAsStringInternal(S, Policy); return S; } - void getAsStringInternal(std::string &Str) const; + void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const; void dump(const char *s) const; void dump() const; @@ -483,7 +486,7 @@ public: QualType getCanonicalTypeInternal() const { return CanonicalType; } void dump() const; - virtual void getAsStringInternal(std::string &InnerString) const = 0; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const = 0; static bool classof(const Type *) { return true; } }; @@ -516,7 +519,7 @@ public: QualType::GCAttrTypes getObjCGCAttr() const { return GCAttrType; } unsigned getAddressSpace() const { return AddressSpace; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getBaseType(), AddressSpace, GCAttrType); @@ -573,9 +576,9 @@ public: TypeKind(K) {} Kind getKind() const { return TypeKind; } - const char *getName() const; + const char *getName(bool CPlusPlus) const; - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } static bool classof(const BuiltinType *) { return true; } @@ -596,7 +599,7 @@ public: bool isSigned() const { return Signed; } const char *getName() const; - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == FixedWidthInt; } static bool classof(const FixedWidthIntType *) { return true; } @@ -615,7 +618,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode { public: QualType getElementType() const { return ElementType; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType()); @@ -639,7 +642,7 @@ class PointerType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. public: - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; QualType getPointeeType() const { return PointeeType; } @@ -670,7 +673,7 @@ public: // Get the pointee type. Pointee is required to always be a function type. QualType getPointeeType() const { return PointeeType; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); @@ -720,7 +723,7 @@ class LValueReferenceType : public ReferenceType { } friend class ASTContext; // ASTContext creates these public: - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == LValueReference; @@ -736,7 +739,7 @@ class RValueReferenceType : public ReferenceType { } friend class ASTContext; // ASTContext creates these public: - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == RValueReference; @@ -764,7 +767,7 @@ public: const Type *getClass() const { return Class; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType(), getClass()); @@ -844,7 +847,7 @@ class ConstantArrayType : public ArrayType { friend class ASTContext; // ASTContext creates these. public: const llvm::APInt &getSize() const { return Size; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getSize(), @@ -874,7 +877,7 @@ class IncompleteArrayType : public ArrayType { friend class ASTContext; // ASTContext creates these. public: - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == IncompleteArray; @@ -928,7 +931,7 @@ public: return (Expr*) SizeExpr; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == VariableArray; @@ -971,7 +974,7 @@ public: return (Expr*) SizeExpr; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == DependentSizedArray; @@ -1010,7 +1013,7 @@ public: QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return NumElements; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getNumElements(), getTypeClass()); @@ -1078,7 +1081,7 @@ public: return unsigned(idx-1) < NumElements; return false; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == ExtVector; @@ -1134,7 +1137,7 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { public: // No additional state past what FunctionType provides. - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getResultType()); @@ -1237,7 +1240,7 @@ public: return exception_begin() + NumExceptions; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == FunctionProto; @@ -1273,7 +1276,7 @@ public: /// looking through the typedefs for B will give you "const volatile A". QualType LookThroughTypedefs() const; - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } static bool classof(const TypedefType *) { return true; } @@ -1287,7 +1290,7 @@ class TypeOfExprType : public Type { public: Expr *getUnderlyingExpr() const { return TOExpr; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == TypeOfExpr; } static bool classof(const TypeOfExprType *) { return true; } @@ -1304,7 +1307,7 @@ class TypeOfType : public Type { public: QualType getUnderlyingType() const { return TOType; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } static bool classof(const TypeOfType *) { return true; } @@ -1331,9 +1334,7 @@ public: bool isBeingDefined() const { return decl.getInt(); } void setBeingDefined(bool Def) { decl.setInt(Def? 1 : 0); } - virtual void getAsStringInternal(std::string &InnerString) const; - void getAsStringInternal(std::string &InnerString, - bool SuppressTagKind) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() >= TagFirst && T->getTypeClass() <= TagLast; @@ -1414,7 +1415,7 @@ public: unsigned getIndex() const { return Index; } IdentifierInfo *getName() const { return Name; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Depth, Index, Name); @@ -1475,7 +1476,8 @@ public: /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. static std::string PrintTemplateArgumentList(const TemplateArgument *Args, - unsigned NumArgs); + unsigned NumArgs, + const PrintingPolicy &Policy); typedef const TemplateArgument * iterator; @@ -1497,7 +1499,7 @@ public: /// \precondition @c isArgType(Arg) const TemplateArgument &getArg(unsigned Idx) const; - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Template, getArgs(), NumArgs); @@ -1540,7 +1542,7 @@ public: /// \brief Retrieve the type named by the qualified-id. QualType getNamedType() const { return NamedType; } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, NNS, NamedType); @@ -1616,7 +1618,7 @@ public: return Name.dyn_cast(); } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, NNS, Name); @@ -1663,7 +1665,7 @@ public: /// interface type, or 0 if there are none. inline unsigned getNumProtocols() const; - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { return T->getTypeClass() == ObjCInterface || T->getTypeClass() == ObjCQualifiedInterface; @@ -1697,7 +1699,7 @@ public: qual_iterator qual_begin() const { return Protocols.begin(); } qual_iterator qual_end() const { return Protocols.end(); } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, @@ -1757,7 +1759,7 @@ public: qual_iterator qual_begin() const { return Protocols.begin(); } qual_iterator qual_end() const { return Protocols.end(); } - virtual void getAsStringInternal(std::string &InnerString) const; + virtual void getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const; void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 00eaa361a3..c719b0bc7d 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -44,6 +44,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, BuiltinInfo.InitializeTargetBuiltins(Target); if (InitializeBuiltins) this->InitializeBuiltins(idents); + PrintingPolicy.CPlusPlus = LangOpts.CPlusPlus; } ASTContext::~ASTContext() { diff --git a/lib/AST/CFG.cpp b/lib/AST/CFG.cpp index af2a8910d8..9f2f2079a0 100644 --- a/lib/AST/CFG.cpp +++ b/lib/AST/CFG.cpp @@ -1525,23 +1525,26 @@ class VISIBILITY_HIDDEN CFGBlockTerminatorPrint llvm::raw_ostream& OS; StmtPrinterHelper* Helper; + PrintingPolicy Policy; + public: - CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper) - : OS(os), Helper(helper) {} + CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper, + const PrintingPolicy &Policy = PrintingPolicy()) + : OS(os), Helper(helper), Policy(Policy) {} void VisitIfStmt(IfStmt* I) { OS << "if "; - I->getCond()->printPretty(OS,Helper); + I->getCond()->printPretty(OS,Helper,Policy); } // Default case. - void VisitStmt(Stmt* Terminator) { Terminator->printPretty(OS); } + void VisitStmt(Stmt* Terminator) { Terminator->printPretty(OS, Helper, Policy); } void VisitForStmt(ForStmt* F) { OS << "for (" ; if (F->getInit()) OS << "..."; OS << "; "; - if (Stmt* C = F->getCond()) C->printPretty(OS,Helper); + if (Stmt* C = F->getCond()) C->printPretty(OS, Helper, Policy); OS << "; "; if (F->getInc()) OS << "..."; OS << ")"; @@ -1549,33 +1552,33 @@ public: void VisitWhileStmt(WhileStmt* W) { OS << "while " ; - if (Stmt* C = W->getCond()) C->printPretty(OS,Helper); + if (Stmt* C = W->getCond()) C->printPretty(OS, Helper, Policy); } void VisitDoStmt(DoStmt* D) { OS << "do ... while "; - if (Stmt* C = D->getCond()) C->printPretty(OS,Helper); + if (Stmt* C = D->getCond()) C->printPretty(OS, Helper, Policy); } void VisitSwitchStmt(SwitchStmt* Terminator) { OS << "switch "; - Terminator->getCond()->printPretty(OS,Helper); + Terminator->getCond()->printPretty(OS, Helper, Policy); } void VisitConditionalOperator(ConditionalOperator* C) { - C->getCond()->printPretty(OS,Helper); + C->getCond()->printPretty(OS, Helper, Policy); OS << " ? ... : ..."; } void VisitChooseExpr(ChooseExpr* C) { OS << "__builtin_choose_expr( "; - C->getCond()->printPretty(OS,Helper); + C->getCond()->printPretty(OS, Helper, Policy); OS << " )"; } void VisitIndirectGotoStmt(IndirectGotoStmt* I) { OS << "goto *"; - I->getTarget()->printPretty(OS,Helper); + I->getTarget()->printPretty(OS, Helper, Policy); } void VisitBinaryOperator(BinaryOperator* B) { @@ -1584,7 +1587,7 @@ public: return; } - B->getLHS()->printPretty(OS,Helper); + B->getLHS()->printPretty(OS, Helper, Policy); switch (B->getOpcode()) { case BinaryOperator::LOr: @@ -1599,7 +1602,7 @@ public: } void VisitExpr(Expr* E) { - E->printPretty(OS,Helper); + E->printPretty(OS, Helper, Policy); } }; @@ -1629,7 +1632,7 @@ void print_stmt(llvm::raw_ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminato } } - Terminator->printPretty(OS, Helper); + Terminator->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy()); // Expressions need a newline. if (isa(Terminator)) OS << '\n'; @@ -1662,10 +1665,10 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B, OS << L->getName(); else if (CaseStmt* C = dyn_cast(Terminator)) { OS << "case "; - C->getLHS()->printPretty(OS); + C->getLHS()->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy()); if (C->getRHS()) { OS << " ... "; - C->getRHS()->printPretty(OS); + C->getRHS()->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy()); } } else if (isa(Terminator)) @@ -1703,7 +1706,7 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B, if (Helper) Helper->setBlockID(-1); - CFGBlockTerminatorPrint TPrinter(OS,Helper); + CFGBlockTerminatorPrint TPrinter(OS, Helper, /*FIXME*/PrintingPolicy()); TPrinter.Visit(const_cast(B.getTerminator())); OS << '\n'; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 063914092e..cb3ec1f487 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -18,6 +18,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/Expr.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/Basic/IdentifierTable.h" #include @@ -224,10 +225,13 @@ std::string NamedDecl::getQualifiedNameAsString() const { if (const ClassTemplateSpecializationDecl *Spec = dyn_cast(Ctx)) { const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + PrintingPolicy Policy; + Policy.CPlusPlus = true; std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size()); + TemplateArgs.flat_size(), + Policy); Names.push_back(Spec->getIdentifier()->getName() + TemplateArgsStr); } else if (const NamedDecl *ND = dyn_cast(Ctx)) Names.push_back(ND->getNameAsString()); diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp index c94a4da7b6..09522a2086 100644 --- a/lib/AST/NestedNameSpecifier.cpp +++ b/lib/AST/NestedNameSpecifier.cpp @@ -14,6 +14,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/AST/Type.h" #include "llvm/Support/raw_ostream.h" #include @@ -104,9 +105,11 @@ bool NestedNameSpecifier::isDependent() const { /// \brief Print this nested name specifier to the given output /// stream. -void NestedNameSpecifier::print(llvm::raw_ostream &OS) const { +void +NestedNameSpecifier::print(llvm::raw_ostream &OS, + const PrintingPolicy &Policy) const { if (getPrefix()) - getPrefix()->print(OS); + getPrefix()->print(OS, Policy); switch (getKind()) { case Identifier: @@ -134,10 +137,9 @@ void NestedNameSpecifier::print(llvm::raw_ostream &OS) const { if (const QualifiedNameType *QualT = dyn_cast(T)) T = QualT->getNamedType().getTypePtr(); - if (const TagType *TagT = dyn_cast(T)) - TagT->getAsStringInternal(TypeStr, true); - else - T->getAsStringInternal(TypeStr); + PrintingPolicy InnerPolicy(Policy); + InnerPolicy.SuppressTagKind = true; + T->getAsStringInternal(TypeStr, InnerPolicy); OS << TypeStr; break; } @@ -152,5 +154,7 @@ void NestedNameSpecifier::Destroy(ASTContext &Context) { } void NestedNameSpecifier::dump() { - print(llvm::errs()); + PrintingPolicy Policy; + Policy.CPlusPlus = true; + print(llvm::errs(), Policy); } diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index 821eb55c72..b24e912582 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -15,6 +15,7 @@ #include "clang/AST/StmtVisitor.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/Compiler.h" #include @@ -39,6 +40,8 @@ namespace { /// out so that we can print out deltas from then on out. const char *LastLocFilename; unsigned LastLocLine; + + PrintingPolicy Policy; public: StmtDumper(SourceManager *sm, FILE *f, unsigned maxDepth) : SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) { @@ -223,7 +226,7 @@ void StmtDumper::DumpDeclarator(Decl *D) { } std::string Name = VD->getNameAsString(); - VD->getType().getAsStringInternal(Name); + VD->getType().getAsStringInternal(Name, Policy); fprintf(F, "%s", Name.c_str()); // If this is a vardecl with an initializer, emit it. diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 80aa2d1d8f..e6a2bad7a5 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -29,14 +29,20 @@ namespace { class VISIBILITY_HIDDEN StmtPrinter : public StmtVisitor { llvm::raw_ostream &OS; unsigned IndentLevel; - bool NoIndent; clang::PrinterHelper* Helper; + PrintingPolicy Policy; + public: - StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper, unsigned I=0, - bool noIndent=false) : - OS(os), IndentLevel(I), NoIndent(noIndent), Helper(helper) {} + StmtPrinter(llvm::raw_ostream &os, PrinterHelper* helper, + const PrintingPolicy &Policy = PrintingPolicy(), + unsigned Indentation = 0) + : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy) {} - void PrintStmt(Stmt *S, int SubIndent = 1) { + void PrintStmt(Stmt *S) { + PrintStmt(S, Policy.Indentation); + } + + void PrintStmt(Stmt *S, int SubIndent) { IndentLevel += SubIndent; if (S && isa(S)) { // If this is an expr used in a stmt context, indent and newline it. @@ -66,10 +72,8 @@ namespace { } llvm::raw_ostream &Indent(int Delta = 0) { - if (!NoIndent) { - for (int i = 0, e = IndentLevel+Delta; i < e; ++i) - OS << " "; - } else NoIndent = false; + for (int i = 0, e = IndentLevel+Delta; i < e; ++i) + OS << " "; return OS; } @@ -123,7 +127,7 @@ void StmtPrinter::PrintRawDecl(Decl *D) { } std::string Name = VD->getNameAsString(); - VD->getType().getAsStringInternal(Name); + VD->getType().getAsStringInternal(Name, Policy); OS << Name; // If this is a vardecl with an initializer, emit it. @@ -531,12 +535,12 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) { void StmtPrinter::VisitQualifiedDeclRefExpr(QualifiedDeclRefExpr *Node) { NamedDecl *D = Node->getDecl(); - Node->getQualifier()->print(OS); + Node->getQualifier()->print(OS, Policy); OS << D->getNameAsString(); } void StmtPrinter::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *Node) { - Node->getQualifier()->print(OS); + Node->getQualifier()->print(OS, Policy); OS << Node->getDeclName().getAsString(); } @@ -1065,11 +1069,11 @@ void StmtPrinter::VisitCXXNewExpr(CXXNewExpr *E) { std::string TypeS; if (Expr *Size = E->getArraySize()) { llvm::raw_string_ostream s(TypeS); - Size->printPretty(s); + Size->printPretty(s, Helper, Policy); s.flush(); TypeS = "[" + TypeS + "]"; } - E->getAllocatedType().getAsStringInternal(TypeS); + E->getAllocatedType().getAsStringInternal(TypeS, Policy); OS << TypeS; if (E->isParenTypeId()) OS << ")"; @@ -1221,7 +1225,7 @@ void StmtPrinter::VisitBlockExpr(BlockExpr *Node) { E = BD->param_end(); AI != E; ++AI) { if (AI != BD->param_begin()) OS << ", "; ParamStr = (*AI)->getNameAsString(); - (*AI)->getType().getAsStringInternal(ParamStr); + (*AI)->getType().getAsStringInternal(ParamStr, Policy); OS << ParamStr; } @@ -1242,17 +1246,18 @@ void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) { //===----------------------------------------------------------------------===// void Stmt::dumpPretty() const { - printPretty(llvm::errs()); + printPretty(llvm::errs(), 0, PrintingPolicy()); } void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper, - unsigned I, bool NoIndent) const { + const PrintingPolicy &Policy, + unsigned Indentation) const { if (this == 0) { OS << ""; return; } - StmtPrinter P(OS, Helper, I, NoIndent); + StmtPrinter P(OS, Helper, Policy, Indentation); P.Visit(const_cast(this)); } diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp index c437e7b929..3613da77b3 100644 --- a/lib/AST/TemplateName.cpp +++ b/lib/AST/TemplateName.cpp @@ -14,6 +14,7 @@ #include "clang/AST/TemplateName.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/PrettyPrinter.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -38,23 +39,27 @@ bool TemplateName::isDependent() const { return true; } -void TemplateName::print(llvm::raw_ostream &OS, bool SuppressNNS) const { +void +TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy, + bool SuppressNNS) const { if (TemplateDecl *Template = Storage.dyn_cast()) OS << Template->getIdentifier()->getName(); else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { if (!SuppressNNS) - QTN->getQualifier()->print(OS); + QTN->getQualifier()->print(OS, Policy); if (QTN->hasTemplateKeyword()) OS << "template "; OS << QTN->getTemplateDecl()->getIdentifier()->getName(); } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { if (!SuppressNNS) - DTN->getQualifier()->print(OS); + DTN->getQualifier()->print(OS, Policy); OS << "template "; OS << DTN->getName()->getName(); } } void TemplateName::dump() const { - print(llvm::errs()); + PrintingPolicy Policy; + Policy.CPlusPlus = true; + print(llvm::errs(), Policy); } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index c04e8275ef..64433cd89b 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/PrettyPrinter.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -895,11 +896,11 @@ bool Type::isNullPtrType() const { return false; } -const char *BuiltinType::getName() const { +const char *BuiltinType::getName(bool CPlusPlus) const { switch (getKind()) { default: assert(0 && "Unknown builtin type!"); case Void: return "void"; - case Bool: return "_Bool"; + case Bool: return CPlusPlus? "bool" : "_Bool"; case Char_S: return "char"; case Char_U: return "char"; case SChar: return "signed char"; @@ -1099,8 +1100,9 @@ TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, //===----------------------------------------------------------------------===// void QualType::dump(const char *msg) const { + PrintingPolicy Policy; std::string R = "identifier"; - getAsStringInternal(R); + getAsStringInternal(R, Policy); if (msg) fprintf(stderr, "%s: %s\n", msg, R.c_str()); else @@ -1112,7 +1114,7 @@ void QualType::dump() const { void Type::dump() const { std::string S = "identifier"; - getAsStringInternal(S); + getAsStringInternal(S, PrintingPolicy()); fprintf(stderr, "%s\n", S.c_str()); } @@ -1129,7 +1131,15 @@ static void AppendTypeQualList(std::string &S, unsigned TypeQuals) { S += (NonePrinted+" restrict"), NonePrinted = false; } -void QualType::getAsStringInternal(std::string &S) const { +std::string QualType::getAsString() const { + std::string S; + getAsStringInternal(S, PrintingPolicy()); + return S; +} + +void +QualType::getAsStringInternal(std::string &S, + const PrintingPolicy &Policy) const { if (isNull()) { S += "NULL TYPE"; return; @@ -1145,20 +1155,21 @@ void QualType::getAsStringInternal(std::string &S) const { S = TQS; } - getTypePtr()->getAsStringInternal(S); + getTypePtr()->getAsStringInternal(S, Policy); } -void BuiltinType::getAsStringInternal(std::string &S) const { +void BuiltinType::getAsStringInternal(std::string &S, + const PrintingPolicy &Policy) const { if (S.empty()) { - S = getName(); + S = getName(Policy.CPlusPlus); } else { // Prefix the basic type, e.g. 'int X'. S = ' ' + S; - S = getName() + S; + S = getName(Policy.CPlusPlus) + S; } } -void FixedWidthIntType::getAsStringInternal(std::string &S) const { +void FixedWidthIntType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { // FIXME: Once we get bitwidth attribute, write as // "int __attribute__((bitwidth(x)))". std::string prefix = "__clang_fixedwidth"; @@ -1173,12 +1184,12 @@ void FixedWidthIntType::getAsStringInternal(std::string &S) const { } -void ComplexType::getAsStringInternal(std::string &S) const { - ElementType->getAsStringInternal(S); +void ComplexType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { + ElementType->getAsStringInternal(S, Policy); S = "_Complex " + S; } -void ExtQualType::getAsStringInternal(std::string &S) const { +void ExtQualType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { bool NeedsSpace = false; if (AddressSpace) { S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S; @@ -1194,10 +1205,10 @@ void ExtQualType::getAsStringInternal(std::string &S) const { S += "strong"; S += ")))"; } - BaseType->getAsStringInternal(S); + BaseType->getAsStringInternal(S, Policy); } -void PointerType::getAsStringInternal(std::string &S) const { +void PointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S = '*' + S; // Handle things like 'int (*A)[4];' correctly. @@ -1205,15 +1216,15 @@ void PointerType::getAsStringInternal(std::string &S) const { if (isa(getPointeeType())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S); + getPointeeType().getAsStringInternal(S, Policy); } -void BlockPointerType::getAsStringInternal(std::string &S) const { +void BlockPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S = '^' + S; - PointeeType.getAsStringInternal(S); + PointeeType.getAsStringInternal(S, Policy); } -void LValueReferenceType::getAsStringInternal(std::string &S) const { +void LValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S = '&' + S; // Handle things like 'int (&A)[4];' correctly. @@ -1221,10 +1232,10 @@ void LValueReferenceType::getAsStringInternal(std::string &S) const { if (isa(getPointeeType())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S); + getPointeeType().getAsStringInternal(S, Policy); } -void RValueReferenceType::getAsStringInternal(std::string &S) const { +void RValueReferenceType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S = "&&" + S; // Handle things like 'int (&&A)[4];' correctly. @@ -1232,12 +1243,12 @@ void RValueReferenceType::getAsStringInternal(std::string &S) const { if (isa(getPointeeType())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S); + getPointeeType().getAsStringInternal(S, Policy); } -void MemberPointerType::getAsStringInternal(std::string &S) const { +void MemberPointerType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { std::string C; - Class->getAsStringInternal(C); + Class->getAsStringInternal(C, Policy); C += "::*"; S = C + S; @@ -1246,24 +1257,24 @@ void MemberPointerType::getAsStringInternal(std::string &S) const { if (isa(getPointeeType())) S = '(' + S + ')'; - getPointeeType().getAsStringInternal(S); + getPointeeType().getAsStringInternal(S, Policy); } -void ConstantArrayType::getAsStringInternal(std::string &S) const { +void ConstantArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S += '['; S += llvm::utostr(getSize().getZExtValue()); S += ']'; - getElementType().getAsStringInternal(S); + getElementType().getAsStringInternal(S, Policy); } -void IncompleteArrayType::getAsStringInternal(std::string &S) const { +void IncompleteArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S += "[]"; - getElementType().getAsStringInternal(S); + getElementType().getAsStringInternal(S, Policy); } -void VariableArrayType::getAsStringInternal(std::string &S) const { +void VariableArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S += '['; if (getIndexTypeQualifier()) { @@ -1279,15 +1290,15 @@ void VariableArrayType::getAsStringInternal(std::string &S) const { if (getSizeExpr()) { std::string SStr; llvm::raw_string_ostream s(SStr); - getSizeExpr()->printPretty(s); + getSizeExpr()->printPretty(s, 0, Policy); S += s.str(); } S += ']'; - getElementType().getAsStringInternal(S); + getElementType().getAsStringInternal(S, Policy); } -void DependentSizedArrayType::getAsStringInternal(std::string &S) const { +void DependentSizedArrayType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S += '['; if (getIndexTypeQualifier()) { @@ -1303,57 +1314,57 @@ void DependentSizedArrayType::getAsStringInternal(std::string &S) const { if (getSizeExpr()) { std::string SStr; llvm::raw_string_ostream s(SStr); - getSizeExpr()->printPretty(s); + getSizeExpr()->printPretty(s, 0, Policy); S += s.str(); } S += ']'; - getElementType().getAsStringInternal(S); + getElementType().getAsStringInternal(S, Policy); } -void VectorType::getAsStringInternal(std::string &S) const { +void VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { // FIXME: We prefer to print the size directly here, but have no way // to get the size of the type. S += " __attribute__((__vector_size__("; S += llvm::utostr_32(NumElements); // convert back to bytes. S += " * sizeof(" + ElementType.getAsString() + "))))"; - ElementType.getAsStringInternal(S); + ElementType.getAsStringInternal(S, Policy); } -void ExtVectorType::getAsStringInternal(std::string &S) const { +void ExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { S += " __attribute__((ext_vector_type("; S += llvm::utostr_32(NumElements); S += ")))"; - ElementType.getAsStringInternal(S); + ElementType.getAsStringInternal(S, Policy); } -void TypeOfExprType::getAsStringInternal(std::string &InnerString) const { +void TypeOfExprType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(e) X'. InnerString = ' ' + InnerString; std::string Str; llvm::raw_string_ostream s(Str); - getUnderlyingExpr()->printPretty(s); + getUnderlyingExpr()->printPretty(s, 0, Policy); InnerString = "typeof " + s.str() + InnerString; } -void TypeOfType::getAsStringInternal(std::string &InnerString) const { +void TypeOfType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typeof(t) X'. InnerString = ' ' + InnerString; std::string Tmp; - getUnderlyingType().getAsStringInternal(Tmp); + getUnderlyingType().getAsStringInternal(Tmp, Policy); InnerString = "typeof(" + Tmp + ")" + InnerString; } -void FunctionNoProtoType::getAsStringInternal(std::string &S) const { +void FunctionNoProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!S.empty()) S = "(" + S + ")"; S += "()"; - getResultType().getAsStringInternal(S); + getResultType().getAsStringInternal(S, Policy); } -void FunctionProtoType::getAsStringInternal(std::string &S) const { +void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const { // If needed for precedence reasons, wrap the inner part in grouping parens. if (!S.empty()) S = "(" + S + ")"; @@ -1362,7 +1373,7 @@ void FunctionProtoType::getAsStringInternal(std::string &S) const { std::string Tmp; for (unsigned i = 0, e = getNumArgs(); i != e; ++i) { if (i) S += ", "; - getArgType(i).getAsStringInternal(Tmp); + getArgType(i).getAsStringInternal(Tmp, Policy); S += Tmp; Tmp.clear(); } @@ -1377,17 +1388,17 @@ void FunctionProtoType::getAsStringInternal(std::string &S) const { } S += ")"; - getResultType().getAsStringInternal(S); + getResultType().getAsStringInternal(S, Policy); } -void TypedefType::getAsStringInternal(std::string &InnerString) const { +void TypedefType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. InnerString = ' ' + InnerString; InnerString = getDecl()->getIdentifier()->getName() + InnerString; } -void TemplateTypeParmType::getAsStringInternal(std::string &InnerString) const { +void TemplateTypeParmType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'parmname X'. InnerString = ' ' + InnerString; @@ -1398,9 +1409,11 @@ void TemplateTypeParmType::getAsStringInternal(std::string &InnerString) const { InnerString = Name->getName() + InnerString; } -std::string TemplateSpecializationType::PrintTemplateArgumentList( - const TemplateArgument *Args, - unsigned NumArgs) { +std::string +TemplateSpecializationType::PrintTemplateArgumentList( + const TemplateArgument *Args, + unsigned NumArgs, + const PrintingPolicy &Policy) { std::string SpecString; SpecString += '<'; for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { @@ -1411,7 +1424,7 @@ std::string TemplateSpecializationType::PrintTemplateArgumentList( std::string ArgString; switch (Args[Arg].getKind()) { case TemplateArgument::Type: - Args[Arg].getAsType().getAsStringInternal(ArgString); + Args[Arg].getAsType().getAsStringInternal(ArgString, Policy); break; case TemplateArgument::Declaration: @@ -1424,7 +1437,7 @@ std::string TemplateSpecializationType::PrintTemplateArgumentList( case TemplateArgument::Expression: { llvm::raw_string_ostream s(ArgString); - Args[Arg].getAsExpr()->printPretty(s); + Args[Arg].getAsExpr()->printPretty(s, 0, Policy); break; } } @@ -1451,35 +1464,33 @@ std::string TemplateSpecializationType::PrintTemplateArgumentList( void TemplateSpecializationType:: -getAsStringInternal(std::string &InnerString) const { +getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { std::string SpecString; { llvm::raw_string_ostream OS(SpecString); - Template.print(OS); + Template.print(OS, Policy); } - SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs()); + SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs(), Policy); if (InnerString.empty()) InnerString.swap(SpecString); else InnerString = SpecString + ' ' + InnerString; } -void QualifiedNameType::getAsStringInternal(std::string &InnerString) const { +void QualifiedNameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { std::string MyString; { llvm::raw_string_ostream OS(MyString); - NNS->print(OS); + NNS->print(OS, Policy); } std::string TypeStr; - if (const TagType *TagT = dyn_cast(NamedType.getTypePtr())) { - // Suppress printing of 'enum', 'struct', 'union', or 'class'. - TagT->getAsStringInternal(TypeStr, true); - } else - NamedType.getAsStringInternal(TypeStr); + PrintingPolicy InnerPolicy(Policy); + InnerPolicy.SuppressTagKind = true; + NamedType.getAsStringInternal(TypeStr, InnerPolicy); MyString += TypeStr; if (InnerString.empty()) @@ -1488,20 +1499,22 @@ void QualifiedNameType::getAsStringInternal(std::string &InnerString) const { InnerString = MyString + ' ' + InnerString; } -void TypenameType::getAsStringInternal(std::string &InnerString) const { +void TypenameType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { std::string MyString; { llvm::raw_string_ostream OS(MyString); OS << "typename "; - NNS->print(OS); + NNS->print(OS, Policy); if (const IdentifierInfo *Ident = getIdentifier()) OS << Ident->getName(); else if (const TemplateSpecializationType *Spec = getTemplateId()) { - Spec->getTemplateName().print(OS, true); + Spec->getTemplateName().print(OS, Policy, true); OS << TemplateSpecializationType::PrintTemplateArgumentList( - Spec->getArgs(), Spec->getNumArgs()); + Spec->getArgs(), + Spec->getNumArgs(), + Policy); } } @@ -1511,14 +1524,15 @@ void TypenameType::getAsStringInternal(std::string &InnerString) const { InnerString = MyString + ' ' + InnerString; } -void ObjCInterfaceType::getAsStringInternal(std::string &InnerString) const { +void ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. InnerString = ' ' + InnerString; InnerString = getDecl()->getIdentifier()->getName() + InnerString; } -void ObjCQualifiedInterfaceType::getAsStringInternal( - std::string &InnerString) const { +void +ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString, + const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. InnerString = ' ' + InnerString; std::string ObjCQIString = getDecl()->getNameAsString(); @@ -1535,7 +1549,7 @@ void ObjCQualifiedInterfaceType::getAsStringInternal( InnerString = ObjCQIString + InnerString; } -void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString) const { +void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. InnerString = ' ' + InnerString; std::string ObjCQIString = "id"; @@ -1549,16 +1563,11 @@ void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString) const { InnerString = ObjCQIString + InnerString; } -void TagType::getAsStringInternal(std::string &InnerString) const { - getAsStringInternal(InnerString, false); -} - -void TagType::getAsStringInternal(std::string &InnerString, - bool SuppressTagKind) const { +void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'. InnerString = ' ' + InnerString; - const char *Kind = SuppressTagKind? 0 : getDecl()->getKindName(); + const char *Kind = Policy.SuppressTagKind? 0 : getDecl()->getKindName(); const char *ID; if (const IdentifierInfo *II = getDecl()->getIdentifier()) ID = II->getName(); @@ -1577,7 +1586,8 @@ void TagType::getAsStringInternal(std::string &InnerString, std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size()); + TemplateArgs.flat_size(), + Policy); InnerString = TemplateArgsStr + InnerString; } @@ -1597,7 +1607,8 @@ void TagType::getAsStringInternal(std::string &InnerString, std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( TemplateArgs.getFlatArgumentList(), - TemplateArgs.flat_size()); + TemplateArgs.flat_size(), + Policy); MyPart = Spec->getIdentifier()->getName() + TemplateArgsStr; } else if (TagDecl *Tag = dyn_cast(DC)) { if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 0c6ed4b889..049e716c7c 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -150,7 +150,9 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT, uint64_t Align = M->getContext().getTypeAlign(BT); uint64_t Offset = 0; - return DebugFactory.CreateBasicType(Unit, BT->getName(), Unit, 0, Size, Align, + return DebugFactory.CreateBasicType(Unit, + BT->getName(M->getContext().getLangOptions().CPlusPlus), + Unit, 0, Size, Align, Offset, /*flags*/ 0, Encoding); } diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp index ba482b049a..c35f4c9e20 100644 --- a/lib/Frontend/ASTConsumers.cpp +++ b/lib/Frontend/ASTConsumers.cpp @@ -20,6 +20,7 @@ #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/CodeGen/ModuleBuilder.h" #include "llvm/Module.h" #include "llvm/Support/Streams.h" @@ -35,10 +36,13 @@ namespace { class DeclPrinter { public: llvm::raw_ostream& Out; + PrintingPolicy Policy; unsigned Indentation; - DeclPrinter(llvm::raw_ostream* out) : Out(out ? *out : llvm::errs()), - Indentation(0) {} + DeclPrinter(llvm::raw_ostream* out, + const PrintingPolicy &Policy = PrintingPolicy()) + : Out(out ? *out : llvm::errs()), Policy(Policy), + Indentation(0) {} DeclPrinter() : Out(llvm::errs()), Indentation(0) {} virtual ~DeclPrinter(); @@ -84,7 +88,7 @@ void DeclPrinter:: PrintDecl(Decl *D) { // FIXME: Pass a context here so we can use getBody() if (FD->getBodyIfAvailable()) { Out << ' '; - FD->getBodyIfAvailable()->printPretty(Out, 0, Indentation, true); + FD->getBodyIfAvailable()->printPretty(Out, 0, Policy); Out << '\n'; } } else if (isa(D)) { @@ -162,7 +166,7 @@ void DeclPrinter:: PrintDecl(Decl *D) { PrintLinkageSpec(LSD); } else if (FileScopeAsmDecl *AD = dyn_cast(D)) { Out << "asm("; - AD->getAsmString()->printPretty(Out); + AD->getAsmString()->printPretty(Out, 0, Policy); Out << ")\n"; } else if (NamedDecl *ND = dyn_cast(D)) { Print(ND); @@ -193,12 +197,12 @@ void DeclPrinter::Print(NamedDecl *ND) { } std::string Name = ND->getNameAsString(); // This forms: "int a". - dyn_cast(ND)->getType().getAsStringInternal(Name); + dyn_cast(ND)->getType().getAsStringInternal(Name, Policy); Out << Name; if (VarDecl *Var = dyn_cast(ND)) { if (Var->getInit()) { Out << " = "; - Var->getInit()->printPretty(Out); + Var->getInit()->printPretty(Out, 0, Policy); } } Out << ";\n"; @@ -252,7 +256,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) { std::string ParamStr; if (HasBody) ParamStr = FD->getParamDecl(i)->getNameAsString(); - FT->getArgType(i).getAsStringInternal(ParamStr); + FT->getArgType(i).getAsStringInternal(ParamStr, Policy); Proto += ParamStr; } @@ -266,7 +270,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) { Proto += "()"; } - AFT->getResultType().getAsStringInternal(Proto); + AFT->getResultType().getAsStringInternal(Proto, Policy); Out << Proto; if (!FD->getBodyIfAvailable()) @@ -276,7 +280,7 @@ void DeclPrinter::PrintFunctionDeclStart(FunctionDecl *FD) { void DeclPrinter::PrintTypeDefDecl(TypedefDecl *TD) { std::string S = TD->getNameAsString(); - TD->getUnderlyingType().getAsStringInternal(S); + TD->getUnderlyingType().getAsStringInternal(S, Policy); Out << "typedef " << S << ";\n"; } @@ -358,7 +362,7 @@ void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) { PrintObjCMethodDecl(OMD); if (OMD->getBody()) { Out << ' '; - OMD->getBody()->printPretty(Out); + OMD->getBody()->printPretty(Out, 0, Policy); Out << '\n'; } } @@ -371,7 +375,7 @@ void DeclPrinter::PrintObjCImplementationDecl(ObjCImplementationDecl *OID) { PrintObjCMethodDecl(OMD); if (OMD->getBody()) { Out << ' '; - OMD->getBody()->printPretty(Out); + OMD->getBody()->printPretty(Out, 0, Policy); Out << '\n'; } } diff --git a/lib/Frontend/DocumentXML.cpp b/lib/Frontend/DocumentXML.cpp index 80060f5b73..ac1d7d2a8b 100644 --- a/lib/Frontend/DocumentXML.cpp +++ b/lib/Frontend/DocumentXML.cpp @@ -194,7 +194,7 @@ void DocumentXML::finalize() // don't use the get methods as they strip of typedef infos if (const BuiltinType *BT = dyn_cast(i->first)) { addSubNode("FundamentalType"); - addAttribute("name", BT->getName()); + addAttribute("name", BT->getName(Ctx->getLangOptions().CPlusPlus)); } else if (const PointerType *PT = dyn_cast(i->first)) { addSubNode("PointerType"); diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp index 29f0578882..6d0f10def2 100644 --- a/lib/Frontend/RewriteBlocks.cpp +++ b/lib/Frontend/RewriteBlocks.cpp @@ -396,7 +396,7 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i, E = BD->param_end(); AI != E; ++AI) { if (AI != BD->param_begin()) S += ", "; ParamStr = (*AI)->getNameAsString(); - (*AI)->getType().getAsStringInternal(ParamStr); + (*AI)->getType().getAsStringInternal(ParamStr, Context->PrintingPolicy); S += ParamStr; } if (FT->isVariadic()) { @@ -413,7 +413,8 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i, E = BlockByRefDecls.end(); I != E; ++I) { S += " "; std::string Name = (*I)->getNameAsString(); - Context->getPointerType((*I)->getType()).getAsStringInternal(Name); + Context->getPointerType((*I)->getType()).getAsStringInternal(Name, + Context->PrintingPolicy); S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; } // Next, emit a declaration for all "by copy" declarations. @@ -434,7 +435,7 @@ std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i, if (isBlockPointerType((*I)->getType())) S += "struct __block_impl *"; else - (*I)->getType().getAsStringInternal(Name); + (*I)->getType().getAsStringInternal(Name, Context->PrintingPolicy); S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; } std::string RewrittenStr = RewrittenBlockExprs[CE]; @@ -515,8 +516,8 @@ std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, S += "struct __block_impl *"; Constructor += ", void *" + ArgName; } else { - (*I)->getType().getAsStringInternal(FieldName); - (*I)->getType().getAsStringInternal(ArgName); + (*I)->getType().getAsStringInternal(FieldName, Context->PrintingPolicy); + (*I)->getType().getAsStringInternal(ArgName, Context->PrintingPolicy); Constructor += ", " + ArgName; } S += FieldName + ";\n"; @@ -541,8 +542,10 @@ std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, S += "struct __block_impl *"; Constructor += ", void *" + ArgName; } else { - Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName); - Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName); + Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName, + Context->PrintingPolicy); + Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName, + Context->PrintingPolicy); Constructor += ", " + ArgName; } S += FieldName + "; // by ref\n"; @@ -947,7 +950,8 @@ std::string RewriteBlocks::SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD) std::string FunkTypeStr; // Get a pointer to the function type so we can cast appropriately. - Context->getPointerType(QualType(Exp->getFunctionType(),0)).getAsStringInternal(FunkTypeStr); + Context->getPointerType(QualType(Exp->getFunctionType(),0)) + .getAsStringInternal(FunkTypeStr, Context->PrintingPolicy); // Rewrite the closure block with a compound literal. The first cast is // to prevent warnings from the C compiler. diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 79ae08cee5..55f0b405a9 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -944,9 +944,10 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD, if (isTopLevelBlockPointerType(PDecl->getType())) { // Make sure we convert "t (^)(...)" to "t (*)(...)". const BlockPointerType *BPT = PDecl->getType()->getAsBlockPointerType(); - Context->getPointerType(BPT->getPointeeType()).getAsStringInternal(Name); + Context->getPointerType(BPT->getPointeeType()).getAsStringInternal(Name, + Context->PrintingPolicy); } else - PDecl->getType().getAsStringInternal(Name); + PDecl->getType().getAsStringInternal(Name, Context->PrintingPolicy); ResultStr += Name; } } @@ -3600,7 +3601,7 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, E = BD->param_end(); AI != E; ++AI) { if (AI != BD->param_begin()) S += ", "; ParamStr = (*AI)->getNameAsString(); - (*AI)->getType().getAsStringInternal(ParamStr); + (*AI)->getType().getAsStringInternal(ParamStr, Context->PrintingPolicy); S += ParamStr; } if (FT->isVariadic()) { @@ -3617,7 +3618,8 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, E = BlockByRefDecls.end(); I != E; ++I) { S += " "; std::string Name = (*I)->getNameAsString(); - Context->getPointerType((*I)->getType()).getAsStringInternal(Name); + Context->getPointerType((*I)->getType()).getAsStringInternal(Name, + Context->PrintingPolicy); S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n"; } // Next, emit a declaration for all "by copy" declarations. @@ -3638,7 +3640,7 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, if (isTopLevelBlockPointerType((*I)->getType())) S += "struct __block_impl *"; else - (*I)->getType().getAsStringInternal(Name); + (*I)->getType().getAsStringInternal(Name, Context->PrintingPolicy); S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n"; } std::string RewrittenStr = RewrittenBlockExprs[CE]; @@ -3719,8 +3721,8 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, S += "struct __block_impl *"; Constructor += ", void *" + ArgName; } else { - (*I)->getType().getAsStringInternal(FieldName); - (*I)->getType().getAsStringInternal(ArgName); + (*I)->getType().getAsStringInternal(FieldName, Context->PrintingPolicy); + (*I)->getType().getAsStringInternal(ArgName, Context->PrintingPolicy); Constructor += ", " + ArgName; } S += FieldName + ";\n"; @@ -3745,8 +3747,10 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, S += "struct __block_impl *"; Constructor += ", void *" + ArgName; } else { - Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName); - Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName); + Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName, + Context->PrintingPolicy); + Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName, + Context->PrintingPolicy); Constructor += ", " + ArgName; } S += FieldName + "; // by ref\n"; diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 411d5a1677..1212d070f6 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -38,7 +38,7 @@ static void ConvertArgToStringFn(Diagnostic::ArgumentKind Kind, intptr_t Val, QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast(Val))); // FIXME: Playing with std::string is really slow. - S = Ty.getAsString(); + S = Ty.getAsString(Context.PrintingPolicy); // If this is a sugared type (like a typedef, typeof, etc), then unwrap one // level of the sugar so that the type is more obvious to the user. diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 42f36d1e03..3cac739818 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -149,7 +149,8 @@ void Sema::PrintInstantiationStack() { std::string TemplateArgsStr = TemplateSpecializationType::PrintTemplateArgumentList( Active->TemplateArgs, - Active->NumTemplateArgs); + Active->NumTemplateArgs, + Context.PrintingPolicy); Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr), diag::note_default_arg_instantiation_here) << (Template->getNameAsString() + TemplateArgsStr) diff --git a/test/SemaCXX/bool.cpp b/test/SemaCXX/bool.cpp index c5ad30e471..bc44c73d8c 100644 --- a/test/SemaCXX/bool.cpp +++ b/test/SemaCXX/bool.cpp @@ -13,4 +13,6 @@ void test(bool b) b++; // expected-warning {{incrementing expression of type bool is deprecated}} --b; // expected-error {{cannot decrement expression of type bool}} b--; // expected-error {{cannot decrement expression of type bool}} + + bool *b1 = (int *)0; // expected-error{{expected 'bool *'}} } diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp index 638afd0555..937b2729d1 100644 --- a/test/SemaCXX/convert-to-bool.cpp +++ b/test/SemaCXX/convert-to-bool.cpp @@ -44,7 +44,7 @@ struct ExplicitConvToRef { void test_explicit_bool(ExplicitConvToBool ecb) { bool b1(ecb); // okay - bool b2 = ecb; // expected-error{{incompatible type initializing 'struct ExplicitConvToBool', expected '_Bool'}} + bool b2 = ecb; // expected-error{{incompatible type initializing 'struct ExplicitConvToBool', expected 'bool'}} accepts_bool(ecb); // expected-error{{no matching function for call to}} } diff --git a/test/SemaCXX/overloaded-operator.cpp b/test/SemaCXX/overloaded-operator.cpp index 2bf8a35d8b..916d753a3f 100644 --- a/test/SemaCXX/overloaded-operator.cpp +++ b/test/SemaCXX/overloaded-operator.cpp @@ -67,7 +67,7 @@ void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2) { float &f1 = (e1 == e2); float &f2 = (enum1 == e2); float &f3 = (e1 == enum2); - float &f4 = (enum1 == enum2); // expected-error{{non-const lvalue reference to type 'float' cannot be initialized with a temporary of type '_Bool'}} + float &f4 = (enum1 == enum2); // expected-error{{non-const lvalue reference to type 'float' cannot be initialized with a temporary of type 'bool'}} } diff --git a/test/SemaTemplate/typename-specifier-2.cpp b/test/SemaTemplate/typename-specifier-2.cpp index 3aebb9a524..99e6285231 100644 --- a/test/SemaTemplate/typename-specifier-2.cpp +++ b/test/SemaTemplate/typename-specifier-2.cpp @@ -18,7 +18,7 @@ int i; // 'aka' telling us that we're dealing with an int**. Should we fix // getDesugaredType to dig through pointers and such? bind_metafun::type::type ip = &i; -bind_metafun::type::type fp = &i; // expected-error{{incompatible type initializing 'int *', expected 'bind_metafun::type::type' (aka 'float *')}} +bind_metafun::type::type fp = &i; // expected-error{{incompatible type initializing 'int *', expected 'bind_metafun::type::type' (aka 'float *')}} template -- 2.40.0