Why is "..." printed 'After' the arg name in TypePrinter?

Hi

I was experimenting with printing out variadic templates with clang.

I had a slight issue with how TypePrinter works for function arguments in variadic function templates.

If I have this in my original source file:
template <typename T, typename …U>
void foo(T t,U… args)
{

}

TypePrinter currently generates this:
U args…

which should have been

U… args

as far as I know.

Is there some policy I can set to change this behaviour?

I had to slightly modify the the implementation to get what I expected.

There are two functions in TypePrinter.cpp as follows:

void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,
raw_ostream &OS) {
printBefore(T->getPattern(), OS);
OS << “…”;
}
void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,
raw_ostream &OS) {

printAfter(T->getPattern(), OS);

}

The line:

OS << “…”;

was previously in printPackExpansionAfter.

Why ?

Any side effects of moving it to the before function, as I did ?

Manasij Mukherjee

Yes. That'll break pretty-printing of template type argument packs:

template<typename ...T> void f() {
  std::tuple<T[3] ...> t;
}

... would get pretty-printed as

  std::tuple<T ...[3]> t;

... which is wrong.

Fixed in r213718.

Hi,
   Thanks for fixing this issue:
   There seem to be another issue with recent clang when printing:
   cat T.h
   typedef struct { } __pthread_unwind_buf_t __attribute__ ((__aligned__));

   clang -cc1 -x c++ -fsyntax-only T.h -ast-print
struct {
} typedef __pthread_unwind_buf_t __attribute__((aligned(clang: /home/vvassilev/workspace/llvm-github/obj/tools/clang/lib/AST/../../include/clang/AST/AttrImpl.inc:294: virtual void clang::AlignedAttr::printPretty(llvm::raw_ostream &, const clang::PrintingPolicy &) const: Assertion `isalignmentExpr && alignmentExpr != nullptr' failed.

Vassil

This is a problem with the way we tablegen attribute helper methods.
I'll look into it, thank you for bringing it to my attention!

~Aaron

This should be resolved in r214513.

~Aaron

Hi,
   Thanks for fixing this issue:
   There seem to be another issue with recent clang when printing:
   cat T.h
   typedef struct { } __pthread_unwind_buf_t __attribute__ ((__aligned__));

   clang -cc1 -x c++ -fsyntax-only T.h -ast-print
struct {
} typedef __pthread_unwind_buf_t __attribute__((aligned(clang:
/home/vvassilev/workspace/llvm-github/obj/tools/clang/lib/AST/../../include/clang/AST/AttrImpl.inc:294:
virtual void clang::AlignedAttr::printPretty(llvm::raw_ostream &, const
clang::PrintingPolicy &) const: Assertion `isalignmentExpr && alignmentExpr
!= nullptr' failed.

This is a problem with the way we tablegen attribute helper methods.
I'll look into it, thank you for bringing it to my attention!

This should be resolved in r214513.

That was quick :slight_smile:
Thanks a lot!
Vassil

Hi,
   Thanks for fixing this issue:
   There seem to be another issue with recent clang when printing:
   cat T.h
   typedef struct { } __pthread_unwind_buf_t __attribute__ ((__aligned__));

   clang -cc1 -x c++ -fsyntax-only T.h -ast-print
struct {
} typedef __pthread_unwind_buf_t __attribute__((aligned(clang:
/home/vvassilev/workspace/llvm-github/obj/tools/clang/lib/AST/../../include/clang/AST/AttrImpl.inc:294:

virtual void clang::AlignedAttr::printPretty(llvm::raw_ostream &, const
clang::PrintingPolicy &) const: Assertion `isalignmentExpr && alignmentExpr
!= nullptr' failed.

This is a problem with the way we tablegen attribute helper methods.
I'll look into it, thank you for bringing it to my attention!

This should be resolved in r214513.

That was quick :slight_smile:
Thanks a lot!

Another interesting issue with AnnotateAttr is that setAnnotation uses:
...
this->annotation = new (C, 1) char [annotationLength];
...

But operator new[]( (unsigned long, clang::ASTContext const&, unsigned long) is not defined and I get a linker error. For clang it works because nobody calls setAnnotation.

I can provide more accurate information if needed.

Vassil

On what platform are you seeing this link failure? I am unable to
reproduce with MSVC when I force a usage of setAnnotation, but that
holds with my belief that the code is fine. See ASTContext.h:2401 for
the definition of operator new[](size_t, ASTContext&, size_t);

~Aaron

Hi,
    Thanks for fixing this issue:
    There seem to be another issue with recent clang when printing:
    cat T.h
    typedef struct { } __pthread_unwind_buf_t __attribute__
((__aligned__));

    clang -cc1 -x c++ -fsyntax-only T.h -ast-print
struct {
} typedef __pthread_unwind_buf_t __attribute__((aligned(clang:

/home/vvassilev/workspace/llvm-github/obj/tools/clang/lib/AST/../../include/clang/AST/AttrImpl.inc:294:
virtual void clang::AlignedAttr::printPretty(llvm::raw_ostream &, const
clang::PrintingPolicy &) const: Assertion `isalignmentExpr &&
alignmentExpr
!= nullptr' failed.

This is a problem with the way we tablegen attribute helper methods.
I'll look into it, thank you for bringing it to my attention!

This should be resolved in r214513.

That was quick :slight_smile:
Thanks a lot!

Another interesting issue with AnnotateAttr is that setAnnotation uses:
...
this->annotation = new (C, 1) char [annotationLength];
...

But operator new[]( (unsigned long, clang::ASTContext const&, unsigned long)
is not defined and I get a linker error. For clang it works because nobody
calls setAnnotation.

I can provide more accurate information if needed.

On what platform are you seeing this link failure? I am unable to
reproduce with MSVC when I force a usage of setAnnotation, but that
holds with my belief that the code is fine. See ASTContext.h:2401 for
the definition of operator new[](size_t, ASTContext&, size_t);

Thanks for the pointer, I somehow missed the definition. It turned out a setup issue on our side. Sorry for the noise.
Vassil

Hi,
   Thanks for fixing this issue:
   There seem to be another issue with recent clang when printing:
   cat T.h
   typedef struct { } __pthread_unwind_buf_t __attribute__ ((__aligned__));

   clang -cc1 -x c++ -fsyntax-only T.h -ast-print
struct {
} typedef __pthread_unwind_buf_t __attribute__((aligned(clang:
/home/vvassilev/workspace/llvm-github/obj/tools/clang/lib/AST/../../include/clang/AST/AttrImpl.inc:294:
virtual void clang::AlignedAttr::printPretty(llvm::raw_ostream &, const
clang::PrintingPolicy &) const: Assertion `isalignmentExpr && alignmentExpr
!= nullptr' failed.

This is a problem with the way we tablegen attribute helper methods.
I'll look into it, thank you for bringing it to my attention!

This should be resolved in r214513.

(Sorry for reusing the thread)
template<typename, unsigned = 0>
struct __attribute__((type_visibility("default"))) extent;

gets printed as:

template<typename, unsigned = 0>
struct __attribute__((type_visibility(0))) extent;

(and it doesn't compiler because a string is expected) Is that by design or a bug?
Vassil

That seems like a bug to me. Enumerations print their integral value,
not their enumerator identifier, which is what causes the issue. It
shouldn't be too hard to fix, I'll look into it today.

Thanks!

~Aaron

Hi,
    Thanks for fixing this issue:
    There seem to be another issue with recent clang when printing:
    cat T.h
    typedef struct { } __pthread_unwind_buf_t __attribute__
((__aligned__));

    clang -cc1 -x c++ -fsyntax-only T.h -ast-print
struct {
} typedef __pthread_unwind_buf_t __attribute__((aligned(clang:

/home/vvassilev/workspace/llvm-github/obj/tools/clang/lib/AST/../../include/clang/AST/AttrImpl.inc:294:
virtual void clang::AlignedAttr::printPretty(llvm::raw_ostream &, const
clang::PrintingPolicy &) const: Assertion `isalignmentExpr &&
alignmentExpr
!= nullptr' failed.

This is a problem with the way we tablegen attribute helper methods.
I'll look into it, thank you for bringing it to my attention!

This should be resolved in r214513.

(Sorry for reusing the thread)
template<typename, unsigned = 0>
struct __attribute__((type_visibility("default"))) extent;

gets printed as:

template<typename, unsigned = 0>
struct __attribute__((type_visibility(0))) extent;

(and it doesn't compiler because a string is expected) Is that by design or
a bug?

That seems like a bug to me. Enumerations print their integral value,
not their enumerator identifier, which is what causes the issue. It
shouldn't be too hard to fix, I'll look into it today.

Thanks! It seems that printPretty would need to reuse (somehow?) the implementation of ASTDumper::dumpAttr... I am not sure if this can be done without a lot of changes to table gen...

Vassil

I have a clang tool that spits a c++ file of functions that return the string name of an enum value, if this might be of aid (the code isn't pretty, but it works for my limited use case).

of On 15/09/14 14:11, Vassil Vassilev wrote:

I've fixed this in r217771 -- however, pretty printing of attributes
in general still needs a lot of work. For instance, attributes on tag
declarations are never printed via -ast-print, which obviously needs
to be fixed still.

Thank you for pointing this out!

~Aaron

Thanks for the prompt fix!
Vassil