Coverage Report

Created: 2020-09-15 12:33

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