From 969c4ad65dd0c23b68117a08eb28f040af379b0d Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Sun, 25 Aug 2002 20:00:08 +0000 Subject: [PATCH] Fix the way parens are printed around "*ptrName" so that no parens are printed around *, **, ... alone, except if it is a pointer type for which no name should be printed, as in the result of a cast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3506 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CBackend/CBackend.cpp | 25 +++++++++++++++++++------ lib/Target/CBackend/Writer.cpp | 25 +++++++++++++++++++------ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index f4fb7a24585..e52c15b0f17 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -42,7 +42,7 @@ namespace { inline void write(Module *M) { printModule(M); } ostream &printType(const Type *Ty, const string &VariableName = "", - bool IgnoreName = false); + bool IgnoreName = false, bool namedContext = true); void writeOperand(Value *Operand); void writeOperandInternal(Value *Operand); @@ -142,11 +142,16 @@ string CWriter::getValueName(const Value *V) { return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID()); } +// A pointer type should not use parens around *'s alone, e.g., (**) +inline bool ptrTypeNameNeedsParens(const string &NameSoFar) { + return (NameSoFar.find_last_not_of('*') != std::string::npos); +} + // Pass the Type* and the variable name and this prints out the variable // declaration. // ostream &CWriter::printType(const Type *Ty, const string &NameSoFar, - bool IgnoreName) { + bool IgnoreName, bool namedContext) { if (Ty->isPrimitiveType()) switch (Ty->getPrimitiveID()) { case Type::VoidTyID: return Out << "void " << NameSoFar; @@ -210,7 +215,14 @@ ostream &CWriter::printType(const Type *Ty, const string &NameSoFar, case Type::PointerTyID: { const PointerType *PTy = cast(Ty); - std::string ptrName = NameSoFar.length()? "(*"+NameSoFar+")" : string("*"); + std::string ptrName = "*" + NameSoFar; + + // Do not need parens around "* NameSoFar" if NameSoFar consists only + // of zero or more '*' chars *and* this is not an unnamed pointer type + // such as the result type in a cast statement. Otherwise, enclose in ( ). + if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext) + ptrName = "(" + ptrName + ")"; // + return printType(PTy->getElementType(), ptrName); } @@ -439,9 +451,10 @@ void CWriter::printModule(Module *M) { << "#include \n" << "#include \n\n" - // Provide a definition for null if one does not already exist. + // Provide a definition for null if one does not already exist, + // and for `bool' if not compiling with a C++ compiler. << "#ifndef NULL\n#define NULL 0\n#endif\n\n" - << "typedef unsigned char bool;\n" + << "#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n" << "\n\n/* Global Declarations */\n"; @@ -755,7 +768,7 @@ void CWriter::visitBinaryOperator(Instruction &I) { void CWriter::visitCastInst(CastInst &I) { Out << "("; - printType(I.getType()); + printType(I.getType(), string(""),/*ignoreName*/false, /*namedContext*/false); Out << ")"; writeOperand(I.getOperand(0)); } diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp index f4fb7a24585..e52c15b0f17 100644 --- a/lib/Target/CBackend/Writer.cpp +++ b/lib/Target/CBackend/Writer.cpp @@ -42,7 +42,7 @@ namespace { inline void write(Module *M) { printModule(M); } ostream &printType(const Type *Ty, const string &VariableName = "", - bool IgnoreName = false); + bool IgnoreName = false, bool namedContext = true); void writeOperand(Value *Operand); void writeOperandInternal(Value *Operand); @@ -142,11 +142,16 @@ string CWriter::getValueName(const Value *V) { return "ltmp_" + itostr(Slot) + "_" + utostr(V->getType()->getUniqueID()); } +// A pointer type should not use parens around *'s alone, e.g., (**) +inline bool ptrTypeNameNeedsParens(const string &NameSoFar) { + return (NameSoFar.find_last_not_of('*') != std::string::npos); +} + // Pass the Type* and the variable name and this prints out the variable // declaration. // ostream &CWriter::printType(const Type *Ty, const string &NameSoFar, - bool IgnoreName) { + bool IgnoreName, bool namedContext) { if (Ty->isPrimitiveType()) switch (Ty->getPrimitiveID()) { case Type::VoidTyID: return Out << "void " << NameSoFar; @@ -210,7 +215,14 @@ ostream &CWriter::printType(const Type *Ty, const string &NameSoFar, case Type::PointerTyID: { const PointerType *PTy = cast(Ty); - std::string ptrName = NameSoFar.length()? "(*"+NameSoFar+")" : string("*"); + std::string ptrName = "*" + NameSoFar; + + // Do not need parens around "* NameSoFar" if NameSoFar consists only + // of zero or more '*' chars *and* this is not an unnamed pointer type + // such as the result type in a cast statement. Otherwise, enclose in ( ). + if (ptrTypeNameNeedsParens(NameSoFar) || !namedContext) + ptrName = "(" + ptrName + ")"; // + return printType(PTy->getElementType(), ptrName); } @@ -439,9 +451,10 @@ void CWriter::printModule(Module *M) { << "#include \n" << "#include \n\n" - // Provide a definition for null if one does not already exist. + // Provide a definition for null if one does not already exist, + // and for `bool' if not compiling with a C++ compiler. << "#ifndef NULL\n#define NULL 0\n#endif\n\n" - << "typedef unsigned char bool;\n" + << "#ifndef __cplusplus\ntypedef unsigned char bool;\n#endif\n" << "\n\n/* Global Declarations */\n"; @@ -755,7 +768,7 @@ void CWriter::visitBinaryOperator(Instruction &I) { void CWriter::visitCastInst(CastInst &I) { Out << "("; - printType(I.getType()); + printType(I.getType(), string(""),/*ignoreName*/false, /*namedContext*/false); Out << ")"; writeOperand(I.getOperand(0)); }