Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/CodeGen/CGNonTrivialStruct.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- CGNonTrivialStruct.cpp - Emit Special Functions for C Structs ----===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file defines functions to generate various special functions for C
10
// structs.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "CodeGenFunction.h"
15
#include "CodeGenModule.h"
16
#include "clang/AST/NonTrivialTypeVisitor.h"
17
#include "clang/CodeGen/CodeGenABITypes.h"
18
#include "llvm/Support/ScopedPrinter.h"
19
#include <array>
20
21
using namespace clang;
22
using namespace CodeGen;
23
24
// Return the size of a field in number of bits.
25
static uint64_t getFieldSize(const FieldDecl *FD, QualType FT,
26
170
                             ASTContext &Ctx) {
27
170
  if (FD && 
FD->isBitField()168
)
28
30
    return FD->getBitWidthValue(Ctx);
29
140
  return Ctx.getTypeSize(FT);
30
140
}
31
32
namespace {
33
enum { DstIdx = 0, SrcIdx = 1 };
34
const char *ValNameStr[2] = {"dst", "src"};
35
36
template <class Derived> struct StructVisitor {
37
489
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
68
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
37
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
103
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
101
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyConstructor>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
49
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyAssignment>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
14
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveConstructor>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
13
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveAssignment>::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
12
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<false> >::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
67
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<true> >::StructVisitor(clang::ASTContext&)
Line
Count
Source
37
25
  StructVisitor(ASTContext &Ctx) : Ctx(Ctx) {}
38
39
  template <class... Ts>
40
405
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
405
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
405
43
405
    // Iterate over the fields of the struct.
44
891
    for (const FieldDecl *FD : RD->fields()) {
45
891
      QualType FT = FD->getType();
46
891
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()16
:
FT875
;
47
891
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
891
    }
49
405
50
405
    asDerived().flushTrivialFields(Args...);
51
405
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::visitStructFields<>(clang::QualType, clang::CharUnits)
Line
Count
Source
40
47
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
47
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
47
43
47
    // Iterate over the fields of the struct.
44
93
    for (const FieldDecl *FD : RD->fields()) {
45
93
      QualType FT = FD->getType();
46
93
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()0
: FT;
47
93
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
93
    }
49
47
50
47
    asDerived().flushTrivialFields(Args...);
51
47
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::visitStructFields<std::__1::array<clang::CodeGen::Address, 1ul> >(clang::QualType, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
40
17
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
17
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
17
43
17
    // Iterate over the fields of the struct.
44
34
    for (const FieldDecl *FD : RD->fields()) {
45
34
      QualType FT = FD->getType();
46
34
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()0
: FT;
47
34
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
34
    }
49
17
50
17
    asDerived().flushTrivialFields(Args...);
51
17
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<false> >::visitStructFields<>(clang::QualType, clang::CharUnits)
Line
Count
Source
40
78
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
78
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
78
43
78
    // Iterate over the fields of the struct.
44
174
    for (const FieldDecl *FD : RD->fields()) {
45
174
      QualType FT = FD->getType();
46
174
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()4
:
FT170
;
47
174
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
174
    }
49
78
50
78
    asDerived().flushTrivialFields(Args...);
51
78
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::visitStructFields<>(clang::QualType, clang::CharUnits)
Line
Count
Source
40
129
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
129
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
129
43
129
    // Iterate over the fields of the struct.
44
274
    for (const FieldDecl *FD : RD->fields()) {
45
274
      QualType FT = FD->getType();
46
274
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()4
:
FT270
;
47
274
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
274
    }
49
129
50
129
    asDerived().flushTrivialFields(Args...);
51
129
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::visitStructFields<std::__1::array<clang::CodeGen::Address, 1ul> >(clang::QualType, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
40
39
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
39
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
39
43
39
    // Iterate over the fields of the struct.
44
97
    for (const FieldDecl *FD : RD->fields()) {
45
97
      QualType FT = FD->getType();
46
97
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()4
:
FT93
;
47
97
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
97
    }
49
39
50
39
    asDerived().flushTrivialFields(Args...);
51
39
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyConstructor>::visitStructFields<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
40
29
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
29
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
29
43
29
    // Iterate over the fields of the struct.
44
79
    for (const FieldDecl *FD : RD->fields()) {
45
79
      QualType FT = FD->getType();
46
79
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()4
:
FT75
;
47
79
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
79
    }
49
29
50
29
    asDerived().flushTrivialFields(Args...);
51
29
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyAssignment>::visitStructFields<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
40
12
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
12
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
12
43
12
    // Iterate over the fields of the struct.
44
24
    for (const FieldDecl *FD : RD->fields()) {
45
24
      QualType FT = FD->getType();
46
24
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()0
: FT;
47
24
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
24
    }
49
12
50
12
    asDerived().flushTrivialFields(Args...);
51
12
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<true> >::visitStructFields<>(clang::QualType, clang::CharUnits)
Line
Count
Source
40
33
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
33
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
33
43
33
    // Iterate over the fields of the struct.
44
70
    for (const FieldDecl *FD : RD->fields()) {
45
70
      QualType FT = FD->getType();
46
70
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()0
: FT;
47
70
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
70
    }
49
33
50
33
    asDerived().flushTrivialFields(Args...);
51
33
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveConstructor>::visitStructFields<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
40
11
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
11
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
11
43
11
    // Iterate over the fields of the struct.
44
24
    for (const FieldDecl *FD : RD->fields()) {
45
24
      QualType FT = FD->getType();
46
24
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()0
: FT;
47
24
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
24
    }
49
11
50
11
    asDerived().flushTrivialFields(Args...);
51
11
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveAssignment>::visitStructFields<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
40
10
  void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
41
10
    const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
42
10
43
10
    // Iterate over the fields of the struct.
44
22
    for (const FieldDecl *FD : RD->fields()) {
45
22
      QualType FT = FD->getType();
46
22
      FT = QT.isVolatileQualified() ? 
FT.withVolatile()0
: FT;
47
22
      asDerived().visit(FT, FD, CurStructOffset, Args...);
48
22
    }
49
10
50
10
    asDerived().flushTrivialFields(Args...);
51
10
  }
52
53
221
  template <class... Ts> void visitTrivial(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::visitTrivial<clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
53
12
  template <class... Ts> void visitTrivial(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::visitTrivial<clang::QualType, clang::FieldDecl const*, clang::CharUnits>(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
53
37
  template <class... Ts> void visitTrivial(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::visitTrivial<clang::QualType, clang::FieldDecl const*, clang::CharUnits>(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
53
123
  template <class... Ts> void visitTrivial(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::visitTrivial<clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
53
49
  template <class... Ts> void visitTrivial(Ts... Args) {}
54
55
0
  template <class... Ts> void visitCXXDestructor(Ts... Args) {
56
0
    llvm_unreachable("field of a C++ struct type is not expected");
57
0
  }
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::visitCXXDestructor<clang::QualType, clang::FieldDecl const*, clang::CharUnits>(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::visitCXXDestructor<clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
58
59
258
  template <class... Ts> void flushTrivialFields(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::flushTrivialFields<std::__1::array<clang::CodeGen::Address, 1ul> >(std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
59
23
  template <class... Ts> void flushTrivialFields(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::flushTrivialFields<>()
Line
Count
Source
59
51
  template <class... Ts> void flushTrivialFields(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::flushTrivialFields<>()
Line
Count
Source
59
137
  template <class... Ts> void flushTrivialFields(Ts... Args) {}
CGNonTrivialStruct.cpp:void (anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::flushTrivialFields<std::__1::array<clang::CodeGen::Address, 1ul> >(std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
59
47
  template <class... Ts> void flushTrivialFields(Ts... Args) {}
60
61
795
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
795
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
728
                    .getFieldOffset(FD->getFieldIndex())
64
795
              : 
067
;
65
795
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
59
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
59
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
22
                    .getFieldOffset(FD->getFieldIndex())
64
59
              : 
037
;
65
59
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
60
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
60
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
56
                    .getFieldOffset(FD->getFieldIndex())
64
60
              : 
04
;
65
60
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<false> >::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
176
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
176
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
172
                    .getFieldOffset(FD->getFieldIndex())
64
176
              : 
04
;
65
176
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
159
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
159
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
151
                    .getFieldOffset(FD->getFieldIndex())
64
159
              : 
08
;
65
159
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
56
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
56
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
48
                    .getFieldOffset(FD->getFieldIndex())
64
56
              : 
08
;
65
56
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyConstructor>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
111
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
111
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
105
                    .getFieldOffset(FD->getFieldIndex())
64
111
              : 
06
;
65
111
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyAssignment>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
36
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
36
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
36
                    .getFieldOffset(FD->getFieldIndex())
64
36
              : 
00
;
65
36
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<true> >::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
70
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
70
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
70
                    .getFieldOffset(FD->getFieldIndex())
64
70
              : 
00
;
65
70
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveConstructor>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
36
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
36
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
36
                    .getFieldOffset(FD->getFieldIndex())
64
36
              : 
00
;
65
36
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveAssignment>::getFieldOffsetInBits(clang::FieldDecl const*)
Line
Count
Source
61
32
  uint64_t getFieldOffsetInBits(const FieldDecl *FD) {
62
32
    return FD ? Ctx.getASTRecordLayout(FD->getParent())
63
32
                    .getFieldOffset(FD->getFieldIndex())
64
32
              : 
00
;
65
32
  }
66
67
629
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
629
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
629
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
59
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
59
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
59
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
60
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
60
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
60
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<false> >::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
94
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
94
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
94
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
159
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
159
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
159
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
56
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
56
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
56
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyConstructor>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
79
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
79
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
79
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyAssignment>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
28
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
28
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
28
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<true> >::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
42
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
42
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
42
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveConstructor>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
28
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
28
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
28
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveAssignment>::getFieldOffset(clang::FieldDecl const*)
Line
Count
Source
67
24
  CharUnits getFieldOffset(const FieldDecl *FD) {
68
24
    return Ctx.toCharUnitsFromBits(getFieldOffsetInBits(FD));
69
24
  }
70
71
2.26k
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::asDerived()
Line
Count
Source
71
140
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::asDerived()
Line
Count
Source
71
51
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<false> >::asDerived()
Line
Count
Source
71
684
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::asDerived()
Line
Count
Source
71
403
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::asDerived()
Line
Count
Source
71
136
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyConstructor>::asDerived()
Line
Count
Source
71
312
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyAssignment>::asDerived()
Line
Count
Source
71
92
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<true> >::asDerived()
Line
Count
Source
71
271
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveConstructor>::asDerived()
Line
Count
Source
71
91
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveAssignment>::asDerived()
Line
Count
Source
71
84
  Derived &asDerived() { return static_cast<Derived &>(*this); }
72
73
1.14k
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitialize>::getContext()
Line
Count
Source
73
79
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDefaultInitializeFuncName>::getContext()
Line
Count
Source
73
101
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<false> >::getContext()
Line
Count
Source
73
258
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructorFuncName>::getContext()
Line
Count
Source
73
290
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenDestructor>::getContext()
Line
Count
Source
73
105
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyConstructor>::getContext()
Line
Count
Source
73
119
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenCopyAssignment>::getContext()
Line
Count
Source
73
32
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenBinaryFuncName<true> >::getContext()
Line
Count
Source
73
98
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveConstructor>::getContext()
Line
Count
Source
73
32
  ASTContext &getContext() { return Ctx; }
CGNonTrivialStruct.cpp:(anonymous namespace)::StructVisitor<(anonymous namespace)::GenMoveAssignment>::getContext()
Line
Count
Source
73
30
  ASTContext &getContext() { return Ctx; }
74
  ASTContext &Ctx;
75
};
76
77
template <class Derived, bool IsMove>
78
struct CopyStructVisitor : StructVisitor<Derived>,
79
                           CopiedTypeVisitor<Derived, IsMove> {
80
  using StructVisitor<Derived>::asDerived;
81
  using Super = CopiedTypeVisitor<Derived, IsMove>;
82
83
180
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyConstructor, false>::CopyStructVisitor(clang::ASTContext&)
Line
Count
Source
83
49
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyAssignment, false>::CopyStructVisitor(clang::ASTContext&)
Line
Count
Source
83
14
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveConstructor, true>::CopyStructVisitor(clang::ASTContext&)
Line
Count
Source
83
13
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveAssignment, true>::CopyStructVisitor(clang::ASTContext&)
Line
Count
Source
83
12
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<false>, false>::CopyStructVisitor(clang::ASTContext&)
Line
Count
Source
83
67
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<true>, true>::CopyStructVisitor(clang::ASTContext&)
Line
Count
Source
83
25
  CopyStructVisitor(ASTContext &Ctx) : StructVisitor<Derived>(Ctx) {}
84
85
  template <class... Ts>
86
  void preVisit(QualType::PrimitiveCopyKind PCK, QualType FT,
87
389
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
389
    if (PCK)
89
231
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
389
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<false>, false>::preVisit<>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
87
172
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
172
    if (PCK)
89
98
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
172
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyConstructor, false>::preVisit<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
87
77
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
77
    if (PCK)
89
45
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
77
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyAssignment, false>::preVisit<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
87
24
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
24
    if (PCK)
89
16
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
24
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<true>, true>::preVisit<>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
87
70
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
70
    if (PCK)
89
42
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
70
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveConstructor, true>::preVisit<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
87
24
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
24
    if (PCK)
89
16
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
24
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveAssignment, true>::preVisit<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
87
22
                const FieldDecl *FD, CharUnits CurStructOffset, Ts &&... Args) {
88
22
    if (PCK)
89
14
      asDerived().flushTrivialFields(std::forward<Ts>(Args)...);
90
22
  }
91
92
  template <class... Ts>
93
  void visitWithKind(QualType::PrimitiveCopyKind PCK, QualType FT,
94
                     const FieldDecl *FD, CharUnits CurStructOffset,
95
403
                     Ts &&... Args) {
96
403
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
14
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
14
                             CurStructOffset, std::forward<Ts>(Args)...);
99
14
      return;
100
14
    }
101
389
102
389
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
389
                         std::forward<Ts>(Args)...);
104
389
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<false>, false>::visitWithKind<>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
95
178
                     Ts &&... Args) {
96
178
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
6
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
6
                             CurStructOffset, std::forward<Ts>(Args)...);
99
6
      return;
100
6
    }
101
172
102
172
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
172
                         std::forward<Ts>(Args)...);
104
172
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyConstructor, false>::visitWithKind<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
95
85
                     Ts &&... Args) {
96
85
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
8
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
8
                             CurStructOffset, std::forward<Ts>(Args)...);
99
8
      return;
100
8
    }
101
77
102
77
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
77
                         std::forward<Ts>(Args)...);
104
77
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyAssignment, false>::visitWithKind<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
95
24
                     Ts &&... Args) {
96
24
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
0
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
0
                             CurStructOffset, std::forward<Ts>(Args)...);
99
0
      return;
100
0
    }
101
24
102
24
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
24
                         std::forward<Ts>(Args)...);
104
24
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<true>, true>::visitWithKind<>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
95
70
                     Ts &&... Args) {
96
70
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
0
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
0
                             CurStructOffset, std::forward<Ts>(Args)...);
99
0
      return;
100
0
    }
101
70
102
70
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
70
                         std::forward<Ts>(Args)...);
104
70
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveConstructor, true>::visitWithKind<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
95
24
                     Ts &&... Args) {
96
24
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
0
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
0
                             CurStructOffset, std::forward<Ts>(Args)...);
99
0
      return;
100
0
    }
101
24
102
24
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
24
                         std::forward<Ts>(Args)...);
104
24
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveAssignment, true>::visitWithKind<std::__1::array<clang::CodeGen::Address, 2ul>&>(clang::QualType::PrimitiveCopyKind, clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>&&&)
Line
Count
Source
95
22
                     Ts &&... Args) {
96
22
    if (const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
97
0
      asDerived().visitArray(PCK, AT, FT.isVolatileQualified(), FD,
98
0
                             CurStructOffset, std::forward<Ts>(Args)...);
99
0
      return;
100
0
    }
101
22
102
22
    Super::visitWithKind(PCK, FT, FD, CurStructOffset,
103
22
                         std::forward<Ts>(Args)...);
104
22
  }
105
106
  template <class... Ts>
107
  void visitTrivial(QualType FT, const FieldDecl *FD, CharUnits CurStructOffset,
108
162
                    Ts... Args) {
109
162
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
162
    ASTContext &Ctx = asDerived().getContext();
111
162
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
162
113
162
    // Ignore zero-sized fields.
114
162
    if (FieldSize == 0)
115
4
      return;
116
158
117
158
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
158
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
158
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
158
121
158
    // Set Start if this is the first field of a sequence of trivial fields.
122
158
    if (Start == End)
123
142
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
158
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
158
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<false>, false>::visitTrivial<>(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
108
76
                    Ts... Args) {
109
76
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
76
    ASTContext &Ctx = asDerived().getContext();
111
76
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
76
113
76
    // Ignore zero-sized fields.
114
76
    if (FieldSize == 0)
115
2
      return;
116
74
117
74
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
74
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
74
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
74
121
74
    // Set Start if this is the first field of a sequence of trivial fields.
122
74
    if (Start == End)
123
66
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
74
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
74
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyConstructor, false>::visitTrivial<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
108
34
                    Ts... Args) {
109
34
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
34
    ASTContext &Ctx = asDerived().getContext();
111
34
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
34
113
34
    // Ignore zero-sized fields.
114
34
    if (FieldSize == 0)
115
2
      return;
116
32
117
32
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
32
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
32
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
32
121
32
    // Set Start if this is the first field of a sequence of trivial fields.
122
32
    if (Start == End)
123
24
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
32
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
32
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenCopyAssignment, false>::visitTrivial<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
108
8
                    Ts... Args) {
109
8
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
8
    ASTContext &Ctx = asDerived().getContext();
111
8
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
8
113
8
    // Ignore zero-sized fields.
114
8
    if (FieldSize == 0)
115
0
      return;
116
8
117
8
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
8
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
8
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
8
121
8
    // Set Start if this is the first field of a sequence of trivial fields.
122
8
    if (Start == End)
123
8
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
8
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
8
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenBinaryFuncName<true>, true>::visitTrivial<>(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
108
28
                    Ts... Args) {
109
28
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
28
    ASTContext &Ctx = asDerived().getContext();
111
28
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
28
113
28
    // Ignore zero-sized fields.
114
28
    if (FieldSize == 0)
115
0
      return;
116
28
117
28
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
28
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
28
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
28
121
28
    // Set Start if this is the first field of a sequence of trivial fields.
122
28
    if (Start == End)
123
28
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
28
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
28
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveConstructor, true>::visitTrivial<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
108
8
                    Ts... Args) {
109
8
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
8
    ASTContext &Ctx = asDerived().getContext();
111
8
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
8
113
8
    // Ignore zero-sized fields.
114
8
    if (FieldSize == 0)
115
0
      return;
116
8
117
8
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
8
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
8
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
8
121
8
    // Set Start if this is the first field of a sequence of trivial fields.
122
8
    if (Start == End)
123
8
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
8
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
8
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::CopyStructVisitor<(anonymous namespace)::GenMoveAssignment, true>::visitTrivial<std::__1::array<clang::CodeGen::Address, 2ul> >(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
108
8
                    Ts... Args) {
109
8
    assert(!FT.isVolatileQualified() && "volatile field not expected");
110
8
    ASTContext &Ctx = asDerived().getContext();
111
8
    uint64_t FieldSize = getFieldSize(FD, FT, Ctx);
112
8
113
8
    // Ignore zero-sized fields.
114
8
    if (FieldSize == 0)
115
0
      return;
116
8
117
8
    uint64_t FStartInBits = asDerived().getFieldOffsetInBits(FD);
118
8
    uint64_t FEndInBits = FStartInBits + FieldSize;
119
8
    uint64_t RoundedFEnd = llvm::alignTo(FEndInBits, Ctx.getCharWidth());
120
8
121
8
    // Set Start if this is the first field of a sequence of trivial fields.
122
8
    if (Start == End)
123
8
      Start = CurStructOffset + Ctx.toCharUnitsFromBits(FStartInBits);
124
8
    End = CurStructOffset + Ctx.toCharUnitsFromBits(RoundedFEnd);
125
8
  }
126
127
  CharUnits Start = CharUnits::Zero(), End = CharUnits::Zero();
128
};
129
130
// This function creates the mangled name of a special function of a non-trivial
131
// C struct. Since there is no ODR in C, the function is mangled based on the
132
// struct contents and not the name. The mangled name has the following
133
// structure:
134
//
135
// <function-name> ::= <prefix> <alignment-info> "_" <struct-field-info>
136
// <prefix> ::= "__destructor_" | "__default_constructor_" |
137
//              "__copy_constructor_" | "__move_constructor_" |
138
//              "__copy_assignment_" | "__move_assignment_"
139
// <alignment-info> ::= <dst-alignment> ["_" <src-alignment>]
140
// <struct-field-info> ::= <field-info>+
141
// <field-info> ::= <struct-or-scalar-field-info> | <array-field-info>
142
// <struct-or-scalar-field-info> ::= "_S" <struct-field-info> |
143
//                                   <strong-field-info> | <trivial-field-info>
144
// <array-field-info> ::= "_AB" <array-offset> "s" <element-size> "n"
145
//                        <num-elements> <innermost-element-info> "_AE"
146
// <innermost-element-info> ::= <struct-or-scalar-field-info>
147
// <strong-field-info> ::= "_s" ["b"] ["v"] <field-offset>
148
// <trivial-field-info> ::= "_t" ["v"] <field-offset> "_" <field-size>
149
150
template <class Derived> struct GenFuncNameBase {
151
284
  std::string getVolatileOffsetStr(bool IsVolatile, CharUnits Offset) {
152
284
    std::string S;
153
284
    if (IsVolatile)
154
8
      S = "v";
155
284
    S += llvm::to_string(Offset.getQuantity());
156
284
    return S;
157
284
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::getVolatileOffsetStr(bool, clang::CharUnits)
Line
Count
Source
151
46
  std::string getVolatileOffsetStr(bool IsVolatile, CharUnits Offset) {
152
46
    std::string S;
153
46
    if (IsVolatile)
154
0
      S = "v";
155
46
    S += llvm::to_string(Offset.getQuantity());
156
46
    return S;
157
46
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::getVolatileOffsetStr(bool, clang::CharUnits)
Line
Count
Source
151
79
  std::string getVolatileOffsetStr(bool IsVolatile, CharUnits Offset) {
152
79
    std::string S;
153
79
    if (IsVolatile)
154
4
      S = "v";
155
79
    S += llvm::to_string(Offset.getQuantity());
156
79
    return S;
157
79
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::getVolatileOffsetStr(bool, clang::CharUnits)
Line
Count
Source
151
125
  std::string getVolatileOffsetStr(bool IsVolatile, CharUnits Offset) {
152
125
    std::string S;
153
125
    if (IsVolatile)
154
4
      S = "v";
155
125
    S += llvm::to_string(Offset.getQuantity());
156
125
    return S;
157
125
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::getVolatileOffsetStr(bool, clang::CharUnits)
Line
Count
Source
151
34
  std::string getVolatileOffsetStr(bool IsVolatile, CharUnits Offset) {
152
34
    std::string S;
153
34
    if (IsVolatile)
154
0
      S = "v";
155
34
    S += llvm::to_string(Offset.getQuantity());
156
34
    return S;
157
34
  }
158
159
  void visitARCStrong(QualType FT, const FieldDecl *FD,
160
221
                      CharUnits CurStructOffset) {
161
221
    appendStr("_s");
162
221
    if (FT->isBlockPointerType())
163
6
      appendStr("b");
164
221
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
165
221
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
166
221
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::visitARCStrong(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
160
34
                      CharUnits CurStructOffset) {
161
34
    appendStr("_s");
162
34
    if (FT->isBlockPointerType())
163
0
      appendStr("b");
164
34
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
165
34
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
166
34
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::visitARCStrong(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
160
61
                      CharUnits CurStructOffset) {
161
61
    appendStr("_s");
162
61
    if (FT->isBlockPointerType())
163
4
      appendStr("b");
164
61
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
165
61
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
166
61
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::visitARCStrong(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
160
100
                      CharUnits CurStructOffset) {
161
100
    appendStr("_s");
162
100
    if (FT->isBlockPointerType())
163
2
      appendStr("b");
164
100
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
165
100
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
166
100
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::visitARCStrong(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
160
26
                      CharUnits CurStructOffset) {
161
26
    appendStr("_s");
162
26
    if (FT->isBlockPointerType())
163
0
      appendStr("b");
164
26
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
165
26
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
166
26
  }
167
168
  void visitARCWeak(QualType FT, const FieldDecl *FD,
169
63
                    CharUnits CurStructOffset) {
170
63
    appendStr("_w");
171
63
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172
63
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
173
63
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::visitARCWeak(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
169
12
                    CharUnits CurStructOffset) {
170
12
    appendStr("_w");
171
12
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172
12
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
173
12
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::visitARCWeak(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
169
18
                    CharUnits CurStructOffset) {
170
18
    appendStr("_w");
171
18
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172
18
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
173
18
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::visitARCWeak(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
169
25
                    CharUnits CurStructOffset) {
170
25
    appendStr("_w");
171
25
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172
25
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
173
25
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::visitARCWeak(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
169
8
                    CharUnits CurStructOffset) {
170
8
    appendStr("_w");
171
8
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
172
8
    appendStr(getVolatileOffsetStr(FT.isVolatileQualified(), FieldOffset));
173
8
  }
174
175
  void visitStruct(QualType QT, const FieldDecl *FD,
176
55
                   CharUnits CurStructOffset) {
177
55
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178
55
    appendStr("_S");
179
55
    asDerived().visitStructFields(QT, FieldOffset);
180
55
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::visitStruct(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
176
10
                   CharUnits CurStructOffset) {
177
10
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178
10
    appendStr("_S");
179
10
    asDerived().visitStructFields(QT, FieldOffset);
180
10
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::visitStruct(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
176
11
                   CharUnits CurStructOffset) {
177
11
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178
11
    appendStr("_S");
179
11
    asDerived().visitStructFields(QT, FieldOffset);
180
11
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::visitStruct(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
176
26
                   CharUnits CurStructOffset) {
177
26
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178
26
    appendStr("_S");
179
26
    asDerived().visitStructFields(QT, FieldOffset);
180
26
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::visitStruct(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
176
8
                   CharUnits CurStructOffset) {
177
8
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
178
8
    appendStr("_S");
179
8
    asDerived().visitStructFields(QT, FieldOffset);
180
8
  }
181
182
  template <class FieldKind>
183
  void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
184
30
                  const FieldDecl *FD, CharUnits CurStructOffset) {
185
30
    // String for non-volatile trivial fields is emitted when
186
30
    // flushTrivialFields is called.
187
30
    if (!FK)
188
14
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset);
189
16
190
16
    asDerived().flushTrivialFields();
191
16
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
192
16
    ASTContext &Ctx = asDerived().getContext();
193
16
    const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
194
16
    unsigned NumElts = Ctx.getConstantArrayElementCount(CAT);
195
16
    QualType EltTy = Ctx.getBaseElementType(CAT);
196
16
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltTy);
197
16
    appendStr("_AB" + llvm::to_string(FieldOffset.getQuantity()) + "s" +
198
16
              llvm::to_string(EltSize.getQuantity()) + "n" +
199
16
              llvm::to_string(NumElts));
200
16
    EltTy = IsVolatile ? 
EltTy.withVolatile()2
:
EltTy14
;
201
16
    asDerived().visitWithKind(FK, EltTy, nullptr, FieldOffset);
202
16
    appendStr("_AE");
203
16
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::visitArray<clang::QualType::PrimitiveDefaultInitializeKind>(clang::QualType::PrimitiveDefaultInitializeKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
184
4
                  const FieldDecl *FD, CharUnits CurStructOffset) {
185
4
    // String for non-volatile trivial fields is emitted when
186
4
    // flushTrivialFields is called.
187
4
    if (!FK)
188
0
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset);
189
4
190
4
    asDerived().flushTrivialFields();
191
4
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
192
4
    ASTContext &Ctx = asDerived().getContext();
193
4
    const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
194
4
    unsigned NumElts = Ctx.getConstantArrayElementCount(CAT);
195
4
    QualType EltTy = Ctx.getBaseElementType(CAT);
196
4
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltTy);
197
4
    appendStr("_AB" + llvm::to_string(FieldOffset.getQuantity()) + "s" +
198
4
              llvm::to_string(EltSize.getQuantity()) + "n" +
199
4
              llvm::to_string(NumElts));
200
4
    EltTy = IsVolatile ? 
EltTy.withVolatile()0
: EltTy;
201
4
    asDerived().visitWithKind(FK, EltTy, nullptr, FieldOffset);
202
4
    appendStr("_AE");
203
4
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::visitArray<clang::QualType::PrimitiveCopyKind>(clang::QualType::PrimitiveCopyKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
184
6
                  const FieldDecl *FD, CharUnits CurStructOffset) {
185
6
    // String for non-volatile trivial fields is emitted when
186
6
    // flushTrivialFields is called.
187
6
    if (!FK)
188
2
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset);
189
4
190
4
    asDerived().flushTrivialFields();
191
4
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
192
4
    ASTContext &Ctx = asDerived().getContext();
193
4
    const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
194
4
    unsigned NumElts = Ctx.getConstantArrayElementCount(CAT);
195
4
    QualType EltTy = Ctx.getBaseElementType(CAT);
196
4
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltTy);
197
4
    appendStr("_AB" + llvm::to_string(FieldOffset.getQuantity()) + "s" +
198
4
              llvm::to_string(EltSize.getQuantity()) + "n" +
199
4
              llvm::to_string(NumElts));
200
4
    EltTy = IsVolatile ? 
EltTy.withVolatile()2
:
EltTy2
;
201
4
    asDerived().visitWithKind(FK, EltTy, nullptr, FieldOffset);
202
4
    appendStr("_AE");
203
4
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::visitArray<clang::QualType::DestructionKind>(clang::QualType::DestructionKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
184
20
                  const FieldDecl *FD, CharUnits CurStructOffset) {
185
20
    // String for non-volatile trivial fields is emitted when
186
20
    // flushTrivialFields is called.
187
20
    if (!FK)
188
12
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset);
189
8
190
8
    asDerived().flushTrivialFields();
191
8
    CharUnits FieldOffset = CurStructOffset + asDerived().getFieldOffset(FD);
192
8
    ASTContext &Ctx = asDerived().getContext();
193
8
    const ConstantArrayType *CAT = cast<ConstantArrayType>(AT);
194
8
    unsigned NumElts = Ctx.getConstantArrayElementCount(CAT);
195
8
    QualType EltTy = Ctx.getBaseElementType(CAT);
196
8
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltTy);
197
8
    appendStr("_AB" + llvm::to_string(FieldOffset.getQuantity()) + "s" +
198
8
              llvm::to_string(EltSize.getQuantity()) + "n" +
199
8
              llvm::to_string(NumElts));
200
8
    EltTy = IsVolatile ? 
EltTy.withVolatile()0
: EltTy;
201
8
    asDerived().visitWithKind(FK, EltTy, nullptr, FieldOffset);
202
8
    appendStr("_AE");
203
8
  }
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::visitArray<clang::QualType::PrimitiveCopyKind>(clang::QualType::PrimitiveCopyKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits)
204
205
1.31k
  void appendStr(StringRef Str) { Name += Str; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::appendStr(llvm::StringRef)
Line
Count
Source
205
184
  void appendStr(StringRef Str) { Name += Str; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::appendStr(llvm::StringRef)
Line
Count
Source
205
500
  void appendStr(StringRef Str) { Name += Str; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::appendStr(llvm::StringRef)
Line
Count
Source
205
456
  void appendStr(StringRef Str) { Name += Str; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::appendStr(llvm::StringRef)
Line
Count
Source
205
179
  void appendStr(StringRef Str) { Name += Str; }
206
207
232
  std::string getName(QualType QT, bool IsVolatile) {
208
232
    QT = IsVolatile ? 
QT.withVolatile()4
:
QT228
;
209
232
    asDerived().visitStructFields(QT, CharUnits::Zero());
210
232
    return Name;
211
232
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::getName(clang::QualType, bool)
Line
Count
Source
207
37
  std::string getName(QualType QT, bool IsVolatile) {
208
37
    QT = IsVolatile ? 
QT.withVolatile()0
: QT;
209
37
    asDerived().visitStructFields(QT, CharUnits::Zero());
210
37
    return Name;
211
37
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::getName(clang::QualType, bool)
Line
Count
Source
207
67
  std::string getName(QualType QT, bool IsVolatile) {
208
67
    QT = IsVolatile ? 
QT.withVolatile()2
:
QT65
;
209
67
    asDerived().visitStructFields(QT, CharUnits::Zero());
210
67
    return Name;
211
67
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::getName(clang::QualType, bool)
Line
Count
Source
207
103
  std::string getName(QualType QT, bool IsVolatile) {
208
103
    QT = IsVolatile ? 
QT.withVolatile()2
:
QT101
;
209
103
    asDerived().visitStructFields(QT, CharUnits::Zero());
210
103
    return Name;
211
103
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::getName(clang::QualType, bool)
Line
Count
Source
207
25
  std::string getName(QualType QT, bool IsVolatile) {
208
25
    QT = IsVolatile ? 
QT.withVolatile()0
: QT;
209
25
    asDerived().visitStructFields(QT, CharUnits::Zero());
210
25
    return Name;
211
25
  }
212
213
704
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDefaultInitializeFuncName>::asDerived()
Line
Count
Source
213
119
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<false> >::asDerived()
Line
Count
Source
213
186
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenDestructorFuncName>::asDerived()
Line
Count
Source
213
324
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncNameBase<(anonymous namespace)::GenBinaryFuncName<true> >::asDerived()
Line
Count
Source
213
75
  Derived &asDerived() { return static_cast<Derived &>(*this); }
214
215
  std::string Name;
216
};
217
218
template <class Derived>
219
struct GenUnaryFuncName : StructVisitor<Derived>, GenFuncNameBase<Derived> {
220
  GenUnaryFuncName(StringRef Prefix, CharUnits DstAlignment, ASTContext &Ctx)
221
140
      : StructVisitor<Derived>(Ctx) {
222
140
    this->appendStr(Prefix);
223
140
    this->appendStr(llvm::to_string(DstAlignment.getQuantity()));
224
140
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenUnaryFuncName<(anonymous namespace)::GenDefaultInitializeFuncName>::GenUnaryFuncName(llvm::StringRef, clang::CharUnits, clang::ASTContext&)
Line
Count
Source
221
37
      : StructVisitor<Derived>(Ctx) {
222
37
    this->appendStr(Prefix);
223
37
    this->appendStr(llvm::to_string(DstAlignment.getQuantity()));
224
37
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenUnaryFuncName<(anonymous namespace)::GenDestructorFuncName>::GenUnaryFuncName(llvm::StringRef, clang::CharUnits, clang::ASTContext&)
Line
Count
Source
221
103
      : StructVisitor<Derived>(Ctx) {
222
103
    this->appendStr(Prefix);
223
103
    this->appendStr(llvm::to_string(DstAlignment.getQuantity()));
224
103
  }
225
};
226
227
// Helper function to create a null constant.
228
14
static llvm::Constant *getNullForVariable(Address Addr) {
229
14
  llvm::Type *Ty = Addr.getElementType();
230
14
  return llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty));
231
14
}
232
233
template <bool IsMove>
234
struct GenBinaryFuncName : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>,
235
                           GenFuncNameBase<GenBinaryFuncName<IsMove>> {
236
237
  GenBinaryFuncName(StringRef Prefix, CharUnits DstAlignment,
238
                    CharUnits SrcAlignment, ASTContext &Ctx)
239
92
      : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>(Ctx) {
240
92
    this->appendStr(Prefix);
241
92
    this->appendStr(llvm::to_string(DstAlignment.getQuantity()));
242
92
    this->appendStr("_" + llvm::to_string(SrcAlignment.getQuantity()));
243
92
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFuncName<false>::GenBinaryFuncName(llvm::StringRef, clang::CharUnits, clang::CharUnits, clang::ASTContext&)
Line
Count
Source
239
67
      : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>(Ctx) {
240
67
    this->appendStr(Prefix);
241
67
    this->appendStr(llvm::to_string(DstAlignment.getQuantity()));
242
67
    this->appendStr("_" + llvm::to_string(SrcAlignment.getQuantity()));
243
67
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFuncName<true>::GenBinaryFuncName(llvm::StringRef, clang::CharUnits, clang::CharUnits, clang::ASTContext&)
Line
Count
Source
239
25
      : CopyStructVisitor<GenBinaryFuncName<IsMove>, IsMove>(Ctx) {
240
25
    this->appendStr(Prefix);
241
25
    this->appendStr(llvm::to_string(DstAlignment.getQuantity()));
242
25
    this->appendStr("_" + llvm::to_string(SrcAlignment.getQuantity()));
243
25
  }
244
245
255
  void flushTrivialFields() {
246
255
    if (this->Start == this->End)
247
161
      return;
248
94
249
94
    this->appendStr("_t" + llvm::to_string(this->Start.getQuantity()) + "w" +
250
94
                    llvm::to_string((this->End - this->Start).getQuantity()));
251
94
252
94
    this->Start = this->End = CharUnits::Zero();
253
94
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFuncName<false>::flushTrivialFields()
Line
Count
Source
245
180
  void flushTrivialFields() {
246
180
    if (this->Start == this->End)
247
114
      return;
248
66
249
66
    this->appendStr("_t" + llvm::to_string(this->Start.getQuantity()) + "w" +
250
66
                    llvm::to_string((this->End - this->Start).getQuantity()));
251
66
252
66
    this->Start = this->End = CharUnits::Zero();
253
66
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFuncName<true>::flushTrivialFields()
Line
Count
Source
245
75
  void flushTrivialFields() {
246
75
    if (this->Start == this->End)
247
47
      return;
248
28
249
28
    this->appendStr("_t" + llvm::to_string(this->Start.getQuantity()) + "w" +
250
28
                    llvm::to_string((this->End - this->Start).getQuantity()));
251
28
252
28
    this->Start = this->End = CharUnits::Zero();
253
28
  }
254
255
  void visitVolatileTrivial(QualType FT, const FieldDecl *FD,
256
8
                            CharUnits CurStructOffset) {
257
8
    // Because volatile fields can be bit-fields and are individually copied,
258
8
    // their offset and width are in bits.
259
8
    uint64_t OffsetInBits =
260
8
        this->Ctx.toBits(CurStructOffset) + this->getFieldOffsetInBits(FD);
261
8
    this->appendStr("_tv" + llvm::to_string(OffsetInBits) + "w" +
262
8
                    llvm::to_string(getFieldSize(FD, FT, this->Ctx)));
263
8
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFuncName<false>::visitVolatileTrivial(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
Line
Count
Source
256
8
                            CharUnits CurStructOffset) {
257
8
    // Because volatile fields can be bit-fields and are individually copied,
258
8
    // their offset and width are in bits.
259
8
    uint64_t OffsetInBits =
260
8
        this->Ctx.toBits(CurStructOffset) + this->getFieldOffsetInBits(FD);
261
8
    this->appendStr("_tv" + llvm::to_string(OffsetInBits) + "w" +
262
8
                    llvm::to_string(getFieldSize(FD, FT, this->Ctx)));
263
8
  }
Unexecuted instantiation: CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFuncName<true>::visitVolatileTrivial(clang::QualType, clang::FieldDecl const*, clang::CharUnits)
264
};
265
266
struct GenDefaultInitializeFuncName
267
    : GenUnaryFuncName<GenDefaultInitializeFuncName>,
268
      DefaultInitializedTypeVisitor<GenDefaultInitializeFuncName> {
269
  using Super = DefaultInitializedTypeVisitor<GenDefaultInitializeFuncName>;
270
  GenDefaultInitializeFuncName(CharUnits DstAlignment, ASTContext &Ctx)
271
      : GenUnaryFuncName<GenDefaultInitializeFuncName>("__default_constructor_",
272
37
                                                       DstAlignment, Ctx) {}
273
  void visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType FT,
274
97
                     const FieldDecl *FD, CharUnits CurStructOffset) {
275
97
    if (const auto *AT = getContext().getAsArrayType(FT)) {
276
4
      visitArray(PDIK, AT, FT.isVolatileQualified(), FD, CurStructOffset);
277
4
      return;
278
4
    }
279
93
280
93
    Super::visitWithKind(PDIK, FT, FD, CurStructOffset);
281
93
  }
282
};
283
284
struct GenDestructorFuncName : GenUnaryFuncName<GenDestructorFuncName>,
285
                               DestructedTypeVisitor<GenDestructorFuncName> {
286
  using Super = DestructedTypeVisitor<GenDestructorFuncName>;
287
  GenDestructorFuncName(const char *Prefix, CharUnits DstAlignment,
288
                        ASTContext &Ctx)
289
103
      : GenUnaryFuncName<GenDestructorFuncName>(Prefix, DstAlignment, Ctx) {}
290
  void visitWithKind(QualType::DestructionKind DK, QualType FT,
291
282
                     const FieldDecl *FD, CharUnits CurStructOffset) {
292
282
    if (const auto *AT = getContext().getAsArrayType(FT)) {
293
20
      visitArray(DK, AT, FT.isVolatileQualified(), FD, CurStructOffset);
294
20
      return;
295
20
    }
296
262
297
262
    Super::visitWithKind(DK, FT, FD, CurStructOffset);
298
262
  }
299
};
300
301
// Helper function that creates CGFunctionInfo for an N-ary special function.
302
template <size_t N>
303
static const CGFunctionInfo &getFunctionInfo(CodeGenModule &CGM,
304
118
                                             FunctionArgList &Args) {
305
118
  ASTContext &Ctx = CGM.getContext();
306
118
  llvm::SmallVector<ImplicitParamDecl *, N> Params;
307
118
  QualType ParamTy = Ctx.getPointerType(Ctx.VoidPtrTy);
308
118
309
298
  for (unsigned I = 0; I < N; 
++I180
)
310
180
    Params.push_back(ImplicitParamDecl::Create(
311
180
        Ctx, nullptr, SourceLocation(), &Ctx.Idents.get(ValNameStr[I]), ParamTy,
312
180
        ImplicitParamDecl::Other));
313
118
314
118
  for (auto &P : Params)
315
180
    Args.push_back(P);
316
118
317
118
  return CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
318
118
}
CGNonTrivialStruct.cpp:clang::CodeGen::CGFunctionInfo const& (anonymous namespace)::getFunctionInfo<1ul>(clang::CodeGen::CodeGenModule&, clang::CodeGen::FunctionArgList&)
Line
Count
Source
304
56
                                             FunctionArgList &Args) {
305
56
  ASTContext &Ctx = CGM.getContext();
306
56
  llvm::SmallVector<ImplicitParamDecl *, N> Params;
307
56
  QualType ParamTy = Ctx.getPointerType(Ctx.VoidPtrTy);
308
56
309
112
  for (unsigned I = 0; I < N; 
++I56
)
310
56
    Params.push_back(ImplicitParamDecl::Create(
311
56
        Ctx, nullptr, SourceLocation(), &Ctx.Idents.get(ValNameStr[I]), ParamTy,
312
56
        ImplicitParamDecl::Other));
313
56
314
56
  for (auto &P : Params)
315
56
    Args.push_back(P);
316
56
317
56
  return CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
318
56
}
CGNonTrivialStruct.cpp:clang::CodeGen::CGFunctionInfo const& (anonymous namespace)::getFunctionInfo<2ul>(clang::CodeGen::CodeGenModule&, clang::CodeGen::FunctionArgList&)
Line
Count
Source
304
62
                                             FunctionArgList &Args) {
305
62
  ASTContext &Ctx = CGM.getContext();
306
62
  llvm::SmallVector<ImplicitParamDecl *, N> Params;
307
62
  QualType ParamTy = Ctx.getPointerType(Ctx.VoidPtrTy);
308
62
309
186
  for (unsigned I = 0; I < N; 
++I124
)
310
124
    Params.push_back(ImplicitParamDecl::Create(
311
124
        Ctx, nullptr, SourceLocation(), &Ctx.Idents.get(ValNameStr[I]), ParamTy,
312
124
        ImplicitParamDecl::Other));
313
62
314
62
  for (auto &P : Params)
315
124
    Args.push_back(P);
316
62
317
62
  return CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
318
62
}
319
320
// Template classes that are used as bases for classes that emit special
321
// functions.
322
template <class Derived> struct GenFuncBase {
323
  template <size_t N>
324
  void visitStruct(QualType FT, const FieldDecl *FD, CharUnits CurStructOffset,
325
64
                   std::array<Address, N> Addrs) {
326
64
    this->asDerived().callSpecialFunction(
327
64
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
64
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::visitStruct<1ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
325
37
                   std::array<Address, N> Addrs) {
326
37
    this->asDerived().callSpecialFunction(
327
37
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
37
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::visitStruct<1ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
325
8
                   std::array<Address, N> Addrs) {
326
8
    this->asDerived().callSpecialFunction(
327
8
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
8
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
325
7
                   std::array<Address, N> Addrs) {
326
7
    this->asDerived().callSpecialFunction(
327
7
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
7
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
325
4
                   std::array<Address, N> Addrs) {
326
4
    this->asDerived().callSpecialFunction(
327
4
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
4
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
325
4
                   std::array<Address, N> Addrs) {
326
4
    this->asDerived().callSpecialFunction(
327
4
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
4
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
325
4
                   std::array<Address, N> Addrs) {
326
4
    this->asDerived().callSpecialFunction(
327
4
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
328
4
  }
329
330
  template <class FieldKind, size_t N>
331
  void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
332
                  const FieldDecl *FD, CharUnits CurStructOffset,
333
28
                  std::array<Address, N> Addrs) {
334
28
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
335
28
    if (!FK)
336
8
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
337
8
                                      Addrs);
338
20
339
20
    asDerived().flushTrivialFields(Addrs);
340
20
    CodeGenFunction &CGF = *this->CGF;
341
20
    ASTContext &Ctx = CGF.getContext();
342
20
343
20
    // Compute the end address.
344
20
    QualType BaseEltQT;
345
20
    std::array<Address, N> StartAddrs = Addrs;
346
46
    for (unsigned I = 0; I < N; 
++I26
)
347
26
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
348
20
    Address DstAddr = StartAddrs[DstIdx];
349
20
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
350
20
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
351
20
    llvm::Value *BaseEltSizeVal =
352
20
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
353
20
    llvm::Value *SizeInBytes =
354
20
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
355
20
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
356
20
    llvm::Value *DstArrayEnd =
357
20
        CGF.Builder.CreateInBoundsGEP(BC.getPointer(), SizeInBytes);
358
20
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
359
20
                                            "dstarray.end");
360
20
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
361
20
362
20
    // Create the header block and insert the phi instructions.
363
20
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
364
20
    CGF.EmitBlock(HeaderBB);
365
20
    llvm::PHINode *PHIs[N];
366
20
367
46
    for (unsigned I = 0; I < N; 
++I26
) {
368
26
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
369
26
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
370
26
    }
371
20
372
20
    // Create the exit and loop body blocks.
373
20
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
374
20
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
375
20
376
20
    // Emit the comparison and conditional branch instruction that jumps to
377
20
    // either the exit or the loop body.
378
20
    llvm::Value *Done =
379
20
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
380
20
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
381
20
382
20
    // Visit the element of the array in the loop body.
383
20
    CGF.EmitBlock(LoopBB);
384
20
    QualType EltQT = AT->getElementType();
385
20
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
386
20
    std::array<Address, N> NewAddrs = Addrs;
387
20
388
46
    for (unsigned I = 0; I < N; 
++I26
)
389
26
      NewAddrs[I] = Address(
390
26
          PHIs[I], StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
391
20
392
20
    EltQT = IsVolatile ? 
EltQT.withVolatile()2
:
EltQT18
;
393
20
    this->asDerived().visitWithKind(FK, EltQT, nullptr, CharUnits::Zero(),
394
20
                                    NewAddrs);
395
20
396
20
    LoopBB = CGF.Builder.GetInsertBlock();
397
20
398
46
    for (unsigned I = 0; I < N; 
++I26
) {
399
26
      // Instrs to update the destination and source addresses.
400
26
      // Update phi instructions.
401
26
      NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
402
26
      PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
403
26
    }
404
20
405
20
    // Insert an unconditional branch to the header block.
406
20
    CGF.Builder.CreateBr(HeaderBB);
407
20
    CGF.EmitBlock(ExitBB);
408
20
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::visitArray<clang::QualType::PrimitiveDefaultInitializeKind, 1ul>(clang::QualType::PrimitiveDefaultInitializeKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
333
6
                  std::array<Address, N> Addrs) {
334
6
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
335
6
    if (!FK)
336
0
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
337
0
                                      Addrs);
338
6
339
6
    asDerived().flushTrivialFields(Addrs);
340
6
    CodeGenFunction &CGF = *this->CGF;
341
6
    ASTContext &Ctx = CGF.getContext();
342
6
343
6
    // Compute the end address.
344
6
    QualType BaseEltQT;
345
6
    std::array<Address, N> StartAddrs = Addrs;
346
12
    for (unsigned I = 0; I < N; 
++I6
)
347
6
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
348
6
    Address DstAddr = StartAddrs[DstIdx];
349
6
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
350
6
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
351
6
    llvm::Value *BaseEltSizeVal =
352
6
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
353
6
    llvm::Value *SizeInBytes =
354
6
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
355
6
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
356
6
    llvm::Value *DstArrayEnd =
357
6
        CGF.Builder.CreateInBoundsGEP(BC.getPointer(), SizeInBytes);
358
6
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
359
6
                                            "dstarray.end");
360
6
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
361
6
362
6
    // Create the header block and insert the phi instructions.
363
6
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
364
6
    CGF.EmitBlock(HeaderBB);
365
6
    llvm::PHINode *PHIs[N];
366
6
367
12
    for (unsigned I = 0; I < N; 
++I6
) {
368
6
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
369
6
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
370
6
    }
371
6
372
6
    // Create the exit and loop body blocks.
373
6
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
374
6
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
375
6
376
6
    // Emit the comparison and conditional branch instruction that jumps to
377
6
    // either the exit or the loop body.
378
6
    llvm::Value *Done =
379
6
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
380
6
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
381
6
382
6
    // Visit the element of the array in the loop body.
383
6
    CGF.EmitBlock(LoopBB);
384
6
    QualType EltQT = AT->getElementType();
385
6
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
386
6
    std::array<Address, N> NewAddrs = Addrs;
387
6
388
12
    for (unsigned I = 0; I < N; 
++I6
)
389
6
      NewAddrs[I] = Address(
390
6
          PHIs[I], StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
391
6
392
6
    EltQT = IsVolatile ? 
EltQT.withVolatile()0
: EltQT;
393
6
    this->asDerived().visitWithKind(FK, EltQT, nullptr, CharUnits::Zero(),
394
6
                                    NewAddrs);
395
6
396
6
    LoopBB = CGF.Builder.GetInsertBlock();
397
6
398
12
    for (unsigned I = 0; I < N; 
++I6
) {
399
6
      // Instrs to update the destination and source addresses.
400
6
      // Update phi instructions.
401
6
      NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
402
6
      PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
403
6
    }
404
6
405
6
    // Insert an unconditional branch to the header block.
406
6
    CGF.Builder.CreateBr(HeaderBB);
407
6
    CGF.EmitBlock(ExitBB);
408
6
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::visitArray<clang::QualType::DestructionKind, 1ul>(clang::QualType::DestructionKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
333
14
                  std::array<Address, N> Addrs) {
334
14
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
335
14
    if (!FK)
336
6
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
337
6
                                      Addrs);
338
8
339
8
    asDerived().flushTrivialFields(Addrs);
340
8
    CodeGenFunction &CGF = *this->CGF;
341
8
    ASTContext &Ctx = CGF.getContext();
342
8
343
8
    // Compute the end address.
344
8
    QualType BaseEltQT;
345
8
    std::array<Address, N> StartAddrs = Addrs;
346
16
    for (unsigned I = 0; I < N; 
++I8
)
347
8
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
348
8
    Address DstAddr = StartAddrs[DstIdx];
349
8
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
350
8
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
351
8
    llvm::Value *BaseEltSizeVal =
352
8
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
353
8
    llvm::Value *SizeInBytes =
354
8
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
355
8
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
356
8
    llvm::Value *DstArrayEnd =
357
8
        CGF.Builder.CreateInBoundsGEP(BC.getPointer(), SizeInBytes);
358
8
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
359
8
                                            "dstarray.end");
360
8
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
361
8
362
8
    // Create the header block and insert the phi instructions.
363
8
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
364
8
    CGF.EmitBlock(HeaderBB);
365
8
    llvm::PHINode *PHIs[N];
366
8
367
16
    for (unsigned I = 0; I < N; 
++I8
) {
368
8
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
369
8
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
370
8
    }
371
8
372
8
    // Create the exit and loop body blocks.
373
8
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
374
8
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
375
8
376
8
    // Emit the comparison and conditional branch instruction that jumps to
377
8
    // either the exit or the loop body.
378
8
    llvm::Value *Done =
379
8
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
380
8
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
381
8
382
8
    // Visit the element of the array in the loop body.
383
8
    CGF.EmitBlock(LoopBB);
384
8
    QualType EltQT = AT->getElementType();
385
8
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
386
8
    std::array<Address, N> NewAddrs = Addrs;
387
8
388
16
    for (unsigned I = 0; I < N; 
++I8
)
389
8
      NewAddrs[I] = Address(
390
8
          PHIs[I], StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
391
8
392
8
    EltQT = IsVolatile ? 
EltQT.withVolatile()0
: EltQT;
393
8
    this->asDerived().visitWithKind(FK, EltQT, nullptr, CharUnits::Zero(),
394
8
                                    NewAddrs);
395
8
396
8
    LoopBB = CGF.Builder.GetInsertBlock();
397
8
398
16
    for (unsigned I = 0; I < N; 
++I8
) {
399
8
      // Instrs to update the destination and source addresses.
400
8
      // Update phi instructions.
401
8
      NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
402
8
      PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
403
8
    }
404
8
405
8
    // Insert an unconditional branch to the header block.
406
8
    CGF.Builder.CreateBr(HeaderBB);
407
8
    CGF.EmitBlock(ExitBB);
408
8
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::visitArray<clang::QualType::PrimitiveCopyKind, 2ul>(clang::QualType::PrimitiveCopyKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
333
8
                  std::array<Address, N> Addrs) {
334
8
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
335
8
    if (!FK)
336
2
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
337
2
                                      Addrs);
338
6
339
6
    asDerived().flushTrivialFields(Addrs);
340
6
    CodeGenFunction &CGF = *this->CGF;
341
6
    ASTContext &Ctx = CGF.getContext();
342
6
343
6
    // Compute the end address.
344
6
    QualType BaseEltQT;
345
6
    std::array<Address, N> StartAddrs = Addrs;
346
18
    for (unsigned I = 0; I < N; 
++I12
)
347
12
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
348
6
    Address DstAddr = StartAddrs[DstIdx];
349
6
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
350
6
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
351
6
    llvm::Value *BaseEltSizeVal =
352
6
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
353
6
    llvm::Value *SizeInBytes =
354
6
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
355
6
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
356
6
    llvm::Value *DstArrayEnd =
357
6
        CGF.Builder.CreateInBoundsGEP(BC.getPointer(), SizeInBytes);
358
6
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
359
6
                                            "dstarray.end");
360
6
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
361
6
362
6
    // Create the header block and insert the phi instructions.
363
6
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
364
6
    CGF.EmitBlock(HeaderBB);
365
6
    llvm::PHINode *PHIs[N];
366
6
367
18
    for (unsigned I = 0; I < N; 
++I12
) {
368
12
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
369
12
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
370
12
    }
371
6
372
6
    // Create the exit and loop body blocks.
373
6
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
374
6
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
375
6
376
6
    // Emit the comparison and conditional branch instruction that jumps to
377
6
    // either the exit or the loop body.
378
6
    llvm::Value *Done =
379
6
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
380
6
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
381
6
382
6
    // Visit the element of the array in the loop body.
383
6
    CGF.EmitBlock(LoopBB);
384
6
    QualType EltQT = AT->getElementType();
385
6
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
386
6
    std::array<Address, N> NewAddrs = Addrs;
387
6
388
18
    for (unsigned I = 0; I < N; 
++I12
)
389
12
      NewAddrs[I] = Address(
390
12
          PHIs[I], StartAddrs[I].getAlignment().alignmentAtOffset(EltSize));
391
6
392
6
    EltQT = IsVolatile ? 
EltQT.withVolatile()2
:
EltQT4
;
393
6
    this->asDerived().visitWithKind(FK, EltQT, nullptr, CharUnits::Zero(),
394
6
                                    NewAddrs);
395
6
396
6
    LoopBB = CGF.Builder.GetInsertBlock();
397
6
398
18
    for (unsigned I = 0; I < N; 
++I12
) {
399
12
      // Instrs to update the destination and source addresses.
400
12
      // Update phi instructions.
401
12
      NewAddrs[I] = getAddrWithOffset(NewAddrs[I], EltSize);
402
12
      PHIs[I]->addIncoming(NewAddrs[I].getPointer(), LoopBB);
403
12
    }
404
6
405
6
    // Insert an unconditional branch to the header block.
406
6
    CGF.Builder.CreateBr(HeaderBB);
407
6
    CGF.EmitBlock(ExitBB);
408
6
  }
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::visitArray<clang::QualType::PrimitiveCopyKind, 2ul>(clang::QualType::PrimitiveCopyKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::visitArray<clang::QualType::PrimitiveCopyKind, 2ul>(clang::QualType::PrimitiveCopyKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::visitArray<clang::QualType::PrimitiveCopyKind, 2ul>(clang::QualType::PrimitiveCopyKind, clang::ArrayType const*, bool, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
409
410
  /// Return an address with the specified offset from the passed address.
411
427
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
427
    assert(Addr.isValid() && "invalid address");
413
427
    if (Offset.getQuantity() == 0)
414
206
      return Addr;
415
221
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
221
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
221
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
221
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits)
Line
Count
Source
411
65
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
65
    assert(Addr.isValid() && "invalid address");
413
65
    if (Offset.getQuantity() == 0)
414
44
      return Addr;
415
21
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
21
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
21
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
21
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits)
Line
Count
Source
411
64
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
64
    assert(Addr.isValid() && "invalid address");
413
64
    if (Offset.getQuantity() == 0)
414
22
      return Addr;
415
42
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
42
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
42
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
42
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits)
Line
Count
Source
411
158
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
158
    assert(Addr.isValid() && "invalid address");
413
158
    if (Offset.getQuantity() == 0)
414
74
      return Addr;
415
84
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
84
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
84
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
84
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits)
Line
Count
Source
411
48
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
48
    assert(Addr.isValid() && "invalid address");
413
48
    if (Offset.getQuantity() == 0)
414
24
      return Addr;
415
24
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
24
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
24
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
24
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits)
Line
Count
Source
411
48
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
48
    assert(Addr.isValid() && "invalid address");
413
48
    if (Offset.getQuantity() == 0)
414
22
      return Addr;
415
26
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
26
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
26
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
26
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits)
Line
Count
Source
411
44
  Address getAddrWithOffset(Address Addr, CharUnits Offset) {
412
44
    assert(Addr.isValid() && "invalid address");
413
44
    if (Offset.getQuantity() == 0)
414
20
      return Addr;
415
24
    Addr = CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
416
24
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
417
24
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
418
24
  }
419
420
  Address getAddrWithOffset(Address Addr, CharUnits StructFieldOffset,
421
210
                            const FieldDecl *FD) {
422
210
    return getAddrWithOffset(Addr, StructFieldOffset +
423
210
                                       asDerived().getFieldOffset(FD));
424
210
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits, clang::FieldDecl const*)
Line
Count
Source
421
22
                            const FieldDecl *FD) {
422
22
    return getAddrWithOffset(Addr, StructFieldOffset +
423
22
                                       asDerived().getFieldOffset(FD));
424
22
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits, clang::FieldDecl const*)
Line
Count
Source
421
48
                            const FieldDecl *FD) {
422
48
    return getAddrWithOffset(Addr, StructFieldOffset +
423
48
                                       asDerived().getFieldOffset(FD));
424
48
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits, clang::FieldDecl const*)
Line
Count
Source
421
72
                            const FieldDecl *FD) {
422
72
    return getAddrWithOffset(Addr, StructFieldOffset +
423
72
                                       asDerived().getFieldOffset(FD));
424
72
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits, clang::FieldDecl const*)
Line
Count
Source
421
24
                            const FieldDecl *FD) {
422
24
    return getAddrWithOffset(Addr, StructFieldOffset +
423
24
                                       asDerived().getFieldOffset(FD));
424
24
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits, clang::FieldDecl const*)
Line
Count
Source
421
24
                            const FieldDecl *FD) {
422
24
    return getAddrWithOffset(Addr, StructFieldOffset +
423
24
                                       asDerived().getFieldOffset(FD));
424
24
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::getAddrWithOffset(clang::CodeGen::Address, clang::CharUnits, clang::FieldDecl const*)
Line
Count
Source
421
20
                            const FieldDecl *FD) {
422
20
    return getAddrWithOffset(Addr, StructFieldOffset +
423
20
                                       asDerived().getFieldOffset(FD));
424
20
  }
425
426
  template <size_t N>
427
  llvm::Function *
428
  getFunction(StringRef FuncName, QualType QT, std::array<Address, N> Addrs,
429
226
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
226
    // If the special function already exists in the module, return it.
431
226
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
108
      bool WrongType = false;
433
108
      if (!F->getReturnType()->isVoidTy())
434
1
        WrongType = true;
435
107
      else {
436
107
        for (const llvm::Argument &Arg : F->args())
437
133
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
107
      }
440
108
441
108
      if (WrongType) {
442
1
        std::string FuncName = F->getName();
443
1
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
1
        CGM.Error(Loc, "special function " + FuncName +
445
1
                           " for non-trivial C struct has incorrect type");
446
1
        return nullptr;
447
1
      }
448
107
      return F;
449
107
    }
450
118
451
118
    ASTContext &Ctx = CGM.getContext();
452
118
    FunctionArgList Args;
453
118
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
118
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
118
    llvm::Function *F =
456
118
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
118
                               FuncName, &CGM.getModule());
458
118
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
118
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
118
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
118
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
118
    FunctionDecl *FD = FunctionDecl::Create(
463
118
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
118
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
118
        SC_PrivateExtern, false, false);
466
118
    CodeGenFunction NewCGF(CGM);
467
118
    setCGF(&NewCGF);
468
118
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
118
470
298
    for (unsigned I = 0; I < N; 
++I180
) {
471
180
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
180
      Addrs[I] = Address(V, Alignments[I]);
473
180
    }
474
118
475
118
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
118
    CGF->FinishFunction();
477
118
    return F;
478
118
  }
CGNonTrivialStruct.cpp:llvm::Function* (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::getFunction<1ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 1ul>, std::__1::array<clang::CharUnits, 1ul>, clang::CodeGen::CodeGenModule&)
Line
Count
Source
429
37
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
37
    // If the special function already exists in the module, return it.
431
37
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
20
      bool WrongType = false;
433
20
      if (!F->getReturnType()->isVoidTy())
434
1
        WrongType = true;
435
19
      else {
436
19
        for (const llvm::Argument &Arg : F->args())
437
19
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
19
      }
440
20
441
20
      if (WrongType) {
442
1
        std::string FuncName = F->getName();
443
1
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
1
        CGM.Error(Loc, "special function " + FuncName +
445
1
                           " for non-trivial C struct has incorrect type");
446
1
        return nullptr;
447
1
      }
448
19
      return F;
449
19
    }
450
17
451
17
    ASTContext &Ctx = CGM.getContext();
452
17
    FunctionArgList Args;
453
17
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
17
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
17
    llvm::Function *F =
456
17
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
17
                               FuncName, &CGM.getModule());
458
17
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
17
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
17
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
17
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
17
    FunctionDecl *FD = FunctionDecl::Create(
463
17
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
17
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
17
        SC_PrivateExtern, false, false);
466
17
    CodeGenFunction NewCGF(CGM);
467
17
    setCGF(&NewCGF);
468
17
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
17
470
34
    for (unsigned I = 0; I < N; 
++I17
) {
471
17
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
17
      Addrs[I] = Address(V, Alignments[I]);
473
17
    }
474
17
475
17
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
17
    CGF->FinishFunction();
477
17
    return F;
478
17
  }
CGNonTrivialStruct.cpp:llvm::Function* (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::getFunction<1ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 1ul>, std::__1::array<clang::CharUnits, 1ul>, clang::CodeGen::CodeGenModule&)
Line
Count
Source
429
101
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
101
    // If the special function already exists in the module, return it.
431
101
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
62
      bool WrongType = false;
433
62
      if (!F->getReturnType()->isVoidTy())
434
0
        WrongType = true;
435
62
      else {
436
62
        for (const llvm::Argument &Arg : F->args())
437
62
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
62
      }
440
62
441
62
      if (WrongType) {
442
0
        std::string FuncName = F->getName();
443
0
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
0
        CGM.Error(Loc, "special function " + FuncName +
445
0
                           " for non-trivial C struct has incorrect type");
446
0
        return nullptr;
447
0
      }
448
62
      return F;
449
62
    }
450
39
451
39
    ASTContext &Ctx = CGM.getContext();
452
39
    FunctionArgList Args;
453
39
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
39
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
39
    llvm::Function *F =
456
39
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
39
                               FuncName, &CGM.getModule());
458
39
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
39
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
39
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
39
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
39
    FunctionDecl *FD = FunctionDecl::Create(
463
39
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
39
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
39
        SC_PrivateExtern, false, false);
466
39
    CodeGenFunction NewCGF(CGM);
467
39
    setCGF(&NewCGF);
468
39
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
39
470
78
    for (unsigned I = 0; I < N; 
++I39
) {
471
39
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
39
      Addrs[I] = Address(V, Alignments[I]);
473
39
    }
474
39
475
39
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
39
    CGF->FinishFunction();
477
39
    return F;
478
39
  }
CGNonTrivialStruct.cpp:llvm::Function* (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::getFunction<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Line
Count
Source
429
49
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
49
    // If the special function already exists in the module, return it.
431
49
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
20
      bool WrongType = false;
433
20
      if (!F->getReturnType()->isVoidTy())
434
0
        WrongType = true;
435
20
      else {
436
20
        for (const llvm::Argument &Arg : F->args())
437
40
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
20
      }
440
20
441
20
      if (WrongType) {
442
0
        std::string FuncName = F->getName();
443
0
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
0
        CGM.Error(Loc, "special function " + FuncName +
445
0
                           " for non-trivial C struct has incorrect type");
446
0
        return nullptr;
447
0
      }
448
20
      return F;
449
20
    }
450
29
451
29
    ASTContext &Ctx = CGM.getContext();
452
29
    FunctionArgList Args;
453
29
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
29
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
29
    llvm::Function *F =
456
29
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
29
                               FuncName, &CGM.getModule());
458
29
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
29
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
29
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
29
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
29
    FunctionDecl *FD = FunctionDecl::Create(
463
29
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
29
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
29
        SC_PrivateExtern, false, false);
466
29
    CodeGenFunction NewCGF(CGM);
467
29
    setCGF(&NewCGF);
468
29
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
29
470
87
    for (unsigned I = 0; I < N; 
++I58
) {
471
58
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
58
      Addrs[I] = Address(V, Alignments[I]);
473
58
    }
474
29
475
29
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
29
    CGF->FinishFunction();
477
29
    return F;
478
29
  }
CGNonTrivialStruct.cpp:llvm::Function* (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::getFunction<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Line
Count
Source
429
14
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
14
    // If the special function already exists in the module, return it.
431
14
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
2
      bool WrongType = false;
433
2
      if (!F->getReturnType()->isVoidTy())
434
0
        WrongType = true;
435
2
      else {
436
2
        for (const llvm::Argument &Arg : F->args())
437
4
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
2
      }
440
2
441
2
      if (WrongType) {
442
0
        std::string FuncName = F->getName();
443
0
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
0
        CGM.Error(Loc, "special function " + FuncName +
445
0
                           " for non-trivial C struct has incorrect type");
446
0
        return nullptr;
447
0
      }
448
2
      return F;
449
2
    }
450
12
451
12
    ASTContext &Ctx = CGM.getContext();
452
12
    FunctionArgList Args;
453
12
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
12
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
12
    llvm::Function *F =
456
12
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
12
                               FuncName, &CGM.getModule());
458
12
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
12
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
12
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
12
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
12
    FunctionDecl *FD = FunctionDecl::Create(
463
12
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
12
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
12
        SC_PrivateExtern, false, false);
466
12
    CodeGenFunction NewCGF(CGM);
467
12
    setCGF(&NewCGF);
468
12
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
12
470
36
    for (unsigned I = 0; I < N; 
++I24
) {
471
24
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
24
      Addrs[I] = Address(V, Alignments[I]);
473
24
    }
474
12
475
12
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
12
    CGF->FinishFunction();
477
12
    return F;
478
12
  }
CGNonTrivialStruct.cpp:llvm::Function* (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::getFunction<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Line
Count
Source
429
13
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
13
    // If the special function already exists in the module, return it.
431
13
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
2
      bool WrongType = false;
433
2
      if (!F->getReturnType()->isVoidTy())
434
0
        WrongType = true;
435
2
      else {
436
2
        for (const llvm::Argument &Arg : F->args())
437
4
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
2
      }
440
2
441
2
      if (WrongType) {
442
0
        std::string FuncName = F->getName();
443
0
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
0
        CGM.Error(Loc, "special function " + FuncName +
445
0
                           " for non-trivial C struct has incorrect type");
446
0
        return nullptr;
447
0
      }
448
2
      return F;
449
2
    }
450
11
451
11
    ASTContext &Ctx = CGM.getContext();
452
11
    FunctionArgList Args;
453
11
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
11
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
11
    llvm::Function *F =
456
11
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
11
                               FuncName, &CGM.getModule());
458
11
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
11
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
11
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
11
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
11
    FunctionDecl *FD = FunctionDecl::Create(
463
11
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
11
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
11
        SC_PrivateExtern, false, false);
466
11
    CodeGenFunction NewCGF(CGM);
467
11
    setCGF(&NewCGF);
468
11
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
11
470
33
    for (unsigned I = 0; I < N; 
++I22
) {
471
22
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
22
      Addrs[I] = Address(V, Alignments[I]);
473
22
    }
474
11
475
11
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
11
    CGF->FinishFunction();
477
11
    return F;
478
11
  }
CGNonTrivialStruct.cpp:llvm::Function* (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::getFunction<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Line
Count
Source
429
12
              std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
430
12
    // If the special function already exists in the module, return it.
431
12
    if (llvm::Function *F = CGM.getModule().getFunction(FuncName)) {
432
2
      bool WrongType = false;
433
2
      if (!F->getReturnType()->isVoidTy())
434
0
        WrongType = true;
435
2
      else {
436
2
        for (const llvm::Argument &Arg : F->args())
437
4
          if (Arg.getType() != CGM.Int8PtrPtrTy)
438
0
            WrongType = true;
439
2
      }
440
2
441
2
      if (WrongType) {
442
0
        std::string FuncName = F->getName();
443
0
        SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
444
0
        CGM.Error(Loc, "special function " + FuncName +
445
0
                           " for non-trivial C struct has incorrect type");
446
0
        return nullptr;
447
0
      }
448
2
      return F;
449
2
    }
450
10
451
10
    ASTContext &Ctx = CGM.getContext();
452
10
    FunctionArgList Args;
453
10
    const CGFunctionInfo &FI = getFunctionInfo<N>(CGM, Args);
454
10
    llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
455
10
    llvm::Function *F =
456
10
        llvm::Function::Create(FuncTy, llvm::GlobalValue::LinkOnceODRLinkage,
457
10
                               FuncName, &CGM.getModule());
458
10
    F->setVisibility(llvm::GlobalValue::HiddenVisibility);
459
10
    CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F);
460
10
    CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
461
10
    IdentifierInfo *II = &Ctx.Idents.get(FuncName);
462
10
    FunctionDecl *FD = FunctionDecl::Create(
463
10
        Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(),
464
10
        II, Ctx.getFunctionType(Ctx.VoidTy, llvm::None, {}), nullptr,
465
10
        SC_PrivateExtern, false, false);
466
10
    CodeGenFunction NewCGF(CGM);
467
10
    setCGF(&NewCGF);
468
10
    CGF->StartFunction(FD, Ctx.VoidTy, F, FI, Args);
469
10
470
30
    for (unsigned I = 0; I < N; 
++I20
) {
471
20
      llvm::Value *V = CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[I]));
472
20
      Addrs[I] = Address(V, Alignments[I]);
473
20
    }
474
10
475
10
    asDerived().visitStructFields(QT, CharUnits::Zero(), Addrs);
476
10
    CGF->FinishFunction();
477
10
    return F;
478
10
  }
479
480
  template <size_t N>
481
  void callFunc(StringRef FuncName, QualType QT, std::array<Address, N> Addrs,
482
226
                CodeGenFunction &CallerCGF) {
483
226
    std::array<CharUnits, N> Alignments;
484
226
    llvm::Value *Ptrs[N];
485
226
486
540
    for (unsigned I = 0; I < N; 
++I314
) {
487
314
      Alignments[I] = Addrs[I].getAlignment();
488
314
      Ptrs[I] =
489
314
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
314
              .getPointer();
491
314
    }
492
226
493
226
    if (llvm::Function *F =
494
225
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
225
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
226
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::callFunc<1ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 1ul>, clang::CodeGen::CodeGenFunction&)
Line
Count
Source
482
37
                CodeGenFunction &CallerCGF) {
483
37
    std::array<CharUnits, N> Alignments;
484
37
    llvm::Value *Ptrs[N];
485
37
486
74
    for (unsigned I = 0; I < N; 
++I37
) {
487
37
      Alignments[I] = Addrs[I].getAlignment();
488
37
      Ptrs[I] =
489
37
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
37
              .getPointer();
491
37
    }
492
37
493
37
    if (llvm::Function *F =
494
36
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
36
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
37
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::callFunc<1ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 1ul>, clang::CodeGen::CodeGenFunction&)
Line
Count
Source
482
101
                CodeGenFunction &CallerCGF) {
483
101
    std::array<CharUnits, N> Alignments;
484
101
    llvm::Value *Ptrs[N];
485
101
486
202
    for (unsigned I = 0; I < N; 
++I101
) {
487
101
      Alignments[I] = Addrs[I].getAlignment();
488
101
      Ptrs[I] =
489
101
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
101
              .getPointer();
491
101
    }
492
101
493
101
    if (llvm::Function *F =
494
101
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
101
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
101
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::callFunc<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, clang::CodeGen::CodeGenFunction&)
Line
Count
Source
482
49
                CodeGenFunction &CallerCGF) {
483
49
    std::array<CharUnits, N> Alignments;
484
49
    llvm::Value *Ptrs[N];
485
49
486
147
    for (unsigned I = 0; I < N; 
++I98
) {
487
98
      Alignments[I] = Addrs[I].getAlignment();
488
98
      Ptrs[I] =
489
98
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
98
              .getPointer();
491
98
    }
492
49
493
49
    if (llvm::Function *F =
494
49
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
49
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
49
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::callFunc<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, clang::CodeGen::CodeGenFunction&)
Line
Count
Source
482
14
                CodeGenFunction &CallerCGF) {
483
14
    std::array<CharUnits, N> Alignments;
484
14
    llvm::Value *Ptrs[N];
485
14
486
42
    for (unsigned I = 0; I < N; 
++I28
) {
487
28
      Alignments[I] = Addrs[I].getAlignment();
488
28
      Ptrs[I] =
489
28
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
28
              .getPointer();
491
28
    }
492
14
493
14
    if (llvm::Function *F =
494
14
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
14
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
14
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::callFunc<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, clang::CodeGen::CodeGenFunction&)
Line
Count
Source
482
13
                CodeGenFunction &CallerCGF) {
483
13
    std::array<CharUnits, N> Alignments;
484
13
    llvm::Value *Ptrs[N];
485
13
486
39
    for (unsigned I = 0; I < N; 
++I26
) {
487
26
      Alignments[I] = Addrs[I].getAlignment();
488
26
      Ptrs[I] =
489
26
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
26
              .getPointer();
491
26
    }
492
13
493
13
    if (llvm::Function *F =
494
13
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
13
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
13
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::callFunc<2ul>(llvm::StringRef, clang::QualType, std::__1::array<clang::CodeGen::Address, 2ul>, clang::CodeGen::CodeGenFunction&)
Line
Count
Source
482
12
                CodeGenFunction &CallerCGF) {
483
12
    std::array<CharUnits, N> Alignments;
484
12
    llvm::Value *Ptrs[N];
485
12
486
36
    for (unsigned I = 0; I < N; 
++I24
) {
487
24
      Alignments[I] = Addrs[I].getAlignment();
488
24
      Ptrs[I] =
489
24
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
490
24
              .getPointer();
491
24
    }
492
12
493
12
    if (llvm::Function *F =
494
12
            getFunction(FuncName, QT, Addrs, Alignments, CallerCGF.CGM))
495
12
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
496
12
  }
497
498
504
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::asDerived()
Line
Count
Source
498
125
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::asDerived()
Line
Count
Source
498
125
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::asDerived()
Line
Count
Source
498
129
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::asDerived()
Line
Count
Source
498
44
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::asDerived()
Line
Count
Source
498
43
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::asDerived()
Line
Count
Source
498
38
  Derived &asDerived() { return static_cast<Derived &>(*this); }
499
500
149
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
500
48
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
500
39
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
500
29
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
500
12
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
500
11
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
500
10
  void setCGF(CodeGenFunction *F) { CGF = F; }
501
502
  CodeGenFunction *CGF = nullptr;
503
};
504
505
template <class Derived, bool IsMove>
506
struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
507
                       GenFuncBase<Derived> {
508
88
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyConstructor, false>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
508
49
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyAssignment, false>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
508
14
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveConstructor, true>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
508
13
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveAssignment, true>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
508
12
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
509
510
159
  void flushTrivialFields(std::array<Address, 2> Addrs) {
511
159
    CharUnits Size = this->End - this->Start;
512
159
513
159
    if (Size.getQuantity() == 0)
514
111
      return;
515
48
516
48
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
517
48
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
518
48
519
48
    // Emit memcpy.
520
48
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())40
) {
521
12
      llvm::Value *SizeVal =
522
12
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
523
12
      DstAddr =
524
12
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
525
12
      SrcAddr =
526
12
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
527
12
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
528
36
    } else {
529
36
      llvm::Type *Ty = llvm::Type::getIntNTy(
530
36
          this->CGF->getLLVMContext(),
531
36
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
532
36
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
533
36
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
534
36
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
535
36
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
536
36
    }
537
48
538
48
    this->Start = this->End = CharUnits::Zero();
539
48
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyConstructor, false>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
510
80
  void flushTrivialFields(std::array<Address, 2> Addrs) {
511
80
    CharUnits Size = this->End - this->Start;
512
80
513
80
    if (Size.getQuantity() == 0)
514
56
      return;
515
24
516
24
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
517
24
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
518
24
519
24
    // Emit memcpy.
520
24
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())22
) {
521
6
      llvm::Value *SizeVal =
522
6
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
523
6
      DstAddr =
524
6
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
525
6
      SrcAddr =
526
6
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
527
6
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
528
18
    } else {
529
18
      llvm::Type *Ty = llvm::Type::getIntNTy(
530
18
          this->CGF->getLLVMContext(),
531
18
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
532
18
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
533
18
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
534
18
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
535
18
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
536
18
    }
537
24
538
24
    this->Start = this->End = CharUnits::Zero();
539
24
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyAssignment, false>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
510
28
  void flushTrivialFields(std::array<Address, 2> Addrs) {
511
28
    CharUnits Size = this->End - this->Start;
512
28
513
28
    if (Size.getQuantity() == 0)
514
20
      return;
515
8
516
8
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
517
8
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
518
8
519
8
    // Emit memcpy.
520
8
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())6
) {
521
2
      llvm::Value *SizeVal =
522
2
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
523
2
      DstAddr =
524
2
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
525
2
      SrcAddr =
526
2
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
527
2
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
528
6
    } else {
529
6
      llvm::Type *Ty = llvm::Type::getIntNTy(
530
6
          this->CGF->getLLVMContext(),
531
6
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
532
6
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
533
6
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
534
6
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
535
6
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
536
6
    }
537
8
538
8
    this->Start = this->End = CharUnits::Zero();
539
8
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveConstructor, true>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
510
27
  void flushTrivialFields(std::array<Address, 2> Addrs) {
511
27
    CharUnits Size = this->End - this->Start;
512
27
513
27
    if (Size.getQuantity() == 0)
514
19
      return;
515
8
516
8
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
517
8
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
518
8
519
8
    // Emit memcpy.
520
8
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())6
) {
521
2
      llvm::Value *SizeVal =
522
2
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
523
2
      DstAddr =
524
2
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
525
2
      SrcAddr =
526
2
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
527
2
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
528
6
    } else {
529
6
      llvm::Type *Ty = llvm::Type::getIntNTy(
530
6
          this->CGF->getLLVMContext(),
531
6
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
532
6
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
533
6
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
534
6
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
535
6
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
536
6
    }
537
8
538
8
    this->Start = this->End = CharUnits::Zero();
539
8
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveAssignment, true>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
510
24
  void flushTrivialFields(std::array<Address, 2> Addrs) {
511
24
    CharUnits Size = this->End - this->Start;
512
24
513
24
    if (Size.getQuantity() == 0)
514
16
      return;
515
8
516
8
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
517
8
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
518
8
519
8
    // Emit memcpy.
520
8
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())6
) {
521
2
      llvm::Value *SizeVal =
522
2
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
523
2
      DstAddr =
524
2
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
525
2
      SrcAddr =
526
2
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
527
2
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
528
6
    } else {
529
6
      llvm::Type *Ty = llvm::Type::getIntNTy(
530
6
          this->CGF->getLLVMContext(),
531
6
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
532
6
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
533
6
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
534
6
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
535
6
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
536
6
    }
537
8
538
8
    this->Start = this->End = CharUnits::Zero();
539
8
  }
540
541
  template <class... Ts>
542
  void visitVolatileTrivial(QualType FT, const FieldDecl *FD, CharUnits Offset,
543
8
                            std::array<Address, 2> Addrs) {
544
8
    LValue DstLV, SrcLV;
545
8
    if (FD) {
546
6
      QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
547
6
      llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
548
6
      Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
549
6
      LValue DstBase = this->CGF->MakeAddrLValue(
550
6
          this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
551
6
      DstLV = this->CGF->EmitLValueForField(DstBase, FD);
552
6
      Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
553
6
      LValue SrcBase = this->CGF->MakeAddrLValue(
554
6
          this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
555
6
      SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
556
6
    } else {
557
2
      llvm::PointerType *Ty = this->CGF->ConvertType(FT)->getPointerTo();
558
2
      Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
559
2
      Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
560
2
      DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
561
2
      SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
562
2
    }
563
8
    RValue SrcVal = this->CGF->EmitLoadOfLValue(SrcLV, SourceLocation());
564
8
    this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
565
8
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyConstructor, false>::visitVolatileTrivial<>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
543
8
                            std::array<Address, 2> Addrs) {
544
8
    LValue DstLV, SrcLV;
545
8
    if (FD) {
546
6
      QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
547
6
      llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
548
6
      Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
549
6
      LValue DstBase = this->CGF->MakeAddrLValue(
550
6
          this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
551
6
      DstLV = this->CGF->EmitLValueForField(DstBase, FD);
552
6
      Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
553
6
      LValue SrcBase = this->CGF->MakeAddrLValue(
554
6
          this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
555
6
      SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
556
6
    } else {
557
2
      llvm::PointerType *Ty = this->CGF->ConvertType(FT)->getPointerTo();
558
2
      Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
559
2
      Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
560
2
      DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
561
2
      SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
562
2
    }
563
8
    RValue SrcVal = this->CGF->EmitLoadOfLValue(SrcLV, SourceLocation());
564
8
    this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
565
8
  }
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyAssignment, false>::visitVolatileTrivial<>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveConstructor, true>::visitVolatileTrivial<>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Unexecuted instantiation: CGNonTrivialStruct.cpp:void (anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveAssignment, true>::visitVolatileTrivial<>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
566
};
567
568
// These classes that emit the special functions for a non-trivial struct.
569
struct GenDestructor : StructVisitor<GenDestructor>,
570
                       GenFuncBase<GenDestructor>,
571
                       DestructedTypeVisitor<GenDestructor> {
572
  using Super = DestructedTypeVisitor<GenDestructor>;
573
101
  GenDestructor(ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
574
575
  void visitWithKind(QualType::DestructionKind DK, QualType FT,
576
                     const FieldDecl *FD, CharUnits CurStructOffset,
577
105
                     std::array<Address, 1> Addrs) {
578
105
    if (const auto *AT = getContext().getAsArrayType(FT)) {
579
14
      visitArray(DK, AT, FT.isVolatileQualified(), FD, CurStructOffset, Addrs);
580
14
      return;
581
14
    }
582
91
583
91
    Super::visitWithKind(DK, FT, FD, CurStructOffset, Addrs);
584
91
  }
585
586
  void visitARCStrong(QualType QT, const FieldDecl *FD,
587
34
                      CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
588
34
    CGF->destroyARCStrongImprecise(
589
34
        *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
590
34
  }
591
592
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
593
6
                    std::array<Address, 1> Addrs) {
594
6
    CGF->destroyARCWeak(
595
6
        *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
596
6
  }
597
598
  void callSpecialFunction(QualType FT, CharUnits Offset,
599
8
                           std::array<Address, 1> Addrs) {
600
8
    CGF->callCStructDestructor(
601
8
        CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
602
8
  }
603
};
604
605
struct GenDefaultInitialize
606
    : StructVisitor<GenDefaultInitialize>,
607
      GenFuncBase<GenDefaultInitialize>,
608
      DefaultInitializedTypeVisitor<GenDefaultInitialize> {
609
  using Super = DefaultInitializedTypeVisitor<GenDefaultInitialize>;
610
  typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
611
612
  GenDefaultInitialize(ASTContext &Ctx)
613
68
      : StructVisitor<GenDefaultInitialize>(Ctx) {}
614
615
  void visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType FT,
616
                     const FieldDecl *FD, CharUnits CurStructOffset,
617
71
                     std::array<Address, 1> Addrs) {
618
71
    if (const auto *AT = getContext().getAsArrayType(FT)) {
619
8
      visitArray(PDIK, AT, FT.isVolatileQualified(), FD, CurStructOffset,
620
8
                 Addrs);
621
8
      return;
622
8
    }
623
63
624
63
    Super::visitWithKind(PDIK, FT, FD, CurStructOffset, Addrs);
625
63
  }
626
627
  void visitARCStrong(QualType QT, const FieldDecl *FD,
628
9
                      CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
629
9
    CGF->EmitNullInitialization(
630
9
        getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
631
9
  }
632
633
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
634
5
                    std::array<Address, 1> Addrs) {
635
5
    CGF->EmitNullInitialization(
636
5
        getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
637
5
  }
638
639
  template <class FieldKind, size_t... Is>
640
  void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
641
                  const FieldDecl *FD, CharUnits CurStructOffset,
642
8
                  std::array<Address, 1> Addrs) {
643
8
    if (!FK)
644
0
      return visitTrivial(QualType(AT, 0), FD, CurStructOffset, Addrs);
645
8
646
8
    ASTContext &Ctx = getContext();
647
8
    CharUnits Size = Ctx.getTypeSizeInChars(QualType(AT, 0));
648
8
    QualType EltTy = Ctx.getBaseElementType(QualType(AT, 0));
649
8
650
8
    if (Size < CharUnits::fromQuantity(16) || 
EltTy->getAs<RecordType>()6
) {
651
6
      GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
652
6
      return;
653
6
    }
654
2
655
2
    llvm::Constant *SizeVal = CGF->Builder.getInt64(Size.getQuantity());
656
2
    Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
657
2
    Address Loc = CGF->Builder.CreateElementBitCast(DstAddr, CGF->Int8Ty);
658
2
    CGF->Builder.CreateMemSet(Loc, CGF->Builder.getInt8(0), SizeVal,
659
2
                              IsVolatile);
660
2
  }
661
662
  void callSpecialFunction(QualType FT, CharUnits Offset,
663
37
                           std::array<Address, 1> Addrs) {
664
37
    CGF->callCStructDefaultConstructor(
665
37
        CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
666
37
  }
667
};
668
669
struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
670
  GenCopyConstructor(ASTContext &Ctx)
671
49
      : GenBinaryFunc<GenCopyConstructor, false>(Ctx) {}
672
673
  void visitARCStrong(QualType QT, const FieldDecl *FD,
674
25
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
675
25
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
676
25
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
677
25
    llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
678
25
        Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
679
25
    llvm::Value *Val = CGF->EmitARCRetain(QT, SrcVal);
680
25
    CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT), true);
681
25
  }
682
683
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
684
5
                    std::array<Address, 2> Addrs) {
685
5
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
686
5
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
687
5
    CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
688
5
  }
689
690
  void callSpecialFunction(QualType FT, CharUnits Offset,
691
7
                           std::array<Address, 2> Addrs) {
692
7
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
693
7
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
694
7
    CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
695
7
                                    CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
696
7
  }
697
};
698
699
struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
700
  GenMoveConstructor(ASTContext &Ctx)
701
13
      : GenBinaryFunc<GenMoveConstructor, true>(Ctx) {}
702
703
  void visitARCStrong(QualType QT, const FieldDecl *FD,
704
8
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
705
8
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
706
8
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
707
8
    LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
708
8
    llvm::Value *SrcVal =
709
8
        CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
710
8
    CGF->EmitStoreOfScalar(getNullForVariable(SrcLV.getAddress()), SrcLV);
711
8
    CGF->EmitStoreOfScalar(SrcVal, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
712
8
                           /* isInitialization */ true);
713
8
  }
714
715
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
716
4
                    std::array<Address, 2> Addrs) {
717
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
718
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
719
4
    CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
720
4
  }
721
722
  void callSpecialFunction(QualType FT, CharUnits Offset,
723
4
                           std::array<Address, 2> Addrs) {
724
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
725
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
726
4
    CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
727
4
                                    CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
728
4
  }
729
};
730
731
struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
732
  GenCopyAssignment(ASTContext &Ctx)
733
14
      : GenBinaryFunc<GenCopyAssignment, false>(Ctx) {}
734
735
  void visitARCStrong(QualType QT, const FieldDecl *FD,
736
8
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
737
8
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
738
8
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
739
8
    llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
740
8
        Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
741
8
    CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
742
8
                            false);
743
8
  }
744
745
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
746
4
                    std::array<Address, 2> Addrs) {
747
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
748
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
749
4
    CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
750
4
  }
751
752
  void callSpecialFunction(QualType FT, CharUnits Offset,
753
4
                           std::array<Address, 2> Addrs) {
754
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
755
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
756
4
    CGF->callCStructCopyAssignmentOperator(
757
4
        CGF->MakeAddrLValue(Addrs[DstIdx], FT),
758
4
        CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
759
4
  }
760
};
761
762
struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
763
  GenMoveAssignment(ASTContext &Ctx)
764
12
      : GenBinaryFunc<GenMoveAssignment, true>(Ctx) {}
765
766
  void visitARCStrong(QualType QT, const FieldDecl *FD,
767
6
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
768
6
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
769
6
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
770
6
    LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
771
6
    llvm::Value *SrcVal =
772
6
        CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
773
6
    CGF->EmitStoreOfScalar(getNullForVariable(SrcLV.getAddress()), SrcLV);
774
6
    LValue DstLV = CGF->MakeAddrLValue(Addrs[DstIdx], QT);
775
6
    llvm::Value *DstVal =
776
6
        CGF->EmitLoadOfLValue(DstLV, SourceLocation()).getScalarVal();
777
6
    CGF->EmitStoreOfScalar(SrcVal, DstLV);
778
6
    CGF->EmitARCRelease(DstVal, ARCImpreciseLifetime);
779
6
  }
780
781
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
782
4
                    std::array<Address, 2> Addrs) {
783
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
784
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
785
4
    CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
786
4
  }
787
788
  void callSpecialFunction(QualType FT, CharUnits Offset,
789
4
                           std::array<Address, 2> Addrs) {
790
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
791
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
792
4
    CGF->callCStructMoveAssignmentOperator(
793
4
        CGF->MakeAddrLValue(Addrs[DstIdx], FT),
794
4
        CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
795
4
  }
796
};
797
798
} // namespace
799
800
void CodeGenFunction::destroyNonTrivialCStruct(CodeGenFunction &CGF,
801
91
                                               Address Addr, QualType Type) {
802
91
  CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Type));
803
91
}
804
805
// Default-initialize a variable that is a non-trivial struct or an array of
806
// such structure.
807
31
void CodeGenFunction::defaultInitNonTrivialCStructVar(LValue Dst) {
808
31
  GenDefaultInitialize Gen(getContext());
809
31
  Address DstPtr = Builder.CreateBitCast(Dst.getAddress(), CGM.Int8PtrPtrTy);
810
31
  Gen.setCGF(this);
811
31
  QualType QT = Dst.getType();
812
31
  QT = Dst.isVolatile() ? 
QT.withVolatile()0
: QT;
813
31
  Gen.visit(QT, nullptr, CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
814
31
}
815
816
template <class G, size_t N>
817
static void callSpecialFunction(G &&Gen, StringRef FuncName, QualType QT,
818
                                bool IsVolatile, CodeGenFunction &CGF,
819
226
                                std::array<Address, N> Addrs) {
820
540
  for (unsigned I = 0; I < N; 
++I314
)
821
314
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
226
  QT = IsVolatile ? 
QT.withVolatile()4
:
QT222
;
823
226
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
226
}
CGNonTrivialStruct.cpp:void callSpecialFunction<(anonymous namespace)::GenDefaultInitialize, 1ul>((anonymous namespace)::GenDefaultInitialize&&, llvm::StringRef, clang::QualType, bool, clang::CodeGen::CodeGenFunction&, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
819
37
                                std::array<Address, N> Addrs) {
820
74
  for (unsigned I = 0; I < N; 
++I37
)
821
37
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
37
  QT = IsVolatile ? 
QT.withVolatile()0
: QT;
823
37
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
37
}
CGNonTrivialStruct.cpp:void callSpecialFunction<(anonymous namespace)::GenDestructor, 1ul>((anonymous namespace)::GenDestructor&&, llvm::StringRef, clang::QualType, bool, clang::CodeGen::CodeGenFunction&, std::__1::array<clang::CodeGen::Address, 1ul>)
Line
Count
Source
819
101
                                std::array<Address, N> Addrs) {
820
202
  for (unsigned I = 0; I < N; 
++I101
)
821
101
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
101
  QT = IsVolatile ? 
QT.withVolatile()2
:
QT99
;
823
101
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
101
}
CGNonTrivialStruct.cpp:void callSpecialFunction<(anonymous namespace)::GenCopyConstructor, 2ul>((anonymous namespace)::GenCopyConstructor&&, llvm::StringRef, clang::QualType, bool, clang::CodeGen::CodeGenFunction&, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
819
49
                                std::array<Address, N> Addrs) {
820
147
  for (unsigned I = 0; I < N; 
++I98
)
821
98
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
49
  QT = IsVolatile ? 
QT.withVolatile()2
:
QT47
;
823
49
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
49
}
CGNonTrivialStruct.cpp:void callSpecialFunction<(anonymous namespace)::GenCopyAssignment, 2ul>((anonymous namespace)::GenCopyAssignment&&, llvm::StringRef, clang::QualType, bool, clang::CodeGen::CodeGenFunction&, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
819
14
                                std::array<Address, N> Addrs) {
820
42
  for (unsigned I = 0; I < N; 
++I28
)
821
28
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
14
  QT = IsVolatile ? 
QT.withVolatile()0
: QT;
823
14
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
14
}
CGNonTrivialStruct.cpp:void callSpecialFunction<(anonymous namespace)::GenMoveConstructor, 2ul>((anonymous namespace)::GenMoveConstructor&&, llvm::StringRef, clang::QualType, bool, clang::CodeGen::CodeGenFunction&, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
819
13
                                std::array<Address, N> Addrs) {
820
39
  for (unsigned I = 0; I < N; 
++I26
)
821
26
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
13
  QT = IsVolatile ? 
QT.withVolatile()0
: QT;
823
13
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
13
}
CGNonTrivialStruct.cpp:void callSpecialFunction<(anonymous namespace)::GenMoveAssignment, 2ul>((anonymous namespace)::GenMoveAssignment&&, llvm::StringRef, clang::QualType, bool, clang::CodeGen::CodeGenFunction&, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
819
12
                                std::array<Address, N> Addrs) {
820
36
  for (unsigned I = 0; I < N; 
++I24
)
821
24
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
822
12
  QT = IsVolatile ? 
QT.withVolatile()0
: QT;
823
12
  Gen.callFunc(FuncName, QT, Addrs, CGF);
824
12
}
825
826
template <size_t N> std::array<Address, N> createNullAddressArray();
827
828
0
template <> std::array<Address, 1> createNullAddressArray() {
829
0
  return std::array<Address, 1>({{Address(nullptr, CharUnits::Zero())}});
830
0
}
831
832
0
template <> std::array<Address, 2> createNullAddressArray() {
833
0
  return std::array<Address, 2>({{Address(nullptr, CharUnits::Zero()),
834
0
                                  Address(nullptr, CharUnits::Zero())}});
835
0
}
836
837
template <class G, size_t N>
838
static llvm::Function *
839
getSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile,
840
0
                   std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
841
0
  QT = IsVolatile ? QT.withVolatile() : QT;
842
0
  // The following call requires an array of addresses as arguments, but doesn't
843
0
  // actually use them (it overwrites them with the addresses of the arguments
844
0
  // of the created function).
845
0
  return Gen.getFunction(FuncName, QT, createNullAddressArray<N>(), Alignments,
846
0
                         CGM);
847
0
}
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenDefaultInitialize, 1ul>((anonymous namespace)::GenDefaultInitialize&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 1ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenCopyConstructor, 2ul>((anonymous namespace)::GenCopyConstructor&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenMoveConstructor, 2ul>((anonymous namespace)::GenMoveConstructor&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenCopyAssignment, 2ul>((anonymous namespace)::GenCopyAssignment&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenMoveAssignment, 2ul>((anonymous namespace)::GenMoveAssignment&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenDestructor, 1ul>((anonymous namespace)::GenDestructor&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 1ul>, clang::CodeGen::CodeGenModule&)
848
849
// Functions to emit calls to the special functions of a non-trivial C struct.
850
37
void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
851
37
  bool IsVolatile = Dst.isVolatile();
852
37
  Address DstPtr = Dst.getAddress();
853
37
  QualType QT = Dst.getType();
854
37
  GenDefaultInitializeFuncName GenName(DstPtr.getAlignment(), getContext());
855
37
  std::string FuncName = GenName.getName(QT, IsVolatile);
856
37
  callSpecialFunction(GenDefaultInitialize(getContext()), FuncName, QT,
857
37
                      IsVolatile, *this, std::array<Address, 1>({{DstPtr}}));
858
37
}
859
860
std::string CodeGenFunction::getNonTrivialCopyConstructorStr(
861
4
    QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx) {
862
4
  GenBinaryFuncName<false> GenName("", Alignment, Alignment, Ctx);
863
4
  return GenName.getName(QT, IsVolatile);
864
4
}
865
866
std::string CodeGenFunction::getNonTrivialDestructorStr(QualType QT,
867
                                                        CharUnits Alignment,
868
                                                        bool IsVolatile,
869
2
                                                        ASTContext &Ctx) {
870
2
  GenDestructorFuncName GenName("", Alignment, Ctx);
871
2
  return GenName.getName(QT, IsVolatile);
872
2
}
873
874
101
void CodeGenFunction::callCStructDestructor(LValue Dst) {
875
101
  bool IsVolatile = Dst.isVolatile();
876
101
  Address DstPtr = Dst.getAddress();
877
101
  QualType QT = Dst.getType();
878
101
  GenDestructorFuncName GenName("__destructor_", DstPtr.getAlignment(),
879
101
                                getContext());
880
101
  std::string FuncName = GenName.getName(QT, IsVolatile);
881
101
  callSpecialFunction(GenDestructor(getContext()), FuncName, QT, IsVolatile,
882
101
                      *this, std::array<Address, 1>({{DstPtr}}));
883
101
}
884
885
49
void CodeGenFunction::callCStructCopyConstructor(LValue Dst, LValue Src) {
886
49
  bool IsVolatile = Dst.isVolatile() || 
Src.isVolatile()47
;
887
49
  Address DstPtr = Dst.getAddress(), SrcPtr = Src.getAddress();
888
49
  QualType QT = Dst.getType();
889
49
  GenBinaryFuncName<false> GenName("__copy_constructor_", DstPtr.getAlignment(),
890
49
                                   SrcPtr.getAlignment(), getContext());
891
49
  std::string FuncName = GenName.getName(QT, IsVolatile);
892
49
  callSpecialFunction(GenCopyConstructor(getContext()), FuncName, QT,
893
49
                      IsVolatile, *this,
894
49
                      std::array<Address, 2>({{DstPtr, SrcPtr}}));
895
49
}
896
897
void CodeGenFunction::callCStructCopyAssignmentOperator(LValue Dst, LValue Src
898
899
14
) {
900
14
  bool IsVolatile = Dst.isVolatile() || Src.isVolatile();
901
14
  Address DstPtr = Dst.getAddress(), SrcPtr = Src.getAddress();
902
14
  QualType QT = Dst.getType();
903
14
  GenBinaryFuncName<false> GenName("__copy_assignment_", DstPtr.getAlignment(),
904
14
                                   SrcPtr.getAlignment(), getContext());
905
14
  std::string FuncName = GenName.getName(QT, IsVolatile);
906
14
  callSpecialFunction(GenCopyAssignment(getContext()), FuncName, QT, IsVolatile,
907
14
                      *this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
908
14
}
909
910
13
void CodeGenFunction::callCStructMoveConstructor(LValue Dst, LValue Src) {
911
13
  bool IsVolatile = Dst.isVolatile() || Src.isVolatile();
912
13
  Address DstPtr = Dst.getAddress(), SrcPtr = Src.getAddress();
913
13
  QualType QT = Dst.getType();
914
13
  GenBinaryFuncName<true> GenName("__move_constructor_", DstPtr.getAlignment(),
915
13
                                  SrcPtr.getAlignment(), getContext());
916
13
  std::string FuncName = GenName.getName(QT, IsVolatile);
917
13
  callSpecialFunction(GenMoveConstructor(getContext()), FuncName, QT,
918
13
                      IsVolatile, *this,
919
13
                      std::array<Address, 2>({{DstPtr, SrcPtr}}));
920
13
}
921
922
void CodeGenFunction::callCStructMoveAssignmentOperator(LValue Dst, LValue Src
923
924
12
) {
925
12
  bool IsVolatile = Dst.isVolatile() || Src.isVolatile();
926
12
  Address DstPtr = Dst.getAddress(), SrcPtr = Src.getAddress();
927
12
  QualType QT = Dst.getType();
928
12
  GenBinaryFuncName<true> GenName("__move_assignment_", DstPtr.getAlignment(),
929
12
                                  SrcPtr.getAlignment(), getContext());
930
12
  std::string FuncName = GenName.getName(QT, IsVolatile);
931
12
  callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
932
12
                      *this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
933
12
}
934
935
llvm::Function *clang::CodeGen::getNonTrivialCStructDefaultConstructor(
936
0
    CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
937
0
  ASTContext &Ctx = CGM.getContext();
938
0
  GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
939
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
940
0
  return getSpecialFunction(GenDefaultInitialize(Ctx), FuncName, QT, IsVolatile,
941
0
                            std::array<CharUnits, 1>({{DstAlignment}}), CGM);
942
0
}
943
944
llvm::Function *clang::CodeGen::getNonTrivialCStructCopyConstructor(
945
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
946
0
    bool IsVolatile, QualType QT) {
947
0
  ASTContext &Ctx = CGM.getContext();
948
0
  GenBinaryFuncName<false> GenName("__copy_constructor_", DstAlignment,
949
0
                                   SrcAlignment, Ctx);
950
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
951
0
  return getSpecialFunction(
952
0
      GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
953
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
954
0
}
955
956
llvm::Function *clang::CodeGen::getNonTrivialCStructMoveConstructor(
957
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
958
0
    bool IsVolatile, QualType QT) {
959
0
  ASTContext &Ctx = CGM.getContext();
960
0
  GenBinaryFuncName<true> GenName("__move_constructor_", DstAlignment,
961
0
                                  SrcAlignment, Ctx);
962
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
963
0
  return getSpecialFunction(
964
0
      GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
965
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
966
0
}
967
968
llvm::Function *clang::CodeGen::getNonTrivialCStructCopyAssignmentOperator(
969
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
970
0
    bool IsVolatile, QualType QT) {
971
0
  ASTContext &Ctx = CGM.getContext();
972
0
  GenBinaryFuncName<false> GenName("__copy_assignment_", DstAlignment,
973
0
                                   SrcAlignment, Ctx);
974
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
975
0
  return getSpecialFunction(
976
0
      GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
977
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
978
0
}
979
980
llvm::Function *clang::CodeGen::getNonTrivialCStructMoveAssignmentOperator(
981
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
982
0
    bool IsVolatile, QualType QT) {
983
0
  ASTContext &Ctx = CGM.getContext();
984
0
  GenBinaryFuncName<true> GenName("__move_assignment_", DstAlignment,
985
0
                                  SrcAlignment, Ctx);
986
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
987
0
  return getSpecialFunction(
988
0
      GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
989
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
990
0
}
991
992
llvm::Function *clang::CodeGen::getNonTrivialCStructDestructor(
993
0
    CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
994
0
  ASTContext &Ctx = CGM.getContext();
995
0
  GenDestructorFuncName GenName("__destructor_", DstAlignment, Ctx);
996
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
997
0
  return getSpecialFunction(GenDestructor(Ctx), FuncName, QT, IsVolatile,
998
0
                            std::array<CharUnits, 1>({{DstAlignment}}), CGM);
999
0
}