libclang , clang_Cursor_isAnonymous what is an anonymous declaration

I have some difficulties to understand what are anonymous structures declaration (or union) .

From this link: http://clang.llvm.org/doxygen/classclang_1_1RecordDecl.html#ad2dd151523eecb8d15149cc0937c3dff

this is an anonymous declaration

union { int i; float f; };

and not this

union X { int i; float f; };
union { int i; float f; } obj;

But if I make some tests:

#include <stdio.h>
#include "clang-c/Index.h"
/*
compile with:
clang -lclang -o anonymous_record_decl_check anonymous_record_decl_check.c
*/
static enum CXChildVisitResult
visitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
   CXSourceLocation loc;
   CXFile file;
   unsigned line;
   unsigned column;
   unsigned offset;
   if (clang_getCursorKind(cursor) == CXCursor_StructDecl)
   {
     printf("sentinel %d\n", __LINE__);
     loc = clang_getCursorLocation(cursor);
     clang_getSpellingLocation(loc,
                               &file,
                               &line,
                               &column,
                               &offset);

     printf("sentinel %d\n", __LINE__);
     printf("line: %d anon ? %d\n", line, clang_Cursor_isAnonymous(cursor));
   }

   if (clang_getCursorKind(cursor) == CXCursor_UnionDecl)
   {
     printf("sentinel %d\n", __LINE__);
     loc = clang_getCursorLocation(cursor);
     printf("sentinel %d\n", __LINE__);
     clang_getSpellingLocation(loc,
                               &file,
                               &line,
                               &column,
                               &offset);
     printf("line: %d anon ? %d\n", line, clang_Cursor_isAnonymous(cursor));
   }
   return CXChildVisit_Recurse; // visit complete AST recursivly
}

int main(int argc, char *argv) {
   CXIndex Index = clang_createIndex(0, 1);
   CXTranslationUnit TU = clang_createTranslationUnitFromSourceFile(Index,
"record_decls.c",
                                                       0,
                                                       0);

   clang_visitChildren(clang_getTranslationUnitCursor(TU), visitor, 0);

   clang_disposeTranslationUnit(TU);
   clang_disposeIndex(Index);
   return 0;
}

with the file that is parsed ( record_decls.c ):

struct { int a; char b; };
struct tata { int c; double e;};
union { int i; float f; };
union X { int i; float f; };

I have this output:

sentinel 17
sentinel 25
line: 1 anon ? 0
sentinel 17
sentinel 25
line: 2 anon ? 0
sentinel 31
sentinel 33
line: 3 anon ? 0
sentinel 31
sentinel 33
line: 4 anon ? 0

Which means that all my declarations return the same value form clang_Cursor_isAnonymous

Which means, well I don't really know, here is the comments from the headers:

/**
  * \brief Determine whether the given cursor represents an anonymous record
  * declaration.
  */

Any ideas?

cedlemo

When I use clang in order to parse the same file, I 'm not able to find anonymous struct or union decl:
even if I use the anonymous examples of the documentation.

class MyASTConsumer : public clang::ASTConsumer
{
  public:
  MyASTConsumer() : clang::ASTConsumer() { }
  virtual ~MyASTConsumer() { }
  virtual void HandleTagDeclDefinition( clang::TagDecl * d)
  {
    if (d->isStruct())
      std::cout << "struct" << std::endl;
    if (d->isUnion())
      std::cout << "union" << std::endl;
    clang::RecordDecl *r; r = llvm::cast(d);
    if( r->isAnonymousStructOrUnion() )
    {
      std::cout << "RecordDecl Anonymous : " << std::endl;
    }
  };

int main()
{
   using clang::CompilerInstance;
   using clang::TargetOptions;
   using clang::TargetInfo;
   using clang::FileEntry;
   using clang::Token;
   using clang::ASTContext;
   using clang::ASTConsumer;
   using clang::Parser;
   using clang::DiagnosticOptions;
   using clang::TextDiagnosticPrinter;
   CompilerInstance ci;
   DiagnosticOptions diagnosticOptions;
   ci.createDiagnostics();
   std::shared_ptrpto = std::make_shared();
   pto->Triple = llvm::sys::getDefaultTargetTriple();
   TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto);
   ci.setTarget(pti);
   ci.createFileManager();
   ci.createSourceManager(ci.getFileManager());
   ci.createPreprocessor(clang::TU_Complete);
   ci.getPreprocessorOpts().UsePredefines = false;
   MyASTConsumer *astConsumer = new MyASTConsumer();
   ci.setASTConsumer(llvm::make_unique(*astConsumer));
   ci.createASTContext();
   const FileEntry *pFile = ci.getFileManager().getFile("record_decls.c");
   clang::FileID id = ci.getSourceManager().createFileID(pFile, clang::SourceLocation(), clang::SrcMgr::C_User);
   ci.getSourceManager().setMainFileID(id);
ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), &ci.getPreprocessor());
   clang::ParseAST(ci.getPreprocessor(), astConsumer, ci.getASTContext());
   ci.getDiagnosticClient().EndSourceFile();
   return 0;
  }

My guess would be that language options aren't set correctly. Comment
in BuildAnonymousStructOrUnion (that calls setAnonymousStructOrUnion)
says:

Anonymous unions are a C++ feature (C++ [class.union]) and a C11
feature; anonymous structures are a C11 feature and GNU C++ extension.

Good to hear! Please don't reply directly in the future, reply to the
mailing list so everyone can see the discussion.