Where is default constructor delete function in clang?

Dear all,

I checked that clang deletes (checked IR code) structure’s constructor when a structure is declared with a structure pointer (e.g., structure “Item” in the below example code).

On the other hand, clang did not delete constructor when structure declared with variable (not a pointer) as structure “Item2” in the below example code.

[Example Code]


class DataSet

{

public:

struct Item

{

int info;

Item() {};
}* theitem;



struct Item2

{

int info;

Item2() {};

} theitem2;



int themax;

};



int main() {

DataSet T;

return 0;
}

I can understand this clang’s behavior (for optimization).

However, for research purposes, I need to keep constructor although structure declared with a structure pointer.

If you don’t mind, could you please advise how I find this optimization function (remove constructor) in clang (I plan to update this code)?

  • I tried to forcibly insert constructor using “DeclareImplicitDefaultConstructor or DefineImplicitDefaultConstructor” and check other possible functions such as “ShouldDeleteSpecialMember” (in SemaDeclCXX.cpp).
  • However, I could not find an answer yet.
    Thank you very much.

Best regards,
Y. Jeon.

Ah, sorry, was confused a bit because you talked about “deleting constructors” and I thought you meant in the C++ sense of “= delete”.

You mean Clang didn’t produce an actual llvm::Function for a constructor when the constructor is trivial? Right right.

I’d suggest you start with the small/simple example of a non-trivial ctor like and one with a trivial dtor:

struct t1 { t1(); };
struct t2 { };
int main() {
t1 v1;
t2 v2;
}

(I’d actually write these in two different programs, rather than all in one)

Then compile each of the two examples - run the compiler under a debugger, break on, maybe llvm::Function’s ctor, eventually you’ll break on LLVM making the ctor function, and you can trace back through the two debuggers to try to figure out why one does make the ctor and why one doesn’t and modify the code there to always make it.

Dear all,

I checked that clang deletes (checked IR code) structure’s constructor when a structure is declared with a structure pointer (e.g., structure “Item” in the below example code).

On the other hand, clang did not delete constructor when structure declared with variable (not a pointer) as structure “Item2” in the below example code.

[Example Code]


class DataSet

{

public:

struct Item

{

int info;

Item() {};
}* theitem;



struct Item2

{

int info;

Item2() {};

} theitem2;



int themax;

};



int main() {

DataSet T;

return 0;
}

I can understand this clang’s behavior (for optimization).

However, for research purposes, I need to keep constructor although structure declared with a structure pointer.

If you don’t mind, could you please advise how I find this optimization function (remove constructor) in clang (I plan to update this code)?

Your description doesn’t match what’s happening. The constructor isn’t being deleted / removed from the IR. Instead, what’s happening is that it’s never emitted in the first place.

The process Clang follows is:

  1. Parse and semantically analyze the source file, forming an AST.
  2. Emit all the strong external symbols defined in the AST, and recursively emit any discardable symbols referenced by those strong external symbols.

Step 1 will build AST for both the Item and Item2 constructors. In step 2, the only strong external symbol to emit as IR is main. main references the DataSet default constructor, so we emit that. The DataSet default constructor references the Item2 constructor, so we emit that. LLVM IR for he Item constructor is never emitted because it’s not used by this translation unit.

Depending on what you want to do for your research purposes, you could either look at the AST rather than the IR, or use the -femit-all-decls flag to ask Clang to emit declarations even if they’re unused.