Coverage Report

Created: 2021-09-21 08:58

/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
  for (auto &P : Params)
319
219
    Args.push_back(P);
320
321
145
  return CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
322
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
  for (auto &P : Params)
319
71
    Args.push_back(P);
320
321
71
  return CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
322
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
  for (auto &P : Params)
319
148
    Args.push_back(P);
320
321
74
  return CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
322
74
}
323
324
template <size_t N, size_t... Ints>
325
static std::array<Address, N> getParamAddrs(std::index_sequence<Ints...> IntSeq,
326
                                            std::array<CharUnits, N> Alignments,
327
                                            FunctionArgList Args,
328
145
                                            CodeGenFunction *CGF) {
329
145
  return std::array<Address, N>{{
330
145
      Address(CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[Ints])),
331
145
              Alignments[Ints])...}};
332
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
328
71
                                            CodeGenFunction *CGF) {
329
71
  return std::array<Address, N>{{
330
71
      Address(CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[Ints])),
331
71
              Alignments[Ints])...}};
332
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
328
74
                                            CodeGenFunction *CGF) {
329
74
  return std::array<Address, N>{{
330
74
      Address(CGF->Builder.CreateLoad(CGF->GetAddrOfLocalVar(Args[Ints])),
331
74
              Alignments[Ints])...}};
332
74
}
333
334
// Template classes that are used as bases for classes that emit special
335
// functions.
336
template <class Derived> struct GenFuncBase {
337
  template <size_t N>
338
  void visitStruct(QualType FT, const FieldDecl *FD, CharUnits CurStructOffset,
339
73
                   std::array<Address, N> Addrs) {
340
73
    this->asDerived().callSpecialFunction(
341
73
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
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
339
44
                   std::array<Address, N> Addrs) {
340
44
    this->asDerived().callSpecialFunction(
341
44
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
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
339
8
                   std::array<Address, N> Addrs) {
340
8
    this->asDerived().callSpecialFunction(
341
8
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
8
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
339
7
                   std::array<Address, N> Addrs) {
340
7
    this->asDerived().callSpecialFunction(
341
7
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
7
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
339
6
                   std::array<Address, N> Addrs) {
340
6
    this->asDerived().callSpecialFunction(
341
6
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
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
339
4
                   std::array<Address, N> Addrs) {
340
4
    this->asDerived().callSpecialFunction(
341
4
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
4
  }
CGNonTrivialStruct.cpp:void (anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::visitStruct<2ul>(clang::QualType, clang::FieldDecl const*, clang::CharUnits, std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
339
4
                   std::array<Address, N> Addrs) {
340
4
    this->asDerived().callSpecialFunction(
341
4
        FT, CurStructOffset + asDerived().getFieldOffset(FD), Addrs);
342
4
  }
343
344
  template <class FieldKind, size_t N>
345
  void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
346
                  const FieldDecl *FD, CharUnits CurStructOffset,
347
32
                  std::array<Address, N> Addrs) {
348
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
349
32
    if (!FK)
350
8
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
351
8
                                      Addrs);
352
353
24
    asDerived().flushTrivialFields(Addrs);
354
24
    CodeGenFunction &CGF = *this->CGF;
355
24
    ASTContext &Ctx = CGF.getContext();
356
357
    // Compute the end address.
358
24
    QualType BaseEltQT;
359
24
    std::array<Address, N> StartAddrs = Addrs;
360
58
    for (unsigned I = 0; I < N; 
++I34
)
361
34
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
362
24
    Address DstAddr = StartAddrs[DstIdx];
363
24
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
364
24
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
365
24
    llvm::Value *BaseEltSizeVal =
366
24
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
367
24
    llvm::Value *SizeInBytes =
368
24
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
369
24
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
370
24
    llvm::Value *DstArrayEnd =
371
24
        CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, BC.getPointer(), SizeInBytes);
372
24
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
373
24
                                            "dstarray.end");
374
24
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
375
376
    // Create the header block and insert the phi instructions.
377
24
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
378
24
    CGF.EmitBlock(HeaderBB);
379
24
    llvm::PHINode *PHIs[N];
380
381
58
    for (unsigned I = 0; I < N; 
++I34
) {
382
34
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
383
34
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
384
34
    }
385
386
    // Create the exit and loop body blocks.
387
24
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
388
24
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
389
390
    // Emit the comparison and conditional branch instruction that jumps to
391
    // either the exit or the loop body.
392
24
    llvm::Value *Done =
393
24
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
394
24
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
395
396
    // Visit the element of the array in the loop body.
397
24
    CGF.EmitBlock(LoopBB);
398
24
    QualType EltQT = AT->getElementType();
399
24
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
400
24
    std::array<Address, N> NewAddrs = Addrs;
401
402
58
    for (unsigned I = 0; I < N; 
++I34
)
403
34
      NewAddrs[I] = Address(
404
34
          PHIs[I], 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
347
6
                  std::array<Address, N> Addrs) {
348
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
349
6
    if (!FK)
350
0
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
351
0
                                      Addrs);
352
353
6
    asDerived().flushTrivialFields(Addrs);
354
6
    CodeGenFunction &CGF = *this->CGF;
355
6
    ASTContext &Ctx = CGF.getContext();
356
357
    // Compute the end address.
358
6
    QualType BaseEltQT;
359
6
    std::array<Address, N> StartAddrs = Addrs;
360
12
    for (unsigned I = 0; I < N; 
++I6
)
361
6
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
362
6
    Address DstAddr = StartAddrs[DstIdx];
363
6
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
364
6
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
365
6
    llvm::Value *BaseEltSizeVal =
366
6
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
367
6
    llvm::Value *SizeInBytes =
368
6
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
369
6
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
370
6
    llvm::Value *DstArrayEnd =
371
6
        CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, BC.getPointer(), SizeInBytes);
372
6
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
373
6
                                            "dstarray.end");
374
6
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
375
376
    // Create the header block and insert the phi instructions.
377
6
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
378
6
    CGF.EmitBlock(HeaderBB);
379
6
    llvm::PHINode *PHIs[N];
380
381
12
    for (unsigned I = 0; I < N; 
++I6
) {
382
6
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
383
6
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
384
6
    }
385
386
    // Create the exit and loop body blocks.
387
6
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
388
6
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
389
390
    // Emit the comparison and conditional branch instruction that jumps to
391
    // either the exit or the loop body.
392
6
    llvm::Value *Done =
393
6
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
394
6
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
395
396
    // Visit the element of the array in the loop body.
397
6
    CGF.EmitBlock(LoopBB);
398
6
    QualType EltQT = AT->getElementType();
399
6
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
400
6
    std::array<Address, N> NewAddrs = Addrs;
401
402
12
    for (unsigned I = 0; I < N; 
++I6
)
403
6
      NewAddrs[I] = Address(
404
6
          PHIs[I], 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
347
14
                  std::array<Address, N> Addrs) {
348
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
349
14
    if (!FK)
350
6
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
351
6
                                      Addrs);
352
353
8
    asDerived().flushTrivialFields(Addrs);
354
8
    CodeGenFunction &CGF = *this->CGF;
355
8
    ASTContext &Ctx = CGF.getContext();
356
357
    // Compute the end address.
358
8
    QualType BaseEltQT;
359
8
    std::array<Address, N> StartAddrs = Addrs;
360
16
    for (unsigned I = 0; I < N; 
++I8
)
361
8
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
362
8
    Address DstAddr = StartAddrs[DstIdx];
363
8
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
364
8
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
365
8
    llvm::Value *BaseEltSizeVal =
366
8
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
367
8
    llvm::Value *SizeInBytes =
368
8
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
369
8
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
370
8
    llvm::Value *DstArrayEnd =
371
8
        CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, BC.getPointer(), SizeInBytes);
372
8
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
373
8
                                            "dstarray.end");
374
8
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
375
376
    // Create the header block and insert the phi instructions.
377
8
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
378
8
    CGF.EmitBlock(HeaderBB);
379
8
    llvm::PHINode *PHIs[N];
380
381
16
    for (unsigned I = 0; I < N; 
++I8
) {
382
8
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
383
8
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
384
8
    }
385
386
    // Create the exit and loop body blocks.
387
8
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
388
8
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
389
390
    // Emit the comparison and conditional branch instruction that jumps to
391
    // either the exit or the loop body.
392
8
    llvm::Value *Done =
393
8
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
394
8
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
395
396
    // Visit the element of the array in the loop body.
397
8
    CGF.EmitBlock(LoopBB);
398
8
    QualType EltQT = AT->getElementType();
399
8
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
400
8
    std::array<Address, N> NewAddrs = Addrs;
401
402
16
    for (unsigned I = 0; I < N; 
++I8
)
403
8
      NewAddrs[I] = Address(
404
8
          PHIs[I], 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
347
8
                  std::array<Address, N> Addrs) {
348
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
349
8
    if (!FK)
350
2
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
351
2
                                      Addrs);
352
353
6
    asDerived().flushTrivialFields(Addrs);
354
6
    CodeGenFunction &CGF = *this->CGF;
355
6
    ASTContext &Ctx = CGF.getContext();
356
357
    // Compute the end address.
358
6
    QualType BaseEltQT;
359
6
    std::array<Address, N> StartAddrs = Addrs;
360
18
    for (unsigned I = 0; I < N; 
++I12
)
361
12
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
362
6
    Address DstAddr = StartAddrs[DstIdx];
363
6
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
364
6
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
365
6
    llvm::Value *BaseEltSizeVal =
366
6
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
367
6
    llvm::Value *SizeInBytes =
368
6
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
369
6
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
370
6
    llvm::Value *DstArrayEnd =
371
6
        CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, BC.getPointer(), SizeInBytes);
372
6
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
373
6
                                            "dstarray.end");
374
6
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
375
376
    // Create the header block and insert the phi instructions.
377
6
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
378
6
    CGF.EmitBlock(HeaderBB);
379
6
    llvm::PHINode *PHIs[N];
380
381
18
    for (unsigned I = 0; I < N; 
++I12
) {
382
12
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
383
12
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
384
12
    }
385
386
    // Create the exit and loop body blocks.
387
6
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
388
6
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
389
390
    // Emit the comparison and conditional branch instruction that jumps to
391
    // either the exit or the loop body.
392
6
    llvm::Value *Done =
393
6
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
394
6
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
395
396
    // Visit the element of the array in the loop body.
397
6
    CGF.EmitBlock(LoopBB);
398
6
    QualType EltQT = AT->getElementType();
399
6
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
400
6
    std::array<Address, N> NewAddrs = Addrs;
401
402
18
    for (unsigned I = 0; I < N; 
++I12
)
403
12
      NewAddrs[I] = Address(
404
12
          PHIs[I], 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
347
4
                  std::array<Address, N> Addrs) {
348
    // Non-volatile trivial fields are copied when flushTrivialFields is called.
349
4
    if (!FK)
350
0
      return asDerived().visitTrivial(QualType(AT, 0), FD, CurStructOffset,
351
0
                                      Addrs);
352
353
4
    asDerived().flushTrivialFields(Addrs);
354
4
    CodeGenFunction &CGF = *this->CGF;
355
4
    ASTContext &Ctx = CGF.getContext();
356
357
    // Compute the end address.
358
4
    QualType BaseEltQT;
359
4
    std::array<Address, N> StartAddrs = Addrs;
360
12
    for (unsigned I = 0; I < N; 
++I8
)
361
8
      StartAddrs[I] = getAddrWithOffset(Addrs[I], CurStructOffset, FD);
362
4
    Address DstAddr = StartAddrs[DstIdx];
363
4
    llvm::Value *NumElts = CGF.emitArrayLength(AT, BaseEltQT, DstAddr);
364
4
    unsigned BaseEltSize = Ctx.getTypeSizeInChars(BaseEltQT).getQuantity();
365
4
    llvm::Value *BaseEltSizeVal =
366
4
        llvm::ConstantInt::get(NumElts->getType(), BaseEltSize);
367
4
    llvm::Value *SizeInBytes =
368
4
        CGF.Builder.CreateNUWMul(BaseEltSizeVal, NumElts);
369
4
    Address BC = CGF.Builder.CreateBitCast(DstAddr, CGF.CGM.Int8PtrTy);
370
4
    llvm::Value *DstArrayEnd =
371
4
        CGF.Builder.CreateInBoundsGEP(CGF.Int8Ty, BC.getPointer(), SizeInBytes);
372
4
    DstArrayEnd = CGF.Builder.CreateBitCast(DstArrayEnd, CGF.CGM.Int8PtrPtrTy,
373
4
                                            "dstarray.end");
374
4
    llvm::BasicBlock *PreheaderBB = CGF.Builder.GetInsertBlock();
375
376
    // Create the header block and insert the phi instructions.
377
4
    llvm::BasicBlock *HeaderBB = CGF.createBasicBlock("loop.header");
378
4
    CGF.EmitBlock(HeaderBB);
379
4
    llvm::PHINode *PHIs[N];
380
381
12
    for (unsigned I = 0; I < N; 
++I8
) {
382
8
      PHIs[I] = CGF.Builder.CreatePHI(CGF.CGM.Int8PtrPtrTy, 2, "addr.cur");
383
8
      PHIs[I]->addIncoming(StartAddrs[I].getPointer(), PreheaderBB);
384
8
    }
385
386
    // Create the exit and loop body blocks.
387
4
    llvm::BasicBlock *ExitBB = CGF.createBasicBlock("loop.exit");
388
4
    llvm::BasicBlock *LoopBB = CGF.createBasicBlock("loop.body");
389
390
    // Emit the comparison and conditional branch instruction that jumps to
391
    // either the exit or the loop body.
392
4
    llvm::Value *Done =
393
4
        CGF.Builder.CreateICmpEQ(PHIs[DstIdx], DstArrayEnd, "done");
394
4
    CGF.Builder.CreateCondBr(Done, ExitBB, LoopBB);
395
396
    // Visit the element of the array in the loop body.
397
4
    CGF.EmitBlock(LoopBB);
398
4
    QualType EltQT = AT->getElementType();
399
4
    CharUnits EltSize = Ctx.getTypeSizeInChars(EltQT);
400
4
    std::array<Address, N> NewAddrs = Addrs;
401
402
12
    for (unsigned I = 0; I < N; 
++I8
)
403
8
      NewAddrs[I] = Address(
404
8
          PHIs[I], 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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
249
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
249
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
23
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
23
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
432
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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
44
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
44
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
432
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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
88
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
88
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
432
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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
44
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
44
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
432
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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
26
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
26
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
432
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.CreateBitCast(Addr, CGF->CGM.Int8PtrTy);
430
24
    Addr = CGF->Builder.CreateConstInBoundsGEP(Addr, Offset.getQuantity());
431
24
    return CGF->Builder.CreateBitCast(Addr, CGF->CGM.Int8PtrPtrTy);
432
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] =
495
430
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
430
              .getPointer();
497
430
    }
498
499
312
    if (llvm::Function *F =
500
312
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
311
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
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] =
495
44
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
44
              .getPointer();
497
44
    }
498
499
44
    if (llvm::Function *F =
500
44
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
43
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
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] =
495
150
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
150
              .getPointer();
497
150
    }
498
499
150
    if (llvm::Function *F =
500
150
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
150
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
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] =
495
128
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
128
              .getPointer();
497
128
    }
498
499
64
    if (llvm::Function *F =
500
64
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
64
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
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] =
495
56
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
56
              .getPointer();
497
56
    }
498
499
28
    if (llvm::Function *F =
500
28
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
28
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
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] =
495
28
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
28
              .getPointer();
497
28
    }
498
499
14
    if (llvm::Function *F =
500
14
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
14
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
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] =
495
24
          CallerCGF.Builder.CreateBitCast(Addrs[I], CallerCGF.CGM.Int8PtrPtrTy)
496
24
              .getPointer();
497
24
    }
498
499
12
    if (llvm::Function *F =
500
12
            getFunction(FuncName, QT, Alignments, CallerCGF.CGM))
501
12
      CallerCGF.EmitNounwindRuntimeCall(F, Ptrs);
502
12
  }
503
504
600
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::asDerived()
Line
Count
Source
504
149
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::asDerived()
Line
Count
Source
504
145
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::asDerived()
Line
Count
Source
504
138
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::asDerived()
Line
Count
Source
504
84
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::asDerived()
Line
Count
Source
504
46
  Derived &asDerived() { return static_cast<Derived &>(*this); }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::asDerived()
Line
Count
Source
504
38
  Derived &asDerived() { return static_cast<Derived &>(*this); }
505
506
183
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDefaultInitialize>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
506
60
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenDestructor>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
506
49
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyConstructor>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
506
32
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenCopyAssignment>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
506
20
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveConstructor>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
506
12
  void setCGF(CodeGenFunction *F) { CGF = F; }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenFuncBase<(anonymous namespace)::GenMoveAssignment>::setCGF(clang::CodeGen::CodeGenFunction*)
Line
Count
Source
506
10
  void setCGF(CodeGenFunction *F) { CGF = F; }
507
508
  CodeGenFunction *CGF = nullptr;
509
};
510
511
template <class Derived, bool IsMove>
512
struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
513
                       GenFuncBase<Derived> {
514
118
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyConstructor, false>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
514
64
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyAssignment, false>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
514
28
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveConstructor, true>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
514
14
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveAssignment, true>::GenBinaryFunc(clang::ASTContext&)
Line
Count
Source
514
12
  GenBinaryFunc(ASTContext &Ctx) : CopyStructVisitor<Derived, IsMove>(Ctx) {}
515
516
195
  void flushTrivialFields(std::array<Address, 2> Addrs) {
517
195
    CharUnits Size = this->End - this->Start;
518
519
195
    if (Size.getQuantity() == 0)
520
145
      return;
521
522
50
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
523
50
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
524
525
    // Emit memcpy.
526
50
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())42
) {
527
12
      llvm::Value *SizeVal =
528
12
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
529
12
      DstAddr =
530
12
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
531
12
      SrcAddr =
532
12
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
533
12
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
534
38
    } else {
535
38
      llvm::Type *Ty = llvm::Type::getIntNTy(
536
38
          this->CGF->getLLVMContext(),
537
38
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
538
38
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
539
38
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
540
38
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
541
38
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
542
38
    }
543
544
50
    this->Start = this->End = CharUnits::Zero();
545
50
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyConstructor, false>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
516
88
  void flushTrivialFields(std::array<Address, 2> Addrs) {
517
88
    CharUnits Size = this->End - this->Start;
518
519
88
    if (Size.getQuantity() == 0)
520
64
      return;
521
522
24
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
523
24
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
524
525
    // Emit memcpy.
526
24
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())22
) {
527
6
      llvm::Value *SizeVal =
528
6
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
529
6
      DstAddr =
530
6
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
531
6
      SrcAddr =
532
6
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
533
6
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
534
18
    } else {
535
18
      llvm::Type *Ty = llvm::Type::getIntNTy(
536
18
          this->CGF->getLLVMContext(),
537
18
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
538
18
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
539
18
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
540
18
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
541
18
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
542
18
    }
543
544
24
    this->Start = this->End = CharUnits::Zero();
545
24
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenCopyAssignment, false>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
516
54
  void flushTrivialFields(std::array<Address, 2> Addrs) {
517
54
    CharUnits Size = this->End - this->Start;
518
519
54
    if (Size.getQuantity() == 0)
520
44
      return;
521
522
10
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
523
10
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
524
525
    // Emit memcpy.
526
10
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())8
) {
527
2
      llvm::Value *SizeVal =
528
2
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
529
2
      DstAddr =
530
2
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
531
2
      SrcAddr =
532
2
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
533
2
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
534
8
    } else {
535
8
      llvm::Type *Ty = llvm::Type::getIntNTy(
536
8
          this->CGF->getLLVMContext(),
537
8
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
538
8
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
539
8
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
540
8
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
541
8
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
542
8
    }
543
544
10
    this->Start = this->End = CharUnits::Zero();
545
10
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveConstructor, true>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
516
29
  void flushTrivialFields(std::array<Address, 2> Addrs) {
517
29
    CharUnits Size = this->End - this->Start;
518
519
29
    if (Size.getQuantity() == 0)
520
21
      return;
521
522
8
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
523
8
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
524
525
    // Emit memcpy.
526
8
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())6
) {
527
2
      llvm::Value *SizeVal =
528
2
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
529
2
      DstAddr =
530
2
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
531
2
      SrcAddr =
532
2
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
533
2
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
534
6
    } else {
535
6
      llvm::Type *Ty = llvm::Type::getIntNTy(
536
6
          this->CGF->getLLVMContext(),
537
6
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
538
6
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
539
6
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
540
6
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
541
6
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
542
6
    }
543
544
8
    this->Start = this->End = CharUnits::Zero();
545
8
  }
CGNonTrivialStruct.cpp:(anonymous namespace)::GenBinaryFunc<(anonymous namespace)::GenMoveAssignment, true>::flushTrivialFields(std::__1::array<clang::CodeGen::Address, 2ul>)
Line
Count
Source
516
24
  void flushTrivialFields(std::array<Address, 2> Addrs) {
517
24
    CharUnits Size = this->End - this->Start;
518
519
24
    if (Size.getQuantity() == 0)
520
16
      return;
521
522
8
    Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], this->Start);
523
8
    Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], this->Start);
524
525
    // Emit memcpy.
526
8
    if (Size.getQuantity() >= 16 || 
!llvm::isPowerOf2_32(Size.getQuantity())6
) {
527
2
      llvm::Value *SizeVal =
528
2
          llvm::ConstantInt::get(this->CGF->SizeTy, Size.getQuantity());
529
2
      DstAddr =
530
2
          this->CGF->Builder.CreateElementBitCast(DstAddr, this->CGF->Int8Ty);
531
2
      SrcAddr =
532
2
          this->CGF->Builder.CreateElementBitCast(SrcAddr, this->CGF->Int8Ty);
533
2
      this->CGF->Builder.CreateMemCpy(DstAddr, SrcAddr, SizeVal, false);
534
6
    } else {
535
6
      llvm::Type *Ty = llvm::Type::getIntNTy(
536
6
          this->CGF->getLLVMContext(),
537
6
          Size.getQuantity() * this->CGF->getContext().getCharWidth());
538
6
      DstAddr = this->CGF->Builder.CreateElementBitCast(DstAddr, Ty);
539
6
      SrcAddr = this->CGF->Builder.CreateElementBitCast(SrcAddr, Ty);
540
6
      llvm::Value *SrcVal = this->CGF->Builder.CreateLoad(SrcAddr, false);
541
6
      this->CGF->Builder.CreateStore(SrcVal, DstAddr, false);
542
6
    }
543
544
8
    this->Start = this->End = CharUnits::Zero();
545
8
  }
546
547
  template <class... Ts>
548
  void visitVolatileTrivial(QualType FT, const FieldDecl *FD, CharUnits Offset,
549
16
                            std::array<Address, 2> Addrs) {
550
16
    LValue DstLV, SrcLV;
551
16
    if (FD) {
552
      // No need to copy zero-length bit-fields.
553
10
      if (FD->isZeroLengthBitField(this->CGF->getContext()))
554
2
        return;
555
556
8
      QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
557
8
      llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
558
8
      Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
559
8
      LValue DstBase = this->CGF->MakeAddrLValue(
560
8
          this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
561
8
      DstLV = this->CGF->EmitLValueForField(DstBase, FD);
562
8
      Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
563
8
      LValue SrcBase = this->CGF->MakeAddrLValue(
564
8
          this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
565
8
      SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
566
8
    } else {
567
6
      llvm::PointerType *Ty = this->CGF->ConvertTypeForMem(FT)->getPointerTo();
568
6
      Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
569
6
      Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
570
6
      DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
571
6
      SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
572
6
    }
573
14
    RValue SrcVal = this->CGF->EmitLoadOfLValue(SrcLV, SourceLocation());
574
14
    this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
575
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
549
10
                            std::array<Address, 2> Addrs) {
550
10
    LValue DstLV, SrcLV;
551
10
    if (FD) {
552
      // No need to copy zero-length bit-fields.
553
8
      if (FD->isZeroLengthBitField(this->CGF->getContext()))
554
0
        return;
555
556
8
      QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
557
8
      llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
558
8
      Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
559
8
      LValue DstBase = this->CGF->MakeAddrLValue(
560
8
          this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
561
8
      DstLV = this->CGF->EmitLValueForField(DstBase, FD);
562
8
      Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
563
8
      LValue SrcBase = this->CGF->MakeAddrLValue(
564
8
          this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
565
8
      SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
566
8
    } else {
567
2
      llvm::PointerType *Ty = this->CGF->ConvertTypeForMem(FT)->getPointerTo();
568
2
      Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
569
2
      Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
570
2
      DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
571
2
      SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
572
2
    }
573
10
    RValue SrcVal = this->CGF->EmitLoadOfLValue(SrcLV, SourceLocation());
574
10
    this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
575
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
549
6
                            std::array<Address, 2> Addrs) {
550
6
    LValue DstLV, SrcLV;
551
6
    if (FD) {
552
      // No need to copy zero-length bit-fields.
553
2
      if (FD->isZeroLengthBitField(this->CGF->getContext()))
554
2
        return;
555
556
0
      QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
557
0
      llvm::PointerType *PtrTy = this->CGF->ConvertType(RT)->getPointerTo();
558
0
      Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
559
0
      LValue DstBase = this->CGF->MakeAddrLValue(
560
0
          this->CGF->Builder.CreateBitCast(DstAddr, PtrTy), FT);
561
0
      DstLV = this->CGF->EmitLValueForField(DstBase, FD);
562
0
      Address SrcAddr = this->getAddrWithOffset(Addrs[SrcIdx], Offset);
563
0
      LValue SrcBase = this->CGF->MakeAddrLValue(
564
0
          this->CGF->Builder.CreateBitCast(SrcAddr, PtrTy), FT);
565
0
      SrcLV = this->CGF->EmitLValueForField(SrcBase, FD);
566
4
    } else {
567
4
      llvm::PointerType *Ty = this->CGF->ConvertTypeForMem(FT)->getPointerTo();
568
4
      Address DstAddr = this->CGF->Builder.CreateBitCast(Addrs[DstIdx], Ty);
569
4
      Address SrcAddr = this->CGF->Builder.CreateBitCast(Addrs[SrcIdx], Ty);
570
4
      DstLV = this->CGF->MakeAddrLValue(DstAddr, FT);
571
4
      SrcLV = this->CGF->MakeAddrLValue(SrcAddr, FT);
572
4
    }
573
4
    RValue SrcVal = this->CGF->EmitLoadOfLValue(SrcLV, SourceLocation());
574
4
    this->CGF->EmitStoreThroughLValue(SrcVal, DstLV);
575
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>)
576
};
577
578
// These classes that emit the special functions for a non-trivial struct.
579
struct GenDestructor : StructVisitor<GenDestructor>,
580
                       GenFuncBase<GenDestructor>,
581
                       DestructedTypeVisitor<GenDestructor> {
582
  using Super = DestructedTypeVisitor<GenDestructor>;
583
150
  GenDestructor(ASTContext &Ctx) : StructVisitor<GenDestructor>(Ctx) {}
584
585
  void visitWithKind(QualType::DestructionKind DK, QualType FT,
586
                     const FieldDecl *FD, CharUnits CurStructOffset,
587
127
                     std::array<Address, 1> Addrs) {
588
127
    if (const auto *AT = getContext().getAsArrayType(FT)) {
589
14
      visitArray(DK, AT, FT.isVolatileQualified(), FD, CurStructOffset, Addrs);
590
14
      return;
591
14
    }
592
593
113
    Super::visitWithKind(DK, FT, FD, CurStructOffset, Addrs);
594
113
  }
595
596
  void visitARCStrong(QualType QT, const FieldDecl *FD,
597
42
                      CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
598
42
    CGF->destroyARCStrongImprecise(
599
42
        *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
600
42
  }
601
602
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
603
8
                    std::array<Address, 1> Addrs) {
604
8
    CGF->destroyARCWeak(
605
8
        *CGF, getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
606
8
  }
607
608
  void callSpecialFunction(QualType FT, CharUnits Offset,
609
8
                           std::array<Address, 1> Addrs) {
610
8
    CGF->callCStructDestructor(
611
8
        CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
612
8
  }
613
};
614
615
struct GenDefaultInitialize
616
    : StructVisitor<GenDefaultInitialize>,
617
      GenFuncBase<GenDefaultInitialize>,
618
      DefaultInitializedTypeVisitor<GenDefaultInitialize> {
619
  using Super = DefaultInitializedTypeVisitor<GenDefaultInitialize>;
620
  typedef GenFuncBase<GenDefaultInitialize> GenFuncBaseTy;
621
622
  GenDefaultInitialize(ASTContext &Ctx)
623
82
      : StructVisitor<GenDefaultInitialize>(Ctx) {}
624
625
  void visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType FT,
626
                     const FieldDecl *FD, CharUnits CurStructOffset,
627
87
                     std::array<Address, 1> Addrs) {
628
87
    if (const auto *AT = getContext().getAsArrayType(FT)) {
629
8
      visitArray(PDIK, AT, FT.isVolatileQualified(), FD, CurStructOffset,
630
8
                 Addrs);
631
8
      return;
632
8
    }
633
634
79
    Super::visitWithKind(PDIK, FT, FD, CurStructOffset, Addrs);
635
79
  }
636
637
  void visitARCStrong(QualType QT, const FieldDecl *FD,
638
14
                      CharUnits CurStructOffset, std::array<Address, 1> Addrs) {
639
14
    CGF->EmitNullInitialization(
640
14
        getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
641
14
  }
642
643
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
644
5
                    std::array<Address, 1> Addrs) {
645
5
    CGF->EmitNullInitialization(
646
5
        getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD), QT);
647
5
  }
648
649
  template <class FieldKind, size_t... Is>
650
  void visitArray(FieldKind FK, const ArrayType *AT, bool IsVolatile,
651
                  const FieldDecl *FD, CharUnits CurStructOffset,
652
8
                  std::array<Address, 1> Addrs) {
653
8
    if (!FK)
654
0
      return visitTrivial(QualType(AT, 0), FD, CurStructOffset, Addrs);
655
656
8
    ASTContext &Ctx = getContext();
657
8
    CharUnits Size = Ctx.getTypeSizeInChars(QualType(AT, 0));
658
8
    QualType EltTy = Ctx.getBaseElementType(QualType(AT, 0));
659
660
8
    if (Size < CharUnits::fromQuantity(16) || 
EltTy->getAs<RecordType>()6
) {
661
6
      GenFuncBaseTy::visitArray(FK, AT, IsVolatile, FD, CurStructOffset, Addrs);
662
6
      return;
663
6
    }
664
665
2
    llvm::Constant *SizeVal = CGF->Builder.getInt64(Size.getQuantity());
666
2
    Address DstAddr = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
667
2
    Address Loc = CGF->Builder.CreateElementBitCast(DstAddr, CGF->Int8Ty);
668
2
    CGF->Builder.CreateMemSet(Loc, CGF->Builder.getInt8(0), SizeVal,
669
2
                              IsVolatile);
670
2
  }
671
672
  void callSpecialFunction(QualType FT, CharUnits Offset,
673
44
                           std::array<Address, 1> Addrs) {
674
44
    CGF->callCStructDefaultConstructor(
675
44
        CGF->MakeAddrLValue(getAddrWithOffset(Addrs[DstIdx], Offset), FT));
676
44
  }
677
};
678
679
struct GenCopyConstructor : GenBinaryFunc<GenCopyConstructor, false> {
680
  GenCopyConstructor(ASTContext &Ctx)
681
64
      : GenBinaryFunc<GenCopyConstructor, false>(Ctx) {}
682
683
  void visitARCStrong(QualType QT, const FieldDecl *FD,
684
28
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
685
28
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
686
28
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
687
28
    llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
688
28
        Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
689
28
    llvm::Value *Val = CGF->EmitARCRetain(QT, SrcVal);
690
28
    CGF->EmitStoreOfScalar(Val, CGF->MakeAddrLValue(Addrs[DstIdx], QT), true);
691
28
  }
692
693
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
694
5
                    std::array<Address, 2> Addrs) {
695
5
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
696
5
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
697
5
    CGF->EmitARCCopyWeak(Addrs[DstIdx], Addrs[SrcIdx]);
698
5
  }
699
700
  void callSpecialFunction(QualType FT, CharUnits Offset,
701
7
                           std::array<Address, 2> Addrs) {
702
7
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
703
7
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
704
7
    CGF->callCStructCopyConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
705
7
                                    CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
706
7
  }
707
};
708
709
struct GenMoveConstructor : GenBinaryFunc<GenMoveConstructor, true> {
710
  GenMoveConstructor(ASTContext &Ctx)
711
14
      : GenBinaryFunc<GenMoveConstructor, true>(Ctx) {}
712
713
  void visitARCStrong(QualType QT, const FieldDecl *FD,
714
9
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
715
9
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
716
9
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
717
9
    LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
718
9
    llvm::Value *SrcVal =
719
9
        CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
720
9
    CGF->EmitStoreOfScalar(getNullForVariable(SrcLV.getAddress(*CGF)), SrcLV);
721
9
    CGF->EmitStoreOfScalar(SrcVal, CGF->MakeAddrLValue(Addrs[DstIdx], QT),
722
9
                           /* isInitialization */ true);
723
9
  }
724
725
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
726
4
                    std::array<Address, 2> Addrs) {
727
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
728
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
729
4
    CGF->EmitARCMoveWeak(Addrs[DstIdx], Addrs[SrcIdx]);
730
4
  }
731
732
  void callSpecialFunction(QualType FT, CharUnits Offset,
733
4
                           std::array<Address, 2> Addrs) {
734
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
735
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
736
4
    CGF->callCStructMoveConstructor(CGF->MakeAddrLValue(Addrs[DstIdx], FT),
737
4
                                    CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
738
4
  }
739
};
740
741
struct GenCopyAssignment : GenBinaryFunc<GenCopyAssignment, false> {
742
  GenCopyAssignment(ASTContext &Ctx)
743
28
      : GenBinaryFunc<GenCopyAssignment, false>(Ctx) {}
744
745
  void visitARCStrong(QualType QT, const FieldDecl *FD,
746
14
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
747
14
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
748
14
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
749
14
    llvm::Value *SrcVal = CGF->EmitLoadOfScalar(
750
14
        Addrs[SrcIdx], QT.isVolatileQualified(), QT, SourceLocation());
751
14
    CGF->EmitARCStoreStrong(CGF->MakeAddrLValue(Addrs[DstIdx], QT), SrcVal,
752
14
                            false);
753
14
  }
754
755
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
756
4
                    std::array<Address, 2> Addrs) {
757
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
758
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
759
4
    CGF->emitARCCopyAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
760
4
  }
761
762
  void callSpecialFunction(QualType FT, CharUnits Offset,
763
6
                           std::array<Address, 2> Addrs) {
764
6
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
765
6
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
766
6
    CGF->callCStructCopyAssignmentOperator(
767
6
        CGF->MakeAddrLValue(Addrs[DstIdx], FT),
768
6
        CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
769
6
  }
770
};
771
772
struct GenMoveAssignment : GenBinaryFunc<GenMoveAssignment, true> {
773
  GenMoveAssignment(ASTContext &Ctx)
774
12
      : GenBinaryFunc<GenMoveAssignment, true>(Ctx) {}
775
776
  void visitARCStrong(QualType QT, const FieldDecl *FD,
777
6
                      CharUnits CurStructOffset, std::array<Address, 2> Addrs) {
778
6
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
779
6
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
780
6
    LValue SrcLV = CGF->MakeAddrLValue(Addrs[SrcIdx], QT);
781
6
    llvm::Value *SrcVal =
782
6
        CGF->EmitLoadOfLValue(SrcLV, SourceLocation()).getScalarVal();
783
6
    CGF->EmitStoreOfScalar(getNullForVariable(SrcLV.getAddress(*CGF)), SrcLV);
784
6
    LValue DstLV = CGF->MakeAddrLValue(Addrs[DstIdx], QT);
785
6
    llvm::Value *DstVal =
786
6
        CGF->EmitLoadOfLValue(DstLV, SourceLocation()).getScalarVal();
787
6
    CGF->EmitStoreOfScalar(SrcVal, DstLV);
788
6
    CGF->EmitARCRelease(DstVal, ARCImpreciseLifetime);
789
6
  }
790
791
  void visitARCWeak(QualType QT, const FieldDecl *FD, CharUnits CurStructOffset,
792
4
                    std::array<Address, 2> Addrs) {
793
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], CurStructOffset, FD);
794
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], CurStructOffset, FD);
795
4
    CGF->emitARCMoveAssignWeak(QT, Addrs[DstIdx], Addrs[SrcIdx]);
796
4
  }
797
798
  void callSpecialFunction(QualType FT, CharUnits Offset,
799
4
                           std::array<Address, 2> Addrs) {
800
4
    Addrs[DstIdx] = getAddrWithOffset(Addrs[DstIdx], Offset);
801
4
    Addrs[SrcIdx] = getAddrWithOffset(Addrs[SrcIdx], Offset);
802
4
    CGF->callCStructMoveAssignmentOperator(
803
4
        CGF->MakeAddrLValue(Addrs[DstIdx], FT),
804
4
        CGF->MakeAddrLValue(Addrs[SrcIdx], FT));
805
4
  }
806
};
807
808
} // namespace
809
810
void CodeGenFunction::destroyNonTrivialCStruct(CodeGenFunction &CGF,
811
140
                                               Address Addr, QualType Type) {
812
140
  CGF.callCStructDestructor(CGF.MakeAddrLValue(Addr, Type));
813
140
}
814
815
// Default-initialize a variable that is a non-trivial struct or an array of
816
// such structure.
817
38
void CodeGenFunction::defaultInitNonTrivialCStructVar(LValue Dst) {
818
38
  GenDefaultInitialize Gen(getContext());
819
38
  Address DstPtr =
820
38
      Builder.CreateBitCast(Dst.getAddress(*this), CGM.Int8PtrPtrTy);
821
38
  Gen.setCGF(this);
822
38
  QualType QT = Dst.getType();
823
38
  QT = Dst.isVolatile() ? 
QT.withVolatile()4
:
QT34
;
824
38
  Gen.visit(QT, nullptr, CharUnits::Zero(), std::array<Address, 1>({{DstPtr}}));
825
38
}
826
827
template <class G, size_t N>
828
static void callSpecialFunction(G &&Gen, StringRef FuncName, QualType QT,
829
                                bool IsVolatile, CodeGenFunction &CGF,
830
312
                                std::array<Address, N> Addrs) {
831
312
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
742
  for (unsigned I = 0; I < N; 
++I430
)
833
430
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
312
  QT = IsVolatile ? 
QT.withVolatile()20
:
QT292
;
835
312
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
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
830
44
                                std::array<Address, N> Addrs) {
831
44
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
88
  for (unsigned I = 0; I < N; 
++I44
)
833
44
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
44
  QT = IsVolatile ? 
QT.withVolatile()4
:
QT40
;
835
44
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
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
830
150
                                std::array<Address, N> Addrs) {
831
150
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
300
  for (unsigned I = 0; I < N; 
++I150
)
833
150
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
150
  QT = IsVolatile ? 
QT.withVolatile()6
:
QT144
;
835
150
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
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
830
64
                                std::array<Address, N> Addrs) {
831
64
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
192
  for (unsigned I = 0; I < N; 
++I128
)
833
128
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
64
  QT = IsVolatile ? 
QT.withVolatile()4
:
QT60
;
835
64
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
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
830
28
                                std::array<Address, N> Addrs) {
831
28
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
84
  for (unsigned I = 0; I < N; 
++I56
)
833
56
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
28
  QT = IsVolatile ? 
QT.withVolatile()6
:
QT22
;
835
28
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
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
830
14
                                std::array<Address, N> Addrs) {
831
14
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
42
  for (unsigned I = 0; I < N; 
++I28
)
833
28
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
14
  QT = IsVolatile ? 
QT.withVolatile()0
: QT;
835
14
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
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
830
12
                                std::array<Address, N> Addrs) {
831
12
  auto SetArtificialLoc = ApplyDebugLocation::CreateArtificial(CGF);
832
36
  for (unsigned I = 0; I < N; 
++I24
)
833
24
    Addrs[I] = CGF.Builder.CreateBitCast(Addrs[I], CGF.CGM.Int8PtrPtrTy);
834
12
  QT = IsVolatile ? 
QT.withVolatile()0
: QT;
835
12
  Gen.callFunc(FuncName, QT, Addrs, CGF);
836
12
}
837
838
template <class G, size_t N>
839
static llvm::Function *
840
getSpecialFunction(G &&Gen, StringRef FuncName, QualType QT, bool IsVolatile,
841
0
                   std::array<CharUnits, N> Alignments, CodeGenModule &CGM) {
842
0
  QT = IsVolatile ? QT.withVolatile() : QT;
843
  // The following call requires an array of addresses as arguments, but doesn't
844
  // actually use them (it overwrites them with the addresses of the arguments
845
  // of the created function).
846
0
  return Gen.getFunction(FuncName, QT, Alignments, CGM);
847
0
}
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenDefaultInitialize, 1ul>((anonymous namespace)::GenDefaultInitialize&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 1ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenCopyConstructor, 2ul>((anonymous namespace)::GenCopyConstructor&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenMoveConstructor, 2ul>((anonymous namespace)::GenMoveConstructor&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenCopyAssignment, 2ul>((anonymous namespace)::GenCopyAssignment&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenMoveAssignment, 2ul>((anonymous namespace)::GenMoveAssignment&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 2ul>, clang::CodeGen::CodeGenModule&)
Unexecuted instantiation: CGNonTrivialStruct.cpp:llvm::Function* getSpecialFunction<(anonymous namespace)::GenDestructor, 1ul>((anonymous namespace)::GenDestructor&&, llvm::StringRef, clang::QualType, bool, std::__1::array<clang::CharUnits, 1ul>, clang::CodeGen::CodeGenModule&)
848
849
// Functions to emit calls to the special functions of a non-trivial C struct.
850
44
void CodeGenFunction::callCStructDefaultConstructor(LValue Dst) {
851
44
  bool IsVolatile = Dst.isVolatile();
852
44
  Address DstPtr = Dst.getAddress(*this);
853
44
  QualType QT = Dst.getType();
854
44
  GenDefaultInitializeFuncName GenName(DstPtr.getAlignment(), getContext());
855
44
  std::string FuncName = GenName.getName(QT, IsVolatile);
856
44
  callSpecialFunction(GenDefaultInitialize(getContext()), FuncName, QT,
857
44
                      IsVolatile, *this, std::array<Address, 1>({{DstPtr}}));
858
44
}
859
860
std::string CodeGenFunction::getNonTrivialCopyConstructorStr(
861
4
    QualType QT, CharUnits Alignment, bool IsVolatile, ASTContext &Ctx) {
862
4
  GenBinaryFuncName<false> GenName("", Alignment, Alignment, Ctx);
863
4
  return GenName.getName(QT, IsVolatile);
864
4
}
865
866
std::string CodeGenFunction::getNonTrivialDestructorStr(QualType QT,
867
                                                        CharUnits Alignment,
868
                                                        bool IsVolatile,
869
2
                                                        ASTContext &Ctx) {
870
2
  GenDestructorFuncName GenName("", Alignment, Ctx);
871
2
  return GenName.getName(QT, IsVolatile);
872
2
}
873
874
150
void CodeGenFunction::callCStructDestructor(LValue Dst) {
875
150
  bool IsVolatile = Dst.isVolatile();
876
150
  Address DstPtr = Dst.getAddress(*this);
877
150
  QualType QT = Dst.getType();
878
150
  GenDestructorFuncName GenName("__destructor_", DstPtr.getAlignment(),
879
150
                                getContext());
880
150
  std::string FuncName = GenName.getName(QT, IsVolatile);
881
150
  callSpecialFunction(GenDestructor(getContext()), FuncName, QT, IsVolatile,
882
150
                      *this, std::array<Address, 1>({{DstPtr}}));
883
150
}
884
885
64
void CodeGenFunction::callCStructCopyConstructor(LValue Dst, LValue Src) {
886
64
  bool IsVolatile = Dst.isVolatile() || 
Src.isVolatile()60
;
887
64
  Address DstPtr = Dst.getAddress(*this), SrcPtr = Src.getAddress(*this);
888
64
  QualType QT = Dst.getType();
889
64
  GenBinaryFuncName<false> GenName("__copy_constructor_", DstPtr.getAlignment(),
890
64
                                   SrcPtr.getAlignment(), getContext());
891
64
  std::string FuncName = GenName.getName(QT, IsVolatile);
892
64
  callSpecialFunction(GenCopyConstructor(getContext()), FuncName, QT,
893
64
                      IsVolatile, *this,
894
64
                      std::array<Address, 2>({{DstPtr, SrcPtr}}));
895
64
}
896
897
void CodeGenFunction::callCStructCopyAssignmentOperator(LValue Dst, LValue Src
898
899
28
) {
900
28
  bool IsVolatile = Dst.isVolatile() || 
Src.isVolatile()22
;
901
28
  Address DstPtr = Dst.getAddress(*this), SrcPtr = Src.getAddress(*this);
902
28
  QualType QT = Dst.getType();
903
28
  GenBinaryFuncName<false> GenName("__copy_assignment_", DstPtr.getAlignment(),
904
28
                                   SrcPtr.getAlignment(), getContext());
905
28
  std::string FuncName = GenName.getName(QT, IsVolatile);
906
28
  callSpecialFunction(GenCopyAssignment(getContext()), FuncName, QT, IsVolatile,
907
28
                      *this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
908
28
}
909
910
14
void CodeGenFunction::callCStructMoveConstructor(LValue Dst, LValue Src) {
911
14
  bool IsVolatile = Dst.isVolatile() || Src.isVolatile();
912
14
  Address DstPtr = Dst.getAddress(*this), SrcPtr = Src.getAddress(*this);
913
14
  QualType QT = Dst.getType();
914
14
  GenBinaryFuncName<true> GenName("__move_constructor_", DstPtr.getAlignment(),
915
14
                                  SrcPtr.getAlignment(), getContext());
916
14
  std::string FuncName = GenName.getName(QT, IsVolatile);
917
14
  callSpecialFunction(GenMoveConstructor(getContext()), FuncName, QT,
918
14
                      IsVolatile, *this,
919
14
                      std::array<Address, 2>({{DstPtr, SrcPtr}}));
920
14
}
921
922
void CodeGenFunction::callCStructMoveAssignmentOperator(LValue Dst, LValue Src
923
924
12
) {
925
12
  bool IsVolatile = Dst.isVolatile() || Src.isVolatile();
926
12
  Address DstPtr = Dst.getAddress(*this), SrcPtr = Src.getAddress(*this);
927
12
  QualType QT = Dst.getType();
928
12
  GenBinaryFuncName<true> GenName("__move_assignment_", DstPtr.getAlignment(),
929
12
                                  SrcPtr.getAlignment(), getContext());
930
12
  std::string FuncName = GenName.getName(QT, IsVolatile);
931
12
  callSpecialFunction(GenMoveAssignment(getContext()), FuncName, QT, IsVolatile,
932
12
                      *this, std::array<Address, 2>({{DstPtr, SrcPtr}}));
933
12
}
934
935
llvm::Function *clang::CodeGen::getNonTrivialCStructDefaultConstructor(
936
0
    CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
937
0
  ASTContext &Ctx = CGM.getContext();
938
0
  GenDefaultInitializeFuncName GenName(DstAlignment, Ctx);
939
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
940
0
  return getSpecialFunction(GenDefaultInitialize(Ctx), FuncName, QT, IsVolatile,
941
0
                            std::array<CharUnits, 1>({{DstAlignment}}), CGM);
942
0
}
943
944
llvm::Function *clang::CodeGen::getNonTrivialCStructCopyConstructor(
945
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
946
0
    bool IsVolatile, QualType QT) {
947
0
  ASTContext &Ctx = CGM.getContext();
948
0
  GenBinaryFuncName<false> GenName("__copy_constructor_", DstAlignment,
949
0
                                   SrcAlignment, Ctx);
950
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
951
0
  return getSpecialFunction(
952
0
      GenCopyConstructor(Ctx), FuncName, QT, IsVolatile,
953
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
954
0
}
955
956
llvm::Function *clang::CodeGen::getNonTrivialCStructMoveConstructor(
957
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
958
0
    bool IsVolatile, QualType QT) {
959
0
  ASTContext &Ctx = CGM.getContext();
960
0
  GenBinaryFuncName<true> GenName("__move_constructor_", DstAlignment,
961
0
                                  SrcAlignment, Ctx);
962
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
963
0
  return getSpecialFunction(
964
0
      GenMoveConstructor(Ctx), FuncName, QT, IsVolatile,
965
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
966
0
}
967
968
llvm::Function *clang::CodeGen::getNonTrivialCStructCopyAssignmentOperator(
969
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
970
0
    bool IsVolatile, QualType QT) {
971
0
  ASTContext &Ctx = CGM.getContext();
972
0
  GenBinaryFuncName<false> GenName("__copy_assignment_", DstAlignment,
973
0
                                   SrcAlignment, Ctx);
974
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
975
0
  return getSpecialFunction(
976
0
      GenCopyAssignment(Ctx), FuncName, QT, IsVolatile,
977
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
978
0
}
979
980
llvm::Function *clang::CodeGen::getNonTrivialCStructMoveAssignmentOperator(
981
    CodeGenModule &CGM, CharUnits DstAlignment, CharUnits SrcAlignment,
982
0
    bool IsVolatile, QualType QT) {
983
0
  ASTContext &Ctx = CGM.getContext();
984
0
  GenBinaryFuncName<true> GenName("__move_assignment_", DstAlignment,
985
0
                                  SrcAlignment, Ctx);
986
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
987
0
  return getSpecialFunction(
988
0
      GenMoveAssignment(Ctx), FuncName, QT, IsVolatile,
989
0
      std::array<CharUnits, 2>({{DstAlignment, SrcAlignment}}), CGM);
990
0
}
991
992
llvm::Function *clang::CodeGen::getNonTrivialCStructDestructor(
993
0
    CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT) {
994
0
  ASTContext &Ctx = CGM.getContext();
995
0
  GenDestructorFuncName GenName("__destructor_", DstAlignment, Ctx);
996
0
  std::string FuncName = GenName.getName(QT, IsVolatile);
997
0
  return getSpecialFunction(GenDestructor(Ctx), FuncName, QT, IsVolatile,
998
0
                            std::array<CharUnits, 1>({{DstAlignment}}), CGM);
999
0
}