Coverage Report

Created: 2022-05-17 06:19

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