PrettyPrinting statements with type signed/unsigned char

Hello,

When I'm trying to pretty print statement with type signed or unsigned char I'm getting an error from the StmtPrinter - "Unexpected type for integer literal!". Is this a bug? If yes, then following small patch fixes it. At least in my case it works just fine and statements are printed correctly.

Cheers,
Andrey Tarasevich

--- StmtPrinter.cpp 2013-06-07 15:17:31.000000000 +0200
+++ StmtPrinter.cpp 2013-06-07 15:24:43.000000000 +0200
@@ -731,6 +731,8 @@
   // FIXME: The Short and UShort cases are to handle cases where a short
   // integeral literal is formed during template instantiation. They should
   // be removed when template instantiation no longer needs integer literals.
+ case BuiltinType::UChar:
+ case BuiltinType::SChar:
   case BuiltinType::Short:
   case BuiltinType::UShort:
   case BuiltinType::Int: break; // no suffix.

Hello,

When I'm trying to pretty print statement with type signed or unsigned char I'm getting an error from the StmtPrinter - "Unexpected type for integer literal!". Is this a bug? If yes, then following small patch fixes it. At least in my case it works just fine and statements are printed correctly.

Please provide a test case. This should only be reachable if you try
to print a *literal* with type SChar or UChar. How are you building
such a literal?

Hi,

It is indeed only reachable if I try to print a literal. The following code within a ASTConsumer class triggers the error

bool TestAstConsumer::HandleTopLevelDecl(clang::DeclGroupRef D)
{

clang::QualType type = _context->UnsignedCharTy;
clang::VarDecl* vd = clang::VarDecl::Create(_context,
_context->getTranslationUnitDecl(),
clang::SourceLocation(),
clang::SourceLocation(),
&_context->Idents.get(“var”),
type,
0,
clang::SC_None);
llvm::APInt
val = new llvm::APInt(_context->getIntWidth(type), 10);
clang::Expr* init = clang::IntegerLiteral::Create(*_context,
*val,
type,
clang::SourceLocation());
vd->setInit(init);
clang::DeclGroupRef *dgr = new (_context) clang::DeclGroupRef(vd);
clang::DeclStmt *dst = new (_context) clang::DeclStmt(*dgr, clang::SourceLocation(), clang::SourceLocation());
dst->printPretty(llvm::outs(), 0, _context->getPrintingPolicy());

}

and this is the error message I get

unsigned char var = 10Unexpected type for integer literal!
UNREACHABLE executed at <path_to_llvm_source>/llvm/tools/clang/lib/AST/StmtPrinter.cpp:730!

Cheers,
Andrey Tarasevich

Hi,

It is indeed only reachable if I try to print a literal. The following code
within a ASTConsumer class triggers the error

bool TestAstConsumer::HandleTopLevelDecl(clang::DeclGroupRef D)
{
clang::QualType type = _context->UnsignedCharTy;
clang::VarDecl* vd = clang::VarDecl::Create(*_context,

_context->getTranslationUnitDecl(),
                                              clang::SourceLocation(),
                                              clang::SourceLocation(),
                                              &_context->Idents.get("var"),
                                              type,
                                              0,
                                              clang::SC_None);
llvm::APInt* val = new llvm::APInt(_context->getIntWidth(type), 10);
clang::Expr* init = clang::IntegerLiteral::Create(*_context,
                                                  *val,
                                                  type,
                                                  clang::SourceLocation());
vd->setInit(init);
clang::DeclGroupRef *dgr = new (_context) clang::DeclGroupRef(vd);
clang::DeclStmt *dst = new (_context) clang::DeclStmt(*dgr,
clang::SourceLocation(), clang::SourceLocation());
dst->printPretty(llvm::outs(), 0, _context->getPrintingPolicy());
}

and this is the error message I get

unsigned char var = 10Unexpected type for integer literal!
UNREACHABLE executed at
<path_to_llvm_source>/llvm/tools/clang/lib/AST/StmtPrinter.cpp:730!

You have built a malformed AST; there are no IntegerLiterals of
character types. Maybe build a CharacterLiteral instead?

Hi,

It is indeed only reachable if I try to print a literal. The following code
within a ASTConsumer class triggers the error

bool TestAstConsumer::HandleTopLevelDecl(clang::DeclGroupRef D)
{
clang::QualType type = _context->UnsignedCharTy;
clang::VarDecl* vd = clang::VarDecl::Create(*_context,

_context->getTranslationUnitDecl(),
clang::SourceLocation(),
clang::SourceLocation(),
&_context->Idents.get(“var”),
type,
0,
clang::SC_None);
llvm::APInt* val = new llvm::APInt(_context->getIntWidth(type), 10);
clang::Expr* init = clang::IntegerLiteral::Create(*_context,
*val,
type,
clang::SourceLocation());
vd->setInit(init);
clang::DeclGroupRef *dgr = new (_context) clang::DeclGroupRef(vd);
clang::DeclStmt *dst = new (_context) clang::DeclStmt(*dgr,
clang::SourceLocation(), clang::SourceLocation());
dst->printPretty(llvm::outs(), 0, _context->getPrintingPolicy());
}

and this is the error message I get

unsigned char var = 10Unexpected type for integer literal!
UNREACHABLE executed at
<path_to_llvm_source>/llvm/tools/clang/lib/AST/StmtPrinter.cpp:730!

You have built a malformed AST; there are no IntegerLiterals of
character types. Maybe build a CharacterLiteral instead

Sorry. I found the problem in my code.
I tried to printPretty following code and it worked fine.

int main()
{
unsigned char a = 10;
}

Eventually clang treats the ‘10’ literal as a IntegerLiteral and not as a CharacterLiteral and prints it as BuiltinType::Int.
It means, that I’m using the IntegerLiteral as a correct class in this case, but the type of the IntegerLiteral is wrong. In my example I should use _context->IntTy and not _context->
UnsignedCharTy when I create the IntegerLiteral itself. Then everything works.